safecoin_client/rpc_client.rs
1//! Communication with a Safecoin node over RPC.
2//!
3//! Software that interacts with the Safecoin blockchain, whether querying its
4//! state or submitting transactions, communicates with a Safecoin node over
5//! [JSON-RPC], using the [`RpcClient`] type.
6//!
7//! [JSON-RPC]: https://www.jsonrpc.org/specification
8
9pub use crate::mock_sender::Mocks;
10#[allow(deprecated)]
11use crate::rpc_deprecated_config::{RpcConfirmedBlockConfig, RpcConfirmedTransactionConfig};
12use {
13 crate::{
14 client_error::Result as ClientResult,
15 http_sender::HttpSender,
16 mock_sender::MockSender,
17 nonblocking::{self, rpc_client::get_rpc_request_str},
18 rpc_config::{RpcAccountInfoConfig, *},
19 rpc_request::{RpcRequest, TokenAccountsFilter},
20 rpc_response::*,
21 rpc_sender::*,
22 },
23 serde::Serialize,
24 serde_json::Value,
25 safecoin_account_decoder::{
26 parse_token::{UiTokenAccount, UiTokenAmount},
27 UiAccount, UiAccountEncoding,
28 },
29 solana_sdk::{
30 account::Account,
31 clock::{Epoch, Slot, UnixTimestamp},
32 commitment_config::CommitmentConfig,
33 epoch_info::EpochInfo,
34 epoch_schedule::EpochSchedule,
35 fee_calculator::{FeeCalculator, FeeRateGovernor},
36 hash::Hash,
37 message::{v0, Message as LegacyMessage},
38 pubkey::Pubkey,
39 signature::Signature,
40 transaction::{self, uses_durable_nonce, Transaction, VersionedTransaction},
41 },
42 safecoin_transaction_status::{
43 EncodedConfirmedBlock, EncodedConfirmedTransactionWithStatusMeta, TransactionStatus,
44 UiConfirmedBlock, UiTransactionEncoding,
45 },
46 std::{net::SocketAddr, str::FromStr, time::Duration},
47};
48
49#[derive(Default)]
50pub struct RpcClientConfig {
51 pub commitment_config: CommitmentConfig,
52 pub confirm_transaction_initial_timeout: Option<Duration>,
53}
54
55impl RpcClientConfig {
56 pub fn with_commitment(commitment_config: CommitmentConfig) -> Self {
57 RpcClientConfig {
58 commitment_config,
59 ..Self::default()
60 }
61 }
62}
63
64/// Trait used to add support for versioned messages to RPC APIs while
65/// retaining backwards compatibility
66pub trait SerializableMessage: Serialize {}
67impl SerializableMessage for LegacyMessage {}
68impl SerializableMessage for v0::Message {}
69
70/// Trait used to add support for versioned transactions to RPC APIs while
71/// retaining backwards compatibility
72pub trait SerializableTransaction: Serialize {
73 fn get_signature(&self) -> &Signature;
74 fn get_recent_blockhash(&self) -> &Hash;
75 fn uses_durable_nonce(&self) -> bool;
76}
77impl SerializableTransaction for Transaction {
78 fn get_signature(&self) -> &Signature {
79 &self.signatures[0]
80 }
81 fn get_recent_blockhash(&self) -> &Hash {
82 &self.message.recent_blockhash
83 }
84 fn uses_durable_nonce(&self) -> bool {
85 uses_durable_nonce(self).is_some()
86 }
87}
88impl SerializableTransaction for VersionedTransaction {
89 fn get_signature(&self) -> &Signature {
90 &self.signatures[0]
91 }
92 fn get_recent_blockhash(&self) -> &Hash {
93 self.message.recent_blockhash()
94 }
95 fn uses_durable_nonce(&self) -> bool {
96 self.uses_durable_nonce()
97 }
98}
99
100#[derive(Debug, Default)]
101pub struct GetConfirmedSignaturesForAddress2Config {
102 pub before: Option<Signature>,
103 pub until: Option<Signature>,
104 pub limit: Option<usize>,
105 pub commitment: Option<CommitmentConfig>,
106}
107
108/// A client of a remote Safecoin node.
109///
110/// `RpcClient` communicates with a Safecoin node over [JSON-RPC], with the
111/// [Safecoin JSON-RPC protocol][jsonprot]. It is the primary Rust interface for
112/// querying and transacting with the network from external programs.
113///
114/// This type builds on the underlying RPC protocol, adding extra features such
115/// as timeout handling, retries, and waiting on transaction [commitment levels][cl].
116/// Some methods simply pass through to the underlying RPC protocol. Not all RPC
117/// methods are encapsulated by this type, but `RpcClient` does expose a generic
118/// [`send`](RpcClient::send) method for making any [`RpcRequest`].
119///
120/// The documentation for most `RpcClient` methods contains an "RPC Reference"
121/// section that links to the documentation for the underlying JSON-RPC method.
122/// The documentation for `RpcClient` does not reproduce the documentation for
123/// the underlying JSON-RPC methods. Thus reading both is necessary for complete
124/// understanding.
125///
126/// `RpcClient`s generally communicate over HTTP on port 8899, a typical server
127/// URL being "http://localhost:8899".
128///
129/// Methods that query information from recent [slots], including those that
130/// confirm transactions, decide the most recent slot to query based on a
131/// [commitment level][cl], which determines how committed or finalized a slot
132/// must be to be considered for the query. Unless specified otherwise, the
133/// commitment level is [`Finalized`], meaning the slot is definitely
134/// permanently committed. The default commitment level can be configured by
135/// creating `RpcClient` with an explicit [`CommitmentConfig`], and that default
136/// configured commitment level can be overridden by calling the various
137/// `_with_commitment` methods, like
138/// [`RpcClient::confirm_transaction_with_commitment`]. In some cases the
139/// configured commitment level is ignored and `Finalized` is used instead, as
140/// in [`RpcClient::get_blocks`], where it would be invalid to use the
141/// [`Processed`] commitment level. These exceptions are noted in the method
142/// documentation.
143///
144/// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
145/// [`Processed`]: solana_sdk::commitment_config::CommitmentLevel::Processed
146/// [jsonprot]: https://docs.solana.com/developing/clients/jsonrpc-api
147/// [JSON-RPC]: https://www.jsonrpc.org/specification
148/// [slots]: https://docs.solana.com/terminology#slot
149/// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
150///
151/// # Errors
152///
153/// Methods on `RpcClient` return
154/// [`client_error::Result`][crate::client_error::Result], and many of them
155/// return the [`RpcResult`][crate::rpc_response::RpcResult] typedef, which
156/// contains [`Response<T>`][crate::rpc_response::Response] on `Ok`. Both
157/// `client_error::Result` and [`RpcResult`] contain `ClientError` on error. In
158/// the case of `RpcResult`, the actual return value is in the
159/// [`value`][crate::rpc_response::Response::value] field, with RPC contextual
160/// information in the [`context`][crate::rpc_response::Response::context]
161/// field, so it is common for the value to be accessed with `?.value`, as in
162///
163/// ```
164/// # use solana_sdk::system_transaction;
165/// # use safecoin_client::rpc_client::RpcClient;
166/// # use safecoin_client::client_error::ClientError;
167/// # use solana_sdk::signature::{Keypair, Signer};
168/// # use solana_sdk::hash::Hash;
169/// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
170/// # let key = Keypair::new();
171/// # let to = solana_sdk::pubkey::new_rand();
172/// # let lamports = 50;
173/// # let latest_blockhash = Hash::default();
174/// # let tx = system_transaction::transfer(&key, &to, lamports, latest_blockhash);
175/// let signature = rpc_client.send_transaction(&tx)?;
176/// let statuses = rpc_client.get_signature_statuses(&[signature])?.value;
177/// # Ok::<(), ClientError>(())
178/// ```
179///
180/// Requests may timeout, in which case they return a [`ClientError`] where the
181/// [`ClientErrorKind`] is [`ClientErrorKind::Reqwest`], and where the interior
182/// [`reqwest::Error`](crate::client_error::reqwest::Error)s
183/// [`is_timeout`](crate::client_error::reqwest::Error::is_timeout) method
184/// returns `true`. The default timeout is 30 seconds, and may be changed by
185/// calling an appropriate constructor with a `timeout` parameter.
186///
187/// [`ClientError`]: crate::client_error::ClientError
188/// [`ClientErrorKind`]: crate::client_error::ClientErrorKind
189/// [`ClientErrorKind::Reqwest`]: crate::client_error::ClientErrorKind::Reqwest
190pub struct RpcClient {
191 rpc_client: nonblocking::rpc_client::RpcClient,
192 runtime: Option<tokio::runtime::Runtime>,
193}
194
195impl Drop for RpcClient {
196 fn drop(&mut self) {
197 self.runtime.take().expect("runtime").shutdown_background();
198 }
199}
200
201impl RpcClient {
202 /// Create an `RpcClient` from an [`RpcSender`] and an [`RpcClientConfig`].
203 ///
204 /// This is the basic constructor, allowing construction with any type of
205 /// `RpcSender`. Most applications should use one of the other constructors,
206 /// such as [`RpcClient::new`], [`RpcClient::new_with_commitment`] or
207 /// [`RpcClient::new_with_timeout`].
208 pub fn new_sender<T: RpcSender + Send + Sync + 'static>(
209 sender: T,
210 config: RpcClientConfig,
211 ) -> Self {
212 Self {
213 rpc_client: nonblocking::rpc_client::RpcClient::new_sender(sender, config),
214 runtime: Some(
215 tokio::runtime::Builder::new_current_thread()
216 .thread_name("solRpcClient")
217 .enable_io()
218 .enable_time()
219 .build()
220 .unwrap(),
221 ),
222 }
223 }
224
225 /// Create an HTTP `RpcClient`.
226 ///
227 /// The URL is an HTTP URL, usually for port 8899, as in
228 /// "http://localhost:8899".
229 ///
230 /// The client has a default timeout of 30 seconds, and a default [commitment
231 /// level][cl] of [`Finalized`].
232 ///
233 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
234 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
235 ///
236 /// # Examples
237 ///
238 /// ```
239 /// # use safecoin_client::rpc_client::RpcClient;
240 /// let url = "http://localhost:8899".to_string();
241 /// let client = RpcClient::new(url);
242 /// ```
243 pub fn new<U: ToString>(url: U) -> Self {
244 Self::new_with_commitment(url, CommitmentConfig::default())
245 }
246
247 /// Create an HTTP `RpcClient` with specified [commitment level][cl].
248 ///
249 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
250 ///
251 /// The URL is an HTTP URL, usually for port 8899, as in
252 /// "http://localhost:8899".
253 ///
254 /// The client has a default timeout of 30 seconds, and a user-specified
255 /// [`CommitmentLevel`] via [`CommitmentConfig`].
256 ///
257 /// [`CommitmentLevel`]: solana_sdk::commitment_config::CommitmentLevel
258 ///
259 /// # Examples
260 ///
261 /// ```
262 /// # use solana_sdk::commitment_config::CommitmentConfig;
263 /// # use safecoin_client::rpc_client::RpcClient;
264 /// let url = "http://localhost:8899".to_string();
265 /// let commitment_config = CommitmentConfig::processed();
266 /// let client = RpcClient::new_with_commitment(url, commitment_config);
267 /// ```
268 pub fn new_with_commitment<U: ToString>(url: U, commitment_config: CommitmentConfig) -> Self {
269 Self::new_sender(
270 HttpSender::new(url),
271 RpcClientConfig::with_commitment(commitment_config),
272 )
273 }
274
275 /// Create an HTTP `RpcClient` with specified timeout.
276 ///
277 /// The URL is an HTTP URL, usually for port 8899, as in
278 /// "http://localhost:8899".
279 ///
280 /// The client has and a default [commitment level][cl] of
281 /// [`Finalized`].
282 ///
283 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
284 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
285 ///
286 /// # Examples
287 ///
288 /// ```
289 /// # use std::time::Duration;
290 /// # use safecoin_client::rpc_client::RpcClient;
291 /// let url = "http://localhost::8899".to_string();
292 /// let timeout = Duration::from_secs(1);
293 /// let client = RpcClient::new_with_timeout(url, timeout);
294 /// ```
295 pub fn new_with_timeout<U: ToString>(url: U, timeout: Duration) -> Self {
296 Self::new_sender(
297 HttpSender::new_with_timeout(url, timeout),
298 RpcClientConfig::with_commitment(CommitmentConfig::default()),
299 )
300 }
301
302 /// Create an HTTP `RpcClient` with specified timeout and [commitment level][cl].
303 ///
304 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
305 ///
306 /// The URL is an HTTP URL, usually for port 8899, as in
307 /// "http://localhost:8899".
308 ///
309 /// # Examples
310 ///
311 /// ```
312 /// # use std::time::Duration;
313 /// # use safecoin_client::rpc_client::RpcClient;
314 /// # use solana_sdk::commitment_config::CommitmentConfig;
315 /// let url = "http://localhost::8899".to_string();
316 /// let timeout = Duration::from_secs(1);
317 /// let commitment_config = CommitmentConfig::processed();
318 /// let client = RpcClient::new_with_timeout_and_commitment(
319 /// url,
320 /// timeout,
321 /// commitment_config,
322 /// );
323 /// ```
324 pub fn new_with_timeout_and_commitment<U: ToString>(
325 url: U,
326 timeout: Duration,
327 commitment_config: CommitmentConfig,
328 ) -> Self {
329 Self::new_sender(
330 HttpSender::new_with_timeout(url, timeout),
331 RpcClientConfig::with_commitment(commitment_config),
332 )
333 }
334
335 /// Create an HTTP `RpcClient` with specified timeout and [commitment level][cl].
336 ///
337 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
338 ///
339 /// The URL is an HTTP URL, usually for port 8899, as in
340 /// "http://localhost:8899".
341 ///
342 /// The `confirm_transaction_initial_timeout` argument specifies, when
343 /// confirming a transaction via one of the `_with_spinner` methods, like
344 /// [`RpcClient::send_and_confirm_transaction_with_spinner`], the amount of
345 /// time to allow for the server to initially process a transaction. In
346 /// other words, setting `confirm_transaction_initial_timeout` to > 0 allows
347 /// `RpcClient` to wait for confirmation of a transaction that the server
348 /// has not "seen" yet.
349 ///
350 /// # Examples
351 ///
352 /// ```
353 /// # use std::time::Duration;
354 /// # use safecoin_client::rpc_client::RpcClient;
355 /// # use solana_sdk::commitment_config::CommitmentConfig;
356 /// let url = "http://localhost::8899".to_string();
357 /// let timeout = Duration::from_secs(1);
358 /// let commitment_config = CommitmentConfig::processed();
359 /// let confirm_transaction_initial_timeout = Duration::from_secs(10);
360 /// let client = RpcClient::new_with_timeouts_and_commitment(
361 /// url,
362 /// timeout,
363 /// commitment_config,
364 /// confirm_transaction_initial_timeout,
365 /// );
366 /// ```
367 pub fn new_with_timeouts_and_commitment<U: ToString>(
368 url: U,
369 timeout: Duration,
370 commitment_config: CommitmentConfig,
371 confirm_transaction_initial_timeout: Duration,
372 ) -> Self {
373 Self::new_sender(
374 HttpSender::new_with_timeout(url, timeout),
375 RpcClientConfig {
376 commitment_config,
377 confirm_transaction_initial_timeout: Some(confirm_transaction_initial_timeout),
378 },
379 )
380 }
381
382 /// Create a mock `RpcClient`.
383 ///
384 /// A mock `RpcClient` contains an implementation of [`RpcSender`] that does
385 /// not use the network, and instead returns synthetic responses, for use in
386 /// tests.
387 ///
388 /// It is primarily for internal use, with limited customizability, and
389 /// behaviors determined by internal Safecoin test cases. New users should
390 /// consider implementing `RpcSender` themselves and constructing
391 /// `RpcClient` with [`RpcClient::new_sender`] to get mock behavior.
392 ///
393 /// Unless directed otherwise, a mock `RpcClient` will generally return a
394 /// reasonable default response to any request, at least for [`RpcRequest`]
395 /// values for which responses have been implemented.
396 ///
397 /// This mock can be customized by changing the `url` argument, which is not
398 /// actually a URL, but a simple string directive that changes the mock
399 /// behavior in specific scenarios:
400 ///
401 /// - It is customary to set the `url` to "succeeds" for mocks that should
402 /// return sucessfully, though this value is not actually interpreted.
403 ///
404 /// - If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
405 ///
406 /// - Other possible values of `url` are specific to different `RpcRequest`
407 /// values. Read the implementation of (non-public) `MockSender` for
408 /// details.
409 ///
410 /// The [`RpcClient::new_mock_with_mocks`] function offers further
411 /// customization options.
412 ///
413 /// # Examples
414 ///
415 /// ```
416 /// # use safecoin_client::rpc_client::RpcClient;
417 /// // Create an `RpcClient` that always succeeds
418 /// let url = "succeeds".to_string();
419 /// let successful_client = RpcClient::new_mock(url);
420 /// ```
421 ///
422 /// ```
423 /// # use safecoin_client::rpc_client::RpcClient;
424 /// // Create an `RpcClient` that always fails
425 /// let url = "fails".to_string();
426 /// let successful_client = RpcClient::new_mock(url);
427 /// ```
428 pub fn new_mock<U: ToString>(url: U) -> Self {
429 Self::new_sender(
430 MockSender::new(url),
431 RpcClientConfig::with_commitment(CommitmentConfig::default()),
432 )
433 }
434
435 /// Create a mock `RpcClient`.
436 ///
437 /// A mock `RpcClient` contains an implementation of [`RpcSender`] that does
438 /// not use the network, and instead returns synthetic responses, for use in
439 /// tests.
440 ///
441 /// It is primarily for internal use, with limited customizability, and
442 /// behaviors determined by internal Safecoin test cases. New users should
443 /// consider implementing `RpcSender` themselves and constructing
444 /// `RpcClient` with [`RpcClient::new_sender`] to get mock behavior.
445 ///
446 /// Unless directed otherwise, a mock `RpcClient` will generally return a
447 /// reasonable default response to any request, at least for [`RpcRequest`]
448 /// values for which responses have been implemented.
449 ///
450 /// This mock can be customized in two ways:
451 ///
452 /// 1) By changing the `url` argument, which is not actually a URL, but a
453 /// simple string directive that changes the mock behavior in specific
454 /// scenarios.
455 ///
456 /// It is customary to set the `url` to "succeeds" for mocks that should
457 /// return sucessfully, though this value is not actually interpreted.
458 ///
459 /// If `url` is "fails" then any call to `send` will return `Ok(Value::Null)`.
460 ///
461 /// Other possible values of `url` are specific to different `RpcRequest`
462 /// values. Read the implementation of `MockSender` (which is non-public)
463 /// for details.
464 ///
465 /// 2) Custom responses can be configured by providing [`Mocks`]. This type
466 /// is a [`HashMap`] from [`RpcRequest`] to a JSON [`Value`] response,
467 /// Any entries in this map override the default behavior for the given
468 /// request.
469 ///
470 /// The [`RpcClient::new_mock_with_mocks`] function offers further
471 /// customization options.
472 ///
473 /// [`HashMap`]: std::collections::HashMap
474 ///
475 /// # Examples
476 ///
477 /// ```
478 /// # use safecoin_client::{
479 /// # rpc_client::RpcClient,
480 /// # rpc_request::RpcRequest,
481 /// # rpc_response::{Response, RpcResponseContext},
482 /// # };
483 /// # use std::collections::HashMap;
484 /// # use serde_json::json;
485 /// // Create a mock with a custom repsonse to the `GetBalance` request
486 /// let account_balance = 50;
487 /// let account_balance_response = json!(Response {
488 /// context: RpcResponseContext { slot: 1, api_version: None },
489 /// value: json!(account_balance),
490 /// });
491 ///
492 /// let mut mocks = HashMap::new();
493 /// mocks.insert(RpcRequest::GetBalance, account_balance_response);
494 /// let url = "succeeds".to_string();
495 /// let client = RpcClient::new_mock_with_mocks(url, mocks);
496 /// ```
497 pub fn new_mock_with_mocks<U: ToString>(url: U, mocks: Mocks) -> Self {
498 Self::new_sender(
499 MockSender::new_with_mocks(url, mocks),
500 RpcClientConfig::with_commitment(CommitmentConfig::default()),
501 )
502 }
503
504 /// Create an HTTP `RpcClient` from a [`SocketAddr`].
505 ///
506 /// The client has a default timeout of 30 seconds, and a default [commitment
507 /// level][cl] of [`Finalized`].
508 ///
509 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
510 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
511 ///
512 /// # Examples
513 ///
514 /// ```
515 /// # use std::net::SocketAddr;
516 /// # use safecoin_client::rpc_client::RpcClient;
517 /// let addr = SocketAddr::from(([127, 0, 0, 1], 8899));
518 /// let client = RpcClient::new_socket(addr);
519 /// ```
520 pub fn new_socket(addr: SocketAddr) -> Self {
521 Self::new(get_rpc_request_str(addr, false))
522 }
523
524 /// Create an HTTP `RpcClient` from a [`SocketAddr`] with specified [commitment level][cl].
525 ///
526 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
527 ///
528 /// The client has a default timeout of 30 seconds, and a user-specified
529 /// [`CommitmentLevel`] via [`CommitmentConfig`].
530 ///
531 /// [`CommitmentLevel`]: solana_sdk::commitment_config::CommitmentLevel
532 ///
533 /// # Examples
534 ///
535 /// ```
536 /// # use std::net::SocketAddr;
537 /// # use safecoin_client::rpc_client::RpcClient;
538 /// # use solana_sdk::commitment_config::CommitmentConfig;
539 /// let addr = SocketAddr::from(([127, 0, 0, 1], 8899));
540 /// let commitment_config = CommitmentConfig::processed();
541 /// let client = RpcClient::new_socket_with_commitment(
542 /// addr,
543 /// commitment_config
544 /// );
545 /// ```
546 pub fn new_socket_with_commitment(
547 addr: SocketAddr,
548 commitment_config: CommitmentConfig,
549 ) -> Self {
550 Self::new_with_commitment(get_rpc_request_str(addr, false), commitment_config)
551 }
552
553 /// Create an HTTP `RpcClient` from a [`SocketAddr`] with specified timeout.
554 ///
555 /// The client has a default [commitment level][cl] of [`Finalized`].
556 ///
557 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
558 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
559 ///
560 /// # Examples
561 ///
562 /// ```
563 /// # use std::net::SocketAddr;
564 /// # use std::time::Duration;
565 /// # use safecoin_client::rpc_client::RpcClient;
566 /// let addr = SocketAddr::from(([127, 0, 0, 1], 8899));
567 /// let timeout = Duration::from_secs(1);
568 /// let client = RpcClient::new_socket_with_timeout(addr, timeout);
569 /// ```
570 pub fn new_socket_with_timeout(addr: SocketAddr, timeout: Duration) -> Self {
571 let url = get_rpc_request_str(addr, false);
572 Self::new_with_timeout(url, timeout)
573 }
574
575 /// Get the configured url of the client's sender
576 pub fn url(&self) -> String {
577 self.rpc_client.url()
578 }
579
580 /// Get the configured default [commitment level][cl].
581 ///
582 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
583 ///
584 /// The commitment config may be specified during construction, and
585 /// determines how thoroughly committed a transaction must be when waiting
586 /// for its confirmation or otherwise checking for confirmation. If not
587 /// specified, the default commitment level is
588 /// [`Finalized`].
589 ///
590 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
591 ///
592 /// The default commitment level is overridden when calling methods that
593 /// explicitly provide a [`CommitmentConfig`], like
594 /// [`RpcClient::confirm_transaction_with_commitment`].
595 pub fn commitment(&self) -> CommitmentConfig {
596 self.rpc_client.commitment()
597 }
598
599 /// Submit a transaction and wait for confirmation.
600 ///
601 /// Once this function returns successfully, the given transaction is
602 /// guaranteed to be processed with the configured [commitment level][cl].
603 ///
604 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
605 ///
606 /// After sending the transaction, this method polls in a loop for the
607 /// status of the transaction until it has ben confirmed.
608 ///
609 /// # Errors
610 ///
611 /// If the transaction is not signed then an error with kind [`RpcError`] is
612 /// returned, containing an [`RpcResponseError`] with `code` set to
613 /// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`].
614 ///
615 /// If the preflight transaction simulation fails then an error with kind
616 /// [`RpcError`] is returned, containing an [`RpcResponseError`] with `code`
617 /// set to [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`].
618 ///
619 /// If the receiving node is unhealthy, e.g. it is not fully synced to
620 /// the cluster, then an error with kind [`RpcError`] is returned,
621 /// containing an [`RpcResponseError`] with `code` set to
622 /// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`].
623 ///
624 /// [`RpcError`]: crate::rpc_request::RpcError
625 /// [`RpcResponseError`]: crate::rpc_request::RpcError::RpcResponseError
626 /// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE
627 /// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
628 /// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY
629 ///
630 /// # RPC Reference
631 ///
632 /// This method is built on the [`sendTransaction`] RPC method, and the
633 /// [`getLatestBlockhash`] RPC method.
634 ///
635 /// [`sendTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#sendtransaction
636 /// [`getLatestBlockhash`]: https://docs.solana.com/developing/clients/jsonrpc-api#getlatestblockhash
637 ///
638 /// # Examples
639 ///
640 /// ```
641 /// # use safecoin_client::{
642 /// # rpc_client::RpcClient,
643 /// # client_error::ClientError,
644 /// # };
645 /// # use solana_sdk::{
646 /// # signature::Signer,
647 /// # signature::Signature,
648 /// # signer::keypair::Keypair,
649 /// # system_transaction,
650 /// # };
651 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
652 /// # let alice = Keypair::new();
653 /// # let bob = Keypair::new();
654 /// # let lamports = 50;
655 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
656 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
657 /// let signature = rpc_client.send_and_confirm_transaction(&tx)?;
658 /// # Ok::<(), ClientError>(())
659 /// ```
660 pub fn send_and_confirm_transaction(
661 &self,
662 transaction: &impl SerializableTransaction,
663 ) -> ClientResult<Signature> {
664 self.invoke(self.rpc_client.send_and_confirm_transaction(transaction))
665 }
666
667 pub fn send_and_confirm_transaction_with_spinner(
668 &self,
669 transaction: &impl SerializableTransaction,
670 ) -> ClientResult<Signature> {
671 self.invoke(
672 self.rpc_client
673 .send_and_confirm_transaction_with_spinner(transaction),
674 )
675 }
676
677 pub fn send_and_confirm_transaction_with_spinner_and_commitment(
678 &self,
679 transaction: &impl SerializableTransaction,
680 commitment: CommitmentConfig,
681 ) -> ClientResult<Signature> {
682 self.invoke(
683 self.rpc_client
684 .send_and_confirm_transaction_with_spinner_and_commitment(transaction, commitment),
685 )
686 }
687
688 pub fn send_and_confirm_transaction_with_spinner_and_config(
689 &self,
690 transaction: &impl SerializableTransaction,
691 commitment: CommitmentConfig,
692 config: RpcSendTransactionConfig,
693 ) -> ClientResult<Signature> {
694 self.invoke(
695 self.rpc_client
696 .send_and_confirm_transaction_with_spinner_and_config(
697 transaction,
698 commitment,
699 config,
700 ),
701 )
702 }
703
704 /// Submits a signed transaction to the network.
705 ///
706 /// Before a transaction is processed, the receiving node runs a "preflight
707 /// check" which verifies signatures, checks that the node is healthy,
708 /// and simulates the transaction. If the preflight check fails then an
709 /// error is returned immediately. Preflight checks can be disabled by
710 /// calling [`send_transaction_with_config`] and setting the
711 /// [`skip_preflight`] field of [`RpcSendTransactionConfig`] to `true`.
712 ///
713 /// This method does not wait for the transaction to be processed or
714 /// confirmed before returning successfully. To wait for the transaction to
715 /// be processed or confirmed, use the [`send_and_confirm_transaction`]
716 /// method.
717 ///
718 /// [`send_transaction_with_config`]: RpcClient::send_transaction_with_config
719 /// [`skip_preflight`]: crate::rpc_config::RpcSendTransactionConfig::skip_preflight
720 /// [`RpcSendTransactionConfig`]: crate::rpc_config::RpcSendTransactionConfig
721 /// [`send_and_confirm_transaction`]: RpcClient::send_and_confirm_transaction
722 ///
723 /// # Errors
724 ///
725 /// If the transaction is not signed then an error with kind [`RpcError`] is
726 /// returned, containing an [`RpcResponseError`] with `code` set to
727 /// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`].
728 ///
729 /// If the preflight transaction simulation fails then an error with kind
730 /// [`RpcError`] is returned, containing an [`RpcResponseError`] with `code`
731 /// set to [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`].
732 ///
733 /// If the receiving node is unhealthy, e.g. it is not fully synced to
734 /// the cluster, then an error with kind [`RpcError`] is returned,
735 /// containing an [`RpcResponseError`] with `code` set to
736 /// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`].
737 ///
738 /// [`RpcError`]: crate::rpc_request::RpcError
739 /// [`RpcResponseError`]: crate::rpc_request::RpcError::RpcResponseError
740 /// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE
741 /// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
742 /// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY
743 ///
744 /// # RPC Reference
745 ///
746 /// This method is built on the [`sendTransaction`] RPC method.
747 ///
748 /// [`sendTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#sendtransaction
749 ///
750 /// # Examples
751 ///
752 /// ```
753 /// # use safecoin_client::{
754 /// # client_error::ClientError,
755 /// # rpc_client::RpcClient,
756 /// # };
757 /// # use solana_sdk::{
758 /// # signature::Signer,
759 /// # signature::Signature,
760 /// # signer::keypair::Keypair,
761 /// # hash::Hash,
762 /// # system_transaction,
763 /// # };
764 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
765 /// // Transfer lamports from Alice to Bob
766 /// # let alice = Keypair::new();
767 /// # let bob = Keypair::new();
768 /// # let lamports = 50;
769 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
770 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
771 /// let signature = rpc_client.send_transaction(&tx)?;
772 /// # Ok::<(), ClientError>(())
773 /// ```
774 pub fn send_transaction(
775 &self,
776 transaction: &impl SerializableTransaction,
777 ) -> ClientResult<Signature> {
778 self.invoke(self.rpc_client.send_transaction(transaction))
779 }
780
781 /// Submits a signed transaction to the network.
782 ///
783 /// Before a transaction is processed, the receiving node runs a "preflight
784 /// check" which verifies signatures, checks that the node is healthy, and
785 /// simulates the transaction. If the preflight check fails then an error is
786 /// returned immediately. Preflight checks can be disabled by setting the
787 /// [`skip_preflight`] field of [`RpcSendTransactionConfig`] to `true`.
788 ///
789 /// This method does not wait for the transaction to be processed or
790 /// confirmed before returning successfully. To wait for the transaction to
791 /// be processed or confirmed, use the [`send_and_confirm_transaction`]
792 /// method.
793 ///
794 /// [`send_transaction_with_config`]: RpcClient::send_transaction_with_config
795 /// [`skip_preflight`]: crate::rpc_config::RpcSendTransactionConfig::skip_preflight
796 /// [`RpcSendTransactionConfig`]: crate::rpc_config::RpcSendTransactionConfig
797 /// [`send_and_confirm_transaction`]: RpcClient::send_and_confirm_transaction
798 ///
799 /// # Errors
800 ///
801 /// If preflight checks are enabled, if the transaction is not signed
802 /// then an error with kind [`RpcError`] is returned, containing an
803 /// [`RpcResponseError`] with `code` set to
804 /// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`].
805 ///
806 /// If preflight checks are enabled, if the preflight transaction simulation
807 /// fails then an error with kind [`RpcError`] is returned, containing an
808 /// [`RpcResponseError`] with `code` set to
809 /// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`].
810 ///
811 /// If the receiving node is unhealthy, e.g. it is not fully synced to
812 /// the cluster, then an error with kind [`RpcError`] is returned,
813 /// containing an [`RpcResponseError`] with `code` set to
814 /// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`].
815 ///
816 /// [`RpcError`]: crate::rpc_request::RpcError
817 /// [`RpcResponseError`]: crate::rpc_request::RpcError::RpcResponseError
818 /// [`JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_TRANSACTION_SIGNATURE_VERIFICATION_FAILURE
819 /// [`JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_SEND_TRANSACTION_PREFLIGHT_FAILURE
820 /// [`JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY`]: crate::rpc_custom_error::JSON_RPC_SERVER_ERROR_NODE_UNHEALTHY
821 ///
822 /// # RPC Reference
823 ///
824 /// This method is built on the [`sendTransaction`] RPC method.
825 ///
826 /// [`sendTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#sendtransaction
827 ///
828 /// # Examples
829 ///
830 /// ```
831 /// # use safecoin_client::{
832 /// # client_error::ClientError,
833 /// # rpc_client::RpcClient,
834 /// # rpc_config::RpcSendTransactionConfig,
835 /// # };
836 /// # use solana_sdk::{
837 /// # signature::Signer,
838 /// # signature::Signature,
839 /// # signer::keypair::Keypair,
840 /// # hash::Hash,
841 /// # system_transaction,
842 /// # };
843 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
844 /// // Transfer lamports from Alice to Bob
845 /// # let alice = Keypair::new();
846 /// # let bob = Keypair::new();
847 /// # let lamports = 50;
848 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
849 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
850 /// let config = RpcSendTransactionConfig {
851 /// skip_preflight: true,
852 /// .. RpcSendTransactionConfig::default()
853 /// };
854 /// let signature = rpc_client.send_transaction_with_config(
855 /// &tx,
856 /// config,
857 /// )?;
858 /// # Ok::<(), ClientError>(())
859 /// ```
860 pub fn send_transaction_with_config(
861 &self,
862 transaction: &impl SerializableTransaction,
863 config: RpcSendTransactionConfig,
864 ) -> ClientResult<Signature> {
865 self.invoke(
866 self.rpc_client
867 .send_transaction_with_config(transaction, config),
868 )
869 }
870
871 pub fn send<T>(&self, request: RpcRequest, params: Value) -> ClientResult<T>
872 where
873 T: serde::de::DeserializeOwned,
874 {
875 self.invoke(self.rpc_client.send(request, params))
876 }
877
878 /// Check the confirmation status of a transaction.
879 ///
880 /// Returns `true` if the given transaction succeeded and has been committed
881 /// with the configured [commitment level][cl], which can be retrieved with
882 /// the [`commitment`](RpcClient::commitment) method.
883 ///
884 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
885 ///
886 /// Note that this method does not wait for a transaction to be confirmed
887 /// — it only checks whether a transaction has been confirmed. To
888 /// submit a transaction and wait for it to confirm, use
889 /// [`send_and_confirm_transaction`][RpcClient::send_and_confirm_transaction].
890 ///
891 /// _This method returns `false` if the transaction failed, even if it has
892 /// been confirmed._
893 ///
894 /// # RPC Reference
895 ///
896 /// This method is built on the [`getSignatureStatuses`] RPC method.
897 ///
898 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturestatuses
899 ///
900 /// # Examples
901 ///
902 /// ```
903 /// # use safecoin_client::{
904 /// # client_error::ClientError,
905 /// # rpc_client::RpcClient,
906 /// # };
907 /// # use solana_sdk::{
908 /// # signature::Signer,
909 /// # signature::Signature,
910 /// # signer::keypair::Keypair,
911 /// # system_transaction,
912 /// # };
913 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
914 /// // Transfer lamports from Alice to Bob and wait for confirmation
915 /// # let alice = Keypair::new();
916 /// # let bob = Keypair::new();
917 /// # let lamports = 50;
918 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
919 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
920 /// let signature = rpc_client.send_transaction(&tx)?;
921 ///
922 /// loop {
923 /// let confirmed = rpc_client.confirm_transaction(&signature)?;
924 /// if confirmed {
925 /// break;
926 /// }
927 /// }
928 /// # Ok::<(), ClientError>(())
929 /// ```
930 pub fn confirm_transaction(&self, signature: &Signature) -> ClientResult<bool> {
931 self.invoke(self.rpc_client.confirm_transaction(signature))
932 }
933
934 /// Check the confirmation status of a transaction.
935 ///
936 /// Returns an [`RpcResult`] with value `true` if the given transaction
937 /// succeeded and has been committed with the given [commitment level][cl].
938 ///
939 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
940 ///
941 /// Note that this method does not wait for a transaction to be confirmed
942 /// — it only checks whether a transaction has been confirmed. To
943 /// submit a transaction and wait for it to confirm, use
944 /// [`send_and_confirm_transaction`][RpcClient::send_and_confirm_transaction].
945 ///
946 /// _This method returns an [`RpcResult`] with value `false` if the
947 /// transaction failed, even if it has been confirmed._
948 ///
949 /// # RPC Reference
950 ///
951 /// This method is built on the [`getSignatureStatuses`] RPC method.
952 ///
953 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturestatuses
954 ///
955 /// # Examples
956 ///
957 /// ```
958 /// # use safecoin_client::{
959 /// # client_error::ClientError,
960 /// # rpc_client::RpcClient,
961 /// # };
962 /// # use solana_sdk::{
963 /// # commitment_config::CommitmentConfig,
964 /// # signature::Signer,
965 /// # signature::Signature,
966 /// # signer::keypair::Keypair,
967 /// # system_transaction,
968 /// # };
969 /// # use std::time::Duration;
970 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
971 /// // Transfer lamports from Alice to Bob and wait for confirmation
972 /// # let alice = Keypair::new();
973 /// # let bob = Keypair::new();
974 /// # let lamports = 50;
975 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
976 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
977 /// let signature = rpc_client.send_transaction(&tx)?;
978 ///
979 /// loop {
980 /// let commitment_config = CommitmentConfig::processed();
981 /// let confirmed = rpc_client.confirm_transaction_with_commitment(&signature, commitment_config)?;
982 /// if confirmed.value {
983 /// break;
984 /// }
985 /// }
986 /// # Ok::<(), ClientError>(())
987 /// ```
988 pub fn confirm_transaction_with_commitment(
989 &self,
990 signature: &Signature,
991 commitment_config: CommitmentConfig,
992 ) -> RpcResult<bool> {
993 self.invoke(
994 self.rpc_client
995 .confirm_transaction_with_commitment(signature, commitment_config),
996 )
997 }
998
999 pub fn confirm_transaction_with_spinner(
1000 &self,
1001 signature: &Signature,
1002 recent_blockhash: &Hash,
1003 commitment_config: CommitmentConfig,
1004 ) -> ClientResult<()> {
1005 self.invoke(self.rpc_client.confirm_transaction_with_spinner(
1006 signature,
1007 recent_blockhash,
1008 commitment_config,
1009 ))
1010 }
1011
1012 /// Simulates sending a transaction.
1013 ///
1014 /// If the transaction fails, then the [`err`] field of the returned
1015 /// [`RpcSimulateTransactionResult`] will be `Some`. Any logs emitted from
1016 /// the transaction are returned in the [`logs`] field.
1017 ///
1018 /// [`err`]: crate::rpc_response::RpcSimulateTransactionResult::err
1019 /// [`logs`]: crate::rpc_response::RpcSimulateTransactionResult::logs
1020 ///
1021 /// Simulating a transaction is similar to the ["preflight check"] that is
1022 /// run by default when sending a transaction.
1023 ///
1024 /// ["preflight check"]: https://docs.solana.com/developing/clients/jsonrpc-api#sendtransaction
1025 ///
1026 /// By default, signatures are not verified during simulation. To verify
1027 /// signatures, call the [`simulate_transaction_with_config`] method, with
1028 /// the [`sig_verify`] field of [`RpcSimulateTransactionConfig`] set to
1029 /// `true`.
1030 ///
1031 /// [`simulate_transaction_with_config`]: RpcClient::simulate_transaction_with_config
1032 /// [`sig_verify`]: crate::rpc_config::RpcSimulateTransactionConfig::sig_verify
1033 ///
1034 /// # RPC Reference
1035 ///
1036 /// This method is built on the [`simulateTransaction`] RPC method.
1037 ///
1038 /// [`simulateTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#simulatetransaction
1039 ///
1040 /// # Examples
1041 ///
1042 /// ```
1043 /// # use safecoin_client::{
1044 /// # client_error::ClientError,
1045 /// # rpc_client::RpcClient,
1046 /// # rpc_response::RpcSimulateTransactionResult,
1047 /// # };
1048 /// # use solana_sdk::{
1049 /// # signature::Signer,
1050 /// # signature::Signature,
1051 /// # signer::keypair::Keypair,
1052 /// # hash::Hash,
1053 /// # system_transaction,
1054 /// # };
1055 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1056 /// // Transfer lamports from Alice to Bob
1057 /// # let alice = Keypair::new();
1058 /// # let bob = Keypair::new();
1059 /// # let lamports = 50;
1060 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
1061 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
1062 /// let result = rpc_client.simulate_transaction(&tx)?;
1063 /// assert!(result.value.err.is_none());
1064 /// # Ok::<(), ClientError>(())
1065 /// ```
1066 pub fn simulate_transaction(
1067 &self,
1068 transaction: &impl SerializableTransaction,
1069 ) -> RpcResult<RpcSimulateTransactionResult> {
1070 self.invoke(self.rpc_client.simulate_transaction(transaction))
1071 }
1072
1073 /// Simulates sending a transaction.
1074 ///
1075 /// If the transaction fails, then the [`err`] field of the returned
1076 /// [`RpcSimulateTransactionResult`] will be `Some`. Any logs emitted from
1077 /// the transaction are returned in the [`logs`] field.
1078 ///
1079 /// [`err`]: crate::rpc_response::RpcSimulateTransactionResult::err
1080 /// [`logs`]: crate::rpc_response::RpcSimulateTransactionResult::logs
1081 ///
1082 /// Simulating a transaction is similar to the ["preflight check"] that is
1083 /// run by default when sending a transaction.
1084 ///
1085 /// ["preflight check"]: https://docs.solana.com/developing/clients/jsonrpc-api#sendtransaction
1086 ///
1087 /// By default, signatures are not verified during simulation. To verify
1088 /// signatures, call the [`simulate_transaction_with_config`] method, with
1089 /// the [`sig_verify`] field of [`RpcSimulateTransactionConfig`] set to
1090 /// `true`.
1091 ///
1092 /// [`simulate_transaction_with_config`]: RpcClient::simulate_transaction_with_config
1093 /// [`sig_verify`]: crate::rpc_config::RpcSimulateTransactionConfig::sig_verify
1094 ///
1095 /// This method can additionally query information about accounts by
1096 /// including them in the [`accounts`] field of the
1097 /// [`RpcSimulateTransactionConfig`] argument, in which case those results
1098 /// are reported in the [`accounts`][accounts2] field of the returned
1099 /// [`RpcSimulateTransactionResult`].
1100 ///
1101 /// [`accounts`]: crate::rpc_config::RpcSimulateTransactionConfig::accounts
1102 /// [accounts2]: crate::rpc_response::RpcSimulateTransactionResult::accounts
1103 ///
1104 /// # RPC Reference
1105 ///
1106 /// This method is built on the [`simulateTransaction`] RPC method.
1107 ///
1108 /// [`simulateTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#simulatetransaction
1109 ///
1110 /// # Examples
1111 ///
1112 /// ```
1113 /// # use safecoin_client::{
1114 /// # client_error::ClientError,
1115 /// # rpc_client::RpcClient,
1116 /// # rpc_config::RpcSimulateTransactionConfig,
1117 /// # rpc_response::RpcSimulateTransactionResult,
1118 /// # };
1119 /// # use solana_sdk::{
1120 /// # signature::Signer,
1121 /// # signer::keypair::Keypair,
1122 /// # hash::Hash,
1123 /// # system_transaction,
1124 /// # };
1125 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1126 /// // Transfer lamports from Alice to Bob
1127 /// # let alice = Keypair::new();
1128 /// # let bob = Keypair::new();
1129 /// # let lamports = 50;
1130 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
1131 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
1132 /// let config = RpcSimulateTransactionConfig {
1133 /// sig_verify: true,
1134 /// .. RpcSimulateTransactionConfig::default()
1135 /// };
1136 /// let result = rpc_client.simulate_transaction_with_config(
1137 /// &tx,
1138 /// config,
1139 /// )?;
1140 /// assert!(result.value.err.is_none());
1141 /// # Ok::<(), ClientError>(())
1142 /// ```
1143 pub fn simulate_transaction_with_config(
1144 &self,
1145 transaction: &impl SerializableTransaction,
1146 config: RpcSimulateTransactionConfig,
1147 ) -> RpcResult<RpcSimulateTransactionResult> {
1148 self.invoke(
1149 self.rpc_client
1150 .simulate_transaction_with_config(transaction, config),
1151 )
1152 }
1153
1154 /// Returns the highest slot information that the node has snapshots for.
1155 ///
1156 /// This will find the highest full snapshot slot, and the highest incremental snapshot slot
1157 /// _based on_ the full snapshot slot, if there is one.
1158 ///
1159 /// # RPC Reference
1160 ///
1161 /// This method corresponds directly to the [`getHighestSnapshotSlot`] RPC method.
1162 ///
1163 /// [`getHighestSnapshotSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#gethighestsnapshotslot
1164 ///
1165 /// # Examples
1166 ///
1167 /// ```
1168 /// # use safecoin_client::{
1169 /// # rpc_client::RpcClient,
1170 /// # client_error::ClientError,
1171 /// # };
1172 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1173 /// let snapshot_slot_info = rpc_client.get_highest_snapshot_slot()?;
1174 /// # Ok::<(), ClientError>(())
1175 /// ```
1176 pub fn get_highest_snapshot_slot(&self) -> ClientResult<RpcSnapshotSlotInfo> {
1177 self.invoke(self.rpc_client.get_highest_snapshot_slot())
1178 }
1179
1180 #[deprecated(
1181 since = "1.8.0",
1182 note = "Please use RpcClient::get_highest_snapshot_slot() instead"
1183 )]
1184 #[allow(deprecated)]
1185 pub fn get_snapshot_slot(&self) -> ClientResult<Slot> {
1186 self.invoke(self.rpc_client.get_snapshot_slot())
1187 }
1188
1189 /// Check if a transaction has been processed with the default [commitment level][cl].
1190 ///
1191 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1192 ///
1193 /// If the transaction has been processed with the default commitment level,
1194 /// then this method returns `Ok` of `Some`. If the transaction has not yet
1195 /// been processed with the default commitment level, it returns `Ok` of
1196 /// `None`.
1197 ///
1198 /// If the transaction has been processed with the default commitment level,
1199 /// and the transaction succeeded, this method returns `Ok(Some(Ok(())))`.
1200 /// If the transaction has peen processed with the default commitment level,
1201 /// and the transaction failed, this method returns `Ok(Some(Err(_)))`,
1202 /// where the interior error is type [`TransactionError`].
1203 ///
1204 /// [`TransactionError`]: solana_sdk::transaction::TransactionError
1205 ///
1206 /// This function only searches a node's recent history, including all
1207 /// recent slots, plus up to
1208 /// [`MAX_RECENT_BLOCKHASHES`][solana_sdk::clock::MAX_RECENT_BLOCKHASHES]
1209 /// rooted slots. To search the full transaction history use the
1210 /// [`get_signature_statuse_with_commitment_and_history`][RpcClient::get_signature_status_with_commitment_and_history]
1211 /// method.
1212 ///
1213 /// # RPC Reference
1214 ///
1215 /// This method is built on the [`getSignatureStatuses`] RPC method.
1216 ///
1217 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#gitsignaturestatuses
1218 ///
1219 /// # Examples
1220 ///
1221 /// ```
1222 /// # use safecoin_client::{
1223 /// # rpc_client::RpcClient,
1224 /// # client_error::ClientError,
1225 /// # };
1226 /// # use solana_sdk::{
1227 /// # signature::Signer,
1228 /// # signature::Signature,
1229 /// # signer::keypair::Keypair,
1230 /// # hash::Hash,
1231 /// # system_transaction,
1232 /// # };
1233 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1234 /// # let alice = Keypair::new();
1235 /// # let bob = Keypair::new();
1236 /// # let lamports = 50;
1237 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
1238 /// # let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
1239 /// let signature = rpc_client.send_transaction(&tx)?;
1240 /// let status = rpc_client.get_signature_status(&signature)?;
1241 /// # Ok::<(), ClientError>(())
1242 /// ```
1243 pub fn get_signature_status(
1244 &self,
1245 signature: &Signature,
1246 ) -> ClientResult<Option<transaction::Result<()>>> {
1247 self.invoke(self.rpc_client.get_signature_status(signature))
1248 }
1249
1250 /// Gets the statuses of a list of transaction signatures.
1251 ///
1252 /// The returned vector of [`TransactionStatus`] has the same length as the
1253 /// input slice.
1254 ///
1255 /// For any transaction that has not been processed by the network, the
1256 /// value of the corresponding entry in the returned vector is `None`. As a
1257 /// result, a transaction that has recently been submitted will not have a
1258 /// status immediately.
1259 ///
1260 /// To submit a transaction and wait for it to confirm, use
1261 /// [`send_and_confirm_transaction`][RpcClient::send_and_confirm_transaction].
1262 ///
1263 /// This function ignores the configured confirmation level, and returns the
1264 /// transaction status whatever it is. It does not wait for transactions to
1265 /// be processed.
1266 ///
1267 /// This function only searches a node's recent history, including all
1268 /// recent slots, plus up to
1269 /// [`MAX_RECENT_BLOCKHASHES`][solana_sdk::clock::MAX_RECENT_BLOCKHASHES]
1270 /// rooted slots. To search the full transaction history use the
1271 /// [`get_signature_statuses_with_history`][RpcClient::get_signature_statuses_with_history]
1272 /// method.
1273 ///
1274 /// # Errors
1275 ///
1276 /// Any individual `TransactionStatus` may have triggered an error during
1277 /// processing, in which case its [`err`][`TransactionStatus::err`] field
1278 /// will be `Some`.
1279 ///
1280 /// # RPC Reference
1281 ///
1282 /// This method corresponds directly to the [`getSignatureStatuses`] RPC method.
1283 ///
1284 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturestatuses
1285 ///
1286 /// # Examples
1287 ///
1288 /// ```
1289 /// # use safecoin_client::{
1290 /// # rpc_client::RpcClient,
1291 /// # client_error::ClientError,
1292 /// # };
1293 /// # use solana_sdk::{
1294 /// # signature::Signer,
1295 /// # signature::Signature,
1296 /// # signer::keypair::Keypair,
1297 /// # hash::Hash,
1298 /// # system_transaction,
1299 /// # };
1300 /// # use std::time::Duration;
1301 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1302 /// # let alice = Keypair::new();
1303 /// // Send lamports from Alice to Bob and wait for the transaction to be processed
1304 /// # let bob = Keypair::new();
1305 /// # let lamports = 50;
1306 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
1307 /// let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
1308 /// let signature = rpc_client.send_transaction(&tx)?;
1309 ///
1310 /// let status = loop {
1311 /// let statuses = rpc_client.get_signature_statuses(&[signature])?.value;
1312 /// if let Some(status) = statuses[0].clone() {
1313 /// break status;
1314 /// }
1315 /// std::thread::sleep(Duration::from_millis(100));
1316 /// };
1317 ///
1318 /// assert!(status.err.is_none());
1319 /// # Ok::<(), ClientError>(())
1320 /// ```
1321 pub fn get_signature_statuses(
1322 &self,
1323 signatures: &[Signature],
1324 ) -> RpcResult<Vec<Option<TransactionStatus>>> {
1325 self.invoke(self.rpc_client.get_signature_statuses(signatures))
1326 }
1327
1328 /// Gets the statuses of a list of transaction signatures.
1329 ///
1330 /// The returned vector of [`TransactionStatus`] has the same length as the
1331 /// input slice.
1332 ///
1333 /// For any transaction that has not been processed by the network, the
1334 /// value of the corresponding entry in the returned vector is `None`. As a
1335 /// result, a transaction that has recently been submitted will not have a
1336 /// status immediately.
1337 ///
1338 /// To submit a transaction and wait for it to confirm, use
1339 /// [`send_and_confirm_transaction`][RpcClient::send_and_confirm_transaction].
1340 ///
1341 /// This function ignores the configured confirmation level, and returns the
1342 /// transaction status whatever it is. It does not wait for transactions to
1343 /// be processed.
1344 ///
1345 /// This function searches a node's full ledger history and (if implemented) long-term storage. To search for
1346 /// transactions in recent slots only use the
1347 /// [`get_signature_statuses`][RpcClient::get_signature_statuses] method.
1348 ///
1349 /// # Errors
1350 ///
1351 /// Any individual `TransactionStatus` may have triggered an error during
1352 /// processing, in which case its [`err`][`TransactionStatus::err`] field
1353 /// will be `Some`.
1354 ///
1355 /// # RPC Reference
1356 ///
1357 /// This method corresponds directly to the [`getSignatureStatuses`] RPC
1358 /// method, with the `searchTransactionHistory` configuration option set to
1359 /// `true`.
1360 ///
1361 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturestatuses
1362 ///
1363 /// # Examples
1364 ///
1365 /// ```
1366 /// # use safecoin_client::{
1367 /// # rpc_client::RpcClient,
1368 /// # client_error::ClientError,
1369 /// # };
1370 /// # use solana_sdk::{
1371 /// # signature::Signer,
1372 /// # signature::Signature,
1373 /// # signer::keypair::Keypair,
1374 /// # hash::Hash,
1375 /// # system_transaction,
1376 /// # };
1377 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1378 /// # let alice = Keypair::new();
1379 /// # fn get_old_transaction_signature() -> Signature { Signature::default() }
1380 /// // Check if an old transaction exists
1381 /// let signature = get_old_transaction_signature();
1382 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
1383 /// let statuses = rpc_client.get_signature_statuses_with_history(&[signature])?.value;
1384 /// if statuses[0].is_none() {
1385 /// println!("old transaction does not exist");
1386 /// }
1387 /// # Ok::<(), ClientError>(())
1388 /// ```
1389 pub fn get_signature_statuses_with_history(
1390 &self,
1391 signatures: &[Signature],
1392 ) -> RpcResult<Vec<Option<TransactionStatus>>> {
1393 self.invoke(
1394 self.rpc_client
1395 .get_signature_statuses_with_history(signatures),
1396 )
1397 }
1398
1399 /// Check if a transaction has been processed with the given [commitment level][cl].
1400 ///
1401 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1402 ///
1403 /// If the transaction has been processed with the given commitment level,
1404 /// then this method returns `Ok` of `Some`. If the transaction has not yet
1405 /// been processed with the given commitment level, it returns `Ok` of
1406 /// `None`.
1407 ///
1408 /// If the transaction has been processed with the given commitment level,
1409 /// and the transaction succeeded, this method returns `Ok(Some(Ok(())))`.
1410 /// If the transaction has peen processed with the given commitment level,
1411 /// and the transaction failed, this method returns `Ok(Some(Err(_)))`,
1412 /// where the interior error is type [`TransactionError`].
1413 ///
1414 /// [`TransactionError`]: solana_sdk::transaction::TransactionError
1415 ///
1416 /// This function only searches a node's recent history, including all
1417 /// recent slots, plus up to
1418 /// [`MAX_RECENT_BLOCKHASHES`][solana_sdk::clock::MAX_RECENT_BLOCKHASHES]
1419 /// rooted slots. To search the full transaction history use the
1420 /// [`get_signature_statuse_with_commitment_and_history`][RpcClient::get_signature_status_with_commitment_and_history]
1421 /// method.
1422 ///
1423 /// # RPC Reference
1424 ///
1425 /// This method is built on the [`getSignatureStatuses`] RPC method.
1426 ///
1427 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturestatuses
1428 ///
1429 /// # Examples
1430 ///
1431 /// ```
1432 /// # use safecoin_client::{
1433 /// # rpc_client::RpcClient,
1434 /// # client_error::ClientError,
1435 /// # };
1436 /// # use solana_sdk::{
1437 /// # commitment_config::CommitmentConfig,
1438 /// # signature::Signer,
1439 /// # signature::Signature,
1440 /// # signer::keypair::Keypair,
1441 /// # system_transaction,
1442 /// # };
1443 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1444 /// # let alice = Keypair::new();
1445 /// # let bob = Keypair::new();
1446 /// # let lamports = 50;
1447 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
1448 /// # let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
1449 /// let signature = rpc_client.send_and_confirm_transaction(&tx)?;
1450 /// let commitment_config = CommitmentConfig::processed();
1451 /// let status = rpc_client.get_signature_status_with_commitment(
1452 /// &signature,
1453 /// commitment_config,
1454 /// )?;
1455 /// # Ok::<(), ClientError>(())
1456 /// ```
1457 pub fn get_signature_status_with_commitment(
1458 &self,
1459 signature: &Signature,
1460 commitment_config: CommitmentConfig,
1461 ) -> ClientResult<Option<transaction::Result<()>>> {
1462 self.invoke(
1463 self.rpc_client
1464 .get_signature_status_with_commitment(signature, commitment_config),
1465 )
1466 }
1467
1468 /// Check if a transaction has been processed with the given [commitment level][cl].
1469 ///
1470 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1471 ///
1472 /// If the transaction has been processed with the given commitment level,
1473 /// then this method returns `Ok` of `Some`. If the transaction has not yet
1474 /// been processed with the given commitment level, it returns `Ok` of
1475 /// `None`.
1476 ///
1477 /// If the transaction has been processed with the given commitment level,
1478 /// and the transaction succeeded, this method returns `Ok(Some(Ok(())))`.
1479 /// If the transaction has peen processed with the given commitment level,
1480 /// and the transaction failed, this method returns `Ok(Some(Err(_)))`,
1481 /// where the interior error is type [`TransactionError`].
1482 ///
1483 /// [`TransactionError`]: solana_sdk::transaction::TransactionError
1484 ///
1485 /// This method optionally searches a node's full ledger history and (if
1486 /// implemented) long-term storage.
1487 ///
1488 /// # RPC Reference
1489 ///
1490 /// This method is built on the [`getSignatureStatuses`] RPC method.
1491 ///
1492 /// [`getSignatureStatuses`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturestatuses
1493 ///
1494 /// # Examples
1495 ///
1496 /// ```
1497 /// # use safecoin_client::{
1498 /// # rpc_client::RpcClient,
1499 /// # client_error::ClientError,
1500 /// # };
1501 /// # use solana_sdk::{
1502 /// # commitment_config::CommitmentConfig,
1503 /// # signature::Signer,
1504 /// # signature::Signature,
1505 /// # signer::keypair::Keypair,
1506 /// # system_transaction,
1507 /// # };
1508 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1509 /// # let alice = Keypair::new();
1510 /// # let bob = Keypair::new();
1511 /// # let lamports = 50;
1512 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
1513 /// # let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
1514 /// let signature = rpc_client.send_transaction(&tx)?;
1515 /// let commitment_config = CommitmentConfig::processed();
1516 /// let search_transaction_history = true;
1517 /// let status = rpc_client.get_signature_status_with_commitment_and_history(
1518 /// &signature,
1519 /// commitment_config,
1520 /// search_transaction_history,
1521 /// )?;
1522 /// # Ok::<(), ClientError>(())
1523 /// ```
1524 pub fn get_signature_status_with_commitment_and_history(
1525 &self,
1526 signature: &Signature,
1527 commitment_config: CommitmentConfig,
1528 search_transaction_history: bool,
1529 ) -> ClientResult<Option<transaction::Result<()>>> {
1530 self.invoke(
1531 self.rpc_client
1532 .get_signature_status_with_commitment_and_history(
1533 signature,
1534 commitment_config,
1535 search_transaction_history,
1536 ),
1537 )
1538 }
1539
1540 /// Returns the slot that has reached the configured [commitment level][cl].
1541 ///
1542 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1543 ///
1544 /// # RPC Reference
1545 ///
1546 /// This method corresponds directly to the [`getSlot`] RPC method.
1547 ///
1548 /// [`getSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#getslot
1549 ///
1550 /// # Examples
1551 ///
1552 /// ```
1553 /// # use safecoin_client::{
1554 /// # rpc_client::RpcClient,
1555 /// # client_error::ClientError,
1556 /// # };
1557 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1558 /// let slot = rpc_client.get_slot()?;
1559 /// # Ok::<(), ClientError>(())
1560 /// ```
1561 pub fn get_slot(&self) -> ClientResult<Slot> {
1562 self.invoke(self.rpc_client.get_slot())
1563 }
1564
1565 /// Returns the slot that has reached the given [commitment level][cl].
1566 ///
1567 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1568 ///
1569 /// # RPC Reference
1570 ///
1571 /// This method corresponds directly to the [`getSlot`] RPC method.
1572 ///
1573 /// [`getSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#getslot
1574 ///
1575 /// # Examples
1576 ///
1577 /// ```
1578 /// # use safecoin_client::{
1579 /// # rpc_client::RpcClient,
1580 /// # client_error::ClientError,
1581 /// # };
1582 /// # use solana_sdk::commitment_config::CommitmentConfig;
1583 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1584 /// let commitment_config = CommitmentConfig::processed();
1585 /// let slot = rpc_client.get_slot_with_commitment(commitment_config)?;
1586 /// # Ok::<(), ClientError>(())
1587 /// ```
1588 pub fn get_slot_with_commitment(
1589 &self,
1590 commitment_config: CommitmentConfig,
1591 ) -> ClientResult<Slot> {
1592 self.invoke(self.rpc_client.get_slot_with_commitment(commitment_config))
1593 }
1594
1595 /// Returns the block height that has reached the configured [commitment level][cl].
1596 ///
1597 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1598 ///
1599 /// # RPC Reference
1600 ///
1601 /// This method is corresponds directly to the [`getBlockHeight`] RPC method.
1602 ///
1603 /// [`getBlockHeight`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblockheight
1604 ///
1605 /// # Examples
1606 ///
1607 /// ```
1608 /// # use safecoin_client::{
1609 /// # rpc_client::RpcClient,
1610 /// # client_error::ClientError,
1611 /// # };
1612 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1613 /// let block_height = rpc_client.get_block_height()?;
1614 /// # Ok::<(), ClientError>(())
1615 /// ```
1616 pub fn get_block_height(&self) -> ClientResult<u64> {
1617 self.invoke(self.rpc_client.get_block_height())
1618 }
1619
1620 /// Returns the block height that has reached the given [commitment level][cl].
1621 ///
1622 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1623 ///
1624 /// # RPC Reference
1625 ///
1626 /// This method is corresponds directly to the [`getBlockHeight`] RPC method.
1627 ///
1628 /// [`getBlockHeight`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblockheight
1629 ///
1630 /// # Examples
1631 ///
1632 /// ```
1633 /// # use safecoin_client::{
1634 /// # rpc_client::RpcClient,
1635 /// # client_error::ClientError,
1636 /// # };
1637 /// # use solana_sdk::commitment_config::CommitmentConfig;
1638 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1639 /// let commitment_config = CommitmentConfig::processed();
1640 /// let block_height = rpc_client.get_block_height_with_commitment(
1641 /// commitment_config,
1642 /// )?;
1643 /// # Ok::<(), ClientError>(())
1644 /// ```
1645 pub fn get_block_height_with_commitment(
1646 &self,
1647 commitment_config: CommitmentConfig,
1648 ) -> ClientResult<u64> {
1649 self.invoke(
1650 self.rpc_client
1651 .get_block_height_with_commitment(commitment_config),
1652 )
1653 }
1654
1655 /// Returns the slot leaders for a given slot range.
1656 ///
1657 /// # RPC Reference
1658 ///
1659 /// This method corresponds directly to the [`getSlotLeaders`] RPC method.
1660 ///
1661 /// [`getSlotLeaders`]: https://docs.solana.com/developing/clients/jsonrpc-api#getslotleaders
1662 ///
1663 /// # Examples
1664 ///
1665 /// ```
1666 /// # use safecoin_client::{
1667 /// # rpc_client::RpcClient,
1668 /// # client_error::ClientError,
1669 /// # };
1670 /// # use solana_sdk::slot_history::Slot;
1671 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1672 /// let start_slot = 1;
1673 /// let limit = 3;
1674 /// let leaders = rpc_client.get_slot_leaders(start_slot, limit)?;
1675 /// # Ok::<(), ClientError>(())
1676 /// ```
1677 pub fn get_slot_leaders(&self, start_slot: Slot, limit: u64) -> ClientResult<Vec<Pubkey>> {
1678 self.invoke(self.rpc_client.get_slot_leaders(start_slot, limit))
1679 }
1680
1681 /// Get block production for the current epoch.
1682 ///
1683 /// # RPC Reference
1684 ///
1685 /// This method corresponds directly to the [`getBlockProduction`] RPC method.
1686 ///
1687 /// [`getBlockProduction`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblockproduction
1688 ///
1689 /// # Examples
1690 ///
1691 /// ```
1692 /// # use safecoin_client::{
1693 /// # rpc_client::RpcClient,
1694 /// # client_error::ClientError,
1695 /// # };
1696 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1697 /// let production = rpc_client.get_block_production()?;
1698 /// # Ok::<(), ClientError>(())
1699 /// ```
1700 pub fn get_block_production(&self) -> RpcResult<RpcBlockProduction> {
1701 self.invoke(self.rpc_client.get_block_production())
1702 }
1703
1704 /// Get block production for the current or previous epoch.
1705 ///
1706 /// # RPC Reference
1707 ///
1708 /// This method corresponds directly to the [`getBlockProduction`] RPC method.
1709 ///
1710 /// [`getBlockProduction`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblockproduction
1711 ///
1712 /// # Examples
1713 ///
1714 /// ```
1715 /// # use safecoin_client::{
1716 /// # rpc_client::RpcClient,
1717 /// # client_error::ClientError,
1718 /// # rpc_config::RpcBlockProductionConfig,
1719 /// # rpc_config::RpcBlockProductionConfigRange,
1720 /// # };
1721 /// # use solana_sdk::{
1722 /// # signature::Signer,
1723 /// # signer::keypair::Keypair,
1724 /// # commitment_config::CommitmentConfig,
1725 /// # };
1726 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1727 /// # let start_slot = 1;
1728 /// # let limit = 3;
1729 /// let leader = rpc_client.get_slot_leaders(start_slot, limit)?;
1730 /// let leader = leader[0];
1731 /// let range = RpcBlockProductionConfigRange {
1732 /// first_slot: start_slot,
1733 /// last_slot: Some(start_slot + limit),
1734 /// };
1735 /// let config = RpcBlockProductionConfig {
1736 /// identity: Some(leader.to_string()),
1737 /// range: Some(range),
1738 /// commitment: Some(CommitmentConfig::processed()),
1739 /// };
1740 /// let production = rpc_client.get_block_production_with_config(
1741 /// config
1742 /// )?;
1743 /// # Ok::<(), ClientError>(())
1744 /// ```
1745 pub fn get_block_production_with_config(
1746 &self,
1747 config: RpcBlockProductionConfig,
1748 ) -> RpcResult<RpcBlockProduction> {
1749 self.invoke(self.rpc_client.get_block_production_with_config(config))
1750 }
1751
1752 /// Returns epoch activation information for a stake account.
1753 ///
1754 /// This method uses the configured [commitment level].
1755 ///
1756 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1757 ///
1758 /// # RPC Reference
1759 ///
1760 /// This method corresponds directly to the [`getStakeActivation`] RPC method.
1761 ///
1762 /// [`getStakeActivation`]: https://docs.solana.com/developing/clients/jsonrpc-api#getstakeactivation
1763 ///
1764 /// # Examples
1765 ///
1766 /// ```
1767 /// # use safecoin_client::{
1768 /// # rpc_client::RpcClient,
1769 /// # client_error::ClientError,
1770 /// # rpc_response::StakeActivationState,
1771 /// # };
1772 /// # use solana_sdk::{
1773 /// # signer::keypair::Keypair,
1774 /// # signature::Signer,
1775 /// # pubkey::Pubkey,
1776 /// # stake,
1777 /// # stake::state::{Authorized, Lockup},
1778 /// # transaction::Transaction
1779 /// # };
1780 /// # use std::str::FromStr;
1781 /// # let alice = Keypair::new();
1782 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1783 /// // Find some vote account to delegate to
1784 /// let vote_accounts = rpc_client.get_vote_accounts()?;
1785 /// let vote_account = vote_accounts.current.get(0).unwrap_or_else(|| &vote_accounts.delinquent[0]);
1786 /// let vote_account_pubkey = &vote_account.vote_pubkey;
1787 /// let vote_account_pubkey = Pubkey::from_str(vote_account_pubkey).expect("pubkey");
1788 ///
1789 /// // Create a stake account
1790 /// let stake_account = Keypair::new();
1791 /// let stake_account_pubkey = stake_account.pubkey();
1792 ///
1793 /// // Build the instructions to create new stake account,
1794 /// // funded by alice, and delegate to a validator's vote account.
1795 /// let instrs = stake::instruction::create_account_and_delegate_stake(
1796 /// &alice.pubkey(),
1797 /// &stake_account_pubkey,
1798 /// &vote_account_pubkey,
1799 /// &Authorized::auto(&stake_account_pubkey),
1800 /// &Lockup::default(),
1801 /// 1_000_000,
1802 /// );
1803 ///
1804 /// let latest_blockhash = rpc_client.get_latest_blockhash()?;
1805 /// let tx = Transaction::new_signed_with_payer(
1806 /// &instrs,
1807 /// Some(&alice.pubkey()),
1808 /// &[&alice, &stake_account],
1809 /// latest_blockhash,
1810 /// );
1811 ///
1812 /// rpc_client.send_and_confirm_transaction(&tx)?;
1813 ///
1814 /// let epoch_info = rpc_client.get_epoch_info()?;
1815 /// let activation = rpc_client.get_stake_activation(
1816 /// stake_account_pubkey,
1817 /// Some(epoch_info.epoch),
1818 /// )?;
1819 ///
1820 /// assert_eq!(activation.state, StakeActivationState::Activating);
1821 /// # Ok::<(), ClientError>(())
1822 /// ```
1823 pub fn get_stake_activation(
1824 &self,
1825 stake_account: Pubkey,
1826 epoch: Option<Epoch>,
1827 ) -> ClientResult<RpcStakeActivation> {
1828 self.invoke(self.rpc_client.get_stake_activation(stake_account, epoch))
1829 }
1830
1831 /// Returns information about the current supply.
1832 ///
1833 /// This method uses the configured [commitment level][cl].
1834 ///
1835 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1836 ///
1837 /// # RPC Reference
1838 ///
1839 /// This method corresponds directly to the [`getSupply`] RPC method.
1840 ///
1841 /// [`getSupply`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsupply
1842 ///
1843 /// # Examples
1844 ///
1845 /// ```
1846 /// # use safecoin_client::{
1847 /// # rpc_client::RpcClient,
1848 /// # client_error::ClientError,
1849 /// # };
1850 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1851 /// let supply = rpc_client.supply()?;
1852 /// # Ok::<(), ClientError>(())
1853 /// ```
1854 pub fn supply(&self) -> RpcResult<RpcSupply> {
1855 self.invoke(self.rpc_client.supply())
1856 }
1857
1858 /// Returns information about the current supply.
1859 ///
1860 /// # RPC Reference
1861 ///
1862 /// This method corresponds directly to the [`getSupply`] RPC method.
1863 ///
1864 /// [`getSupply`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsupply
1865 ///
1866 /// # Examples
1867 ///
1868 /// ```
1869 /// # use safecoin_client::{
1870 /// # rpc_client::RpcClient,
1871 /// # client_error::ClientError,
1872 /// # };
1873 /// # use solana_sdk::commitment_config::CommitmentConfig;
1874 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1875 /// let commitment_config = CommitmentConfig::processed();
1876 /// let supply = rpc_client.supply_with_commitment(
1877 /// commitment_config,
1878 /// )?;
1879 /// # Ok::<(), ClientError>(())
1880 /// ```
1881 pub fn supply_with_commitment(
1882 &self,
1883 commitment_config: CommitmentConfig,
1884 ) -> RpcResult<RpcSupply> {
1885 self.invoke(self.rpc_client.supply_with_commitment(commitment_config))
1886 }
1887
1888 /// Returns the 20 largest accounts, by lamport balance.
1889 ///
1890 /// # RPC Reference
1891 ///
1892 /// This method corresponds directly to the [`getLargestAccounts`] RPC
1893 /// method.
1894 ///
1895 /// [`getLargestAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getlargestaccounts
1896 ///
1897 /// # Examples
1898 ///
1899 /// ```
1900 /// # use safecoin_client::{
1901 /// # rpc_client::RpcClient,
1902 /// # client_error::ClientError,
1903 /// # rpc_config::RpcLargestAccountsConfig,
1904 /// # rpc_config::RpcLargestAccountsFilter,
1905 /// # };
1906 /// # use solana_sdk::commitment_config::CommitmentConfig;
1907 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1908 /// let commitment_config = CommitmentConfig::processed();
1909 /// let config = RpcLargestAccountsConfig {
1910 /// commitment: Some(commitment_config),
1911 /// filter: Some(RpcLargestAccountsFilter::Circulating),
1912 /// };
1913 /// let accounts = rpc_client.get_largest_accounts_with_config(
1914 /// config,
1915 /// )?;
1916 /// # Ok::<(), ClientError>(())
1917 /// ```
1918 pub fn get_largest_accounts_with_config(
1919 &self,
1920 config: RpcLargestAccountsConfig,
1921 ) -> RpcResult<Vec<RpcAccountBalance>> {
1922 self.invoke(self.rpc_client.get_largest_accounts_with_config(config))
1923 }
1924
1925 /// Returns the account info and associated stake for all the voting accounts
1926 /// that have reached the configured [commitment level][cl].
1927 ///
1928 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1929 ///
1930 /// # RPC Reference
1931 ///
1932 /// This method corresponds directly to the [`getVoteAccounts`]
1933 /// RPC method.
1934 ///
1935 /// [`getVoteAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getvoteaccounts
1936 ///
1937 /// # Examples
1938 ///
1939 /// ```
1940 /// # use safecoin_client::{
1941 /// # rpc_client::RpcClient,
1942 /// # client_error::ClientError,
1943 /// # };
1944 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1945 /// let accounts = rpc_client.get_vote_accounts()?;
1946 /// # Ok::<(), ClientError>(())
1947 /// ```
1948 pub fn get_vote_accounts(&self) -> ClientResult<RpcVoteAccountStatus> {
1949 self.invoke(self.rpc_client.get_vote_accounts())
1950 }
1951
1952 /// Returns the account info and associated stake for all the voting accounts
1953 /// that have reached the given [commitment level][cl].
1954 ///
1955 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1956 ///
1957 /// # RPC Reference
1958 ///
1959 /// This method corresponds directly to the [`getVoteAccounts`] RPC method.
1960 ///
1961 /// [`getVoteAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getvoteaccounts
1962 ///
1963 /// # Examples
1964 ///
1965 /// ```
1966 /// # use solana_sdk::commitment_config::CommitmentConfig;
1967 /// # use safecoin_client::{
1968 /// # rpc_client::RpcClient,
1969 /// # client_error::ClientError,
1970 /// # };
1971 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
1972 /// let commitment_config = CommitmentConfig::processed();
1973 /// let accounts = rpc_client.get_vote_accounts_with_commitment(
1974 /// commitment_config,
1975 /// )?;
1976 /// # Ok::<(), ClientError>(())
1977 /// ```
1978 pub fn get_vote_accounts_with_commitment(
1979 &self,
1980 commitment_config: CommitmentConfig,
1981 ) -> ClientResult<RpcVoteAccountStatus> {
1982 self.invoke(
1983 self.rpc_client
1984 .get_vote_accounts_with_commitment(commitment_config),
1985 )
1986 }
1987
1988 /// Returns the account info and associated stake for all the voting accounts
1989 /// that have reached the given [commitment level][cl].
1990 ///
1991 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
1992 ///
1993 /// # RPC Reference
1994 ///
1995 /// This method corresponds directly to the [`getVoteAccounts`] RPC method.
1996 ///
1997 /// [`getVoteAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getvoteaccounts
1998 ///
1999 /// # Examples
2000 ///
2001 /// ```
2002 /// # use safecoin_client::{
2003 /// # rpc_client::RpcClient,
2004 /// # client_error::ClientError,
2005 /// # rpc_config::RpcGetVoteAccountsConfig,
2006 /// # };
2007 /// # use solana_sdk::{
2008 /// # signer::keypair::Keypair,
2009 /// # signature::Signer,
2010 /// # commitment_config::CommitmentConfig,
2011 /// # };
2012 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2013 /// # let vote_keypair = Keypair::new();
2014 /// let vote_pubkey = vote_keypair.pubkey();
2015 /// let commitment = CommitmentConfig::processed();
2016 /// let config = RpcGetVoteAccountsConfig {
2017 /// vote_pubkey: Some(vote_pubkey.to_string()),
2018 /// commitment: Some(commitment),
2019 /// keep_unstaked_delinquents: Some(true),
2020 /// delinquent_slot_distance: Some(10),
2021 /// };
2022 /// let accounts = rpc_client.get_vote_accounts_with_config(
2023 /// config,
2024 /// )?;
2025 /// # Ok::<(), ClientError>(())
2026 /// ```
2027 pub fn get_vote_accounts_with_config(
2028 &self,
2029 config: RpcGetVoteAccountsConfig,
2030 ) -> ClientResult<RpcVoteAccountStatus> {
2031 self.invoke(self.rpc_client.get_vote_accounts_with_config(config))
2032 }
2033
2034 pub fn wait_for_max_stake(
2035 &self,
2036 commitment: CommitmentConfig,
2037 max_stake_percent: f32,
2038 ) -> ClientResult<()> {
2039 self.invoke(
2040 self.rpc_client
2041 .wait_for_max_stake(commitment, max_stake_percent),
2042 )
2043 }
2044
2045 /// Returns information about all the nodes participating in the cluster.
2046 ///
2047 /// # RPC Reference
2048 ///
2049 /// This method corresponds directly to the [`getClusterNodes`]
2050 /// RPC method.
2051 ///
2052 /// [`getClusterNodes`]: https://docs.solana.com/developing/clients/jsonrpc-api#getclusternodes
2053 ///
2054 /// # Examples
2055 ///
2056 /// ```
2057 /// # use safecoin_client::{
2058 /// # rpc_client::RpcClient,
2059 /// # client_error::ClientError,
2060 /// # };
2061 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2062 /// let cluster_nodes = rpc_client.get_cluster_nodes()?;
2063 /// # Ok::<(), ClientError>(())
2064 /// ```
2065 pub fn get_cluster_nodes(&self) -> ClientResult<Vec<RpcContactInfo>> {
2066 self.invoke(self.rpc_client.get_cluster_nodes())
2067 }
2068
2069 /// Returns identity and transaction information about a confirmed block in the ledger.
2070 ///
2071 /// The encodings are returned in [`UiTransactionEncoding::Json`][uite]
2072 /// format. To return transactions in other encodings, use
2073 /// [`get_block_with_encoding`].
2074 ///
2075 /// [`get_block_with_encoding`]: RpcClient::get_block_with_encoding
2076 /// [uite]: UiTransactionEncoding::Json
2077 ///
2078 /// # RPC Reference
2079 ///
2080 /// This method corresponds directly to the [`getBlock`] RPC
2081 /// method.
2082 ///
2083 /// [`getBlock`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblock
2084 ///
2085 /// # Examples
2086 ///
2087 /// ```
2088 /// # use safecoin_client::{
2089 /// # rpc_client::RpcClient,
2090 /// # client_error::ClientError,
2091 /// # };
2092 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2093 /// # let slot = rpc_client.get_slot()?;
2094 /// let block = rpc_client.get_block(slot)?;
2095 /// # Ok::<(), ClientError>(())
2096 /// ```
2097 pub fn get_block(&self, slot: Slot) -> ClientResult<EncodedConfirmedBlock> {
2098 self.invoke(self.rpc_client.get_block(slot))
2099 }
2100
2101 /// Returns identity and transaction information about a confirmed block in the ledger.
2102 ///
2103 /// # RPC Reference
2104 ///
2105 /// This method corresponds directly to the [`getBlock`] RPC method.
2106 ///
2107 /// [`getBlock`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblock
2108 ///
2109 /// # Examples
2110 ///
2111 /// ```
2112 /// # use safecoin_transaction_status::UiTransactionEncoding;
2113 /// # use safecoin_client::{
2114 /// # rpc_client::RpcClient,
2115 /// # client_error::ClientError,
2116 /// # };
2117 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2118 /// # let slot = rpc_client.get_slot()?;
2119 /// let encoding = UiTransactionEncoding::Base58;
2120 /// let block = rpc_client.get_block_with_encoding(
2121 /// slot,
2122 /// encoding,
2123 /// )?;
2124 /// # Ok::<(), ClientError>(())
2125 /// ```
2126 pub fn get_block_with_encoding(
2127 &self,
2128 slot: Slot,
2129 encoding: UiTransactionEncoding,
2130 ) -> ClientResult<EncodedConfirmedBlock> {
2131 self.invoke(self.rpc_client.get_block_with_encoding(slot, encoding))
2132 }
2133
2134 /// Returns identity and transaction information about a confirmed block in the ledger.
2135 ///
2136 /// # RPC Reference
2137 ///
2138 /// This method corresponds directly to the [`getBlock`] RPC method.
2139 ///
2140 /// [`getBlock`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblock
2141 ///
2142 /// # Examples
2143 ///
2144 /// ```
2145 /// # use safecoin_transaction_status::{
2146 /// # TransactionDetails,
2147 /// # UiTransactionEncoding,
2148 /// # };
2149 /// # use safecoin_client::{
2150 /// # rpc_client::RpcClient,
2151 /// # rpc_config::RpcBlockConfig,
2152 /// # client_error::ClientError,
2153 /// # };
2154 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2155 /// # let slot = rpc_client.get_slot()?;
2156 /// let config = RpcBlockConfig {
2157 /// encoding: Some(UiTransactionEncoding::Base58),
2158 /// transaction_details: Some(TransactionDetails::None),
2159 /// rewards: Some(true),
2160 /// commitment: None,
2161 /// max_supported_transaction_version: Some(0),
2162 /// };
2163 /// let block = rpc_client.get_block_with_config(
2164 /// slot,
2165 /// config,
2166 /// )?;
2167 /// # Ok::<(), ClientError>(())
2168 /// ```
2169 pub fn get_block_with_config(
2170 &self,
2171 slot: Slot,
2172 config: RpcBlockConfig,
2173 ) -> ClientResult<UiConfirmedBlock> {
2174 self.invoke(self.rpc_client.get_block_with_config(slot, config))
2175 }
2176
2177 #[deprecated(since = "1.7.0", note = "Please use RpcClient::get_block() instead")]
2178 #[allow(deprecated)]
2179 pub fn get_confirmed_block(&self, slot: Slot) -> ClientResult<EncodedConfirmedBlock> {
2180 self.invoke(self.rpc_client.get_confirmed_block(slot))
2181 }
2182
2183 #[deprecated(
2184 since = "1.7.0",
2185 note = "Please use RpcClient::get_block_with_encoding() instead"
2186 )]
2187 #[allow(deprecated)]
2188 pub fn get_confirmed_block_with_encoding(
2189 &self,
2190 slot: Slot,
2191 encoding: UiTransactionEncoding,
2192 ) -> ClientResult<EncodedConfirmedBlock> {
2193 self.invoke(
2194 self.rpc_client
2195 .get_confirmed_block_with_encoding(slot, encoding),
2196 )
2197 }
2198
2199 #[deprecated(
2200 since = "1.7.0",
2201 note = "Please use RpcClient::get_block_with_config() instead"
2202 )]
2203 #[allow(deprecated)]
2204 pub fn get_confirmed_block_with_config(
2205 &self,
2206 slot: Slot,
2207 config: RpcConfirmedBlockConfig,
2208 ) -> ClientResult<UiConfirmedBlock> {
2209 self.invoke(
2210 self.rpc_client
2211 .get_confirmed_block_with_config(slot, config),
2212 )
2213 }
2214
2215 /// Returns a list of finalized blocks between two slots.
2216 ///
2217 /// The range is inclusive, with results including the block for both
2218 /// `start_slot` and `end_slot`.
2219 ///
2220 /// If `end_slot` is not provided, then the end slot is for the latest
2221 /// finalized block.
2222 ///
2223 /// This method may not return blocks for the full range of slots if some
2224 /// slots do not have corresponding blocks. To simply get a specific number
2225 /// of sequential blocks, use the [`get_blocks_with_limit`] method.
2226 ///
2227 /// This method uses the [`Finalized`] [commitment level][cl].
2228 ///
2229 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
2230 /// [`get_blocks_with_limit`]: RpcClient::get_blocks_with_limit.
2231 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2232 ///
2233 /// # Errors
2234 ///
2235 /// This method returns an error if the range is greater than 500,000 slots.
2236 ///
2237 /// # RPC Reference
2238 ///
2239 /// This method corresponds directly to the [`getBlocks`] RPC method, unless
2240 /// the remote node version is less than 1.7, in which case it maps to the
2241 /// [`getConfirmedBlocks`] RPC method.
2242 ///
2243 /// [`getBlocks`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblocks
2244 /// [`getConfirmedBlocks`]: https://docs.solana.com/developing/clients/jsonrpc-api#getConfirmedblocks
2245 ///
2246 /// # Examples
2247 ///
2248 /// ```
2249 /// # use safecoin_client::{
2250 /// # rpc_client::RpcClient,
2251 /// # client_error::ClientError,
2252 /// # };
2253 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2254 /// // Get up to the first 10 blocks
2255 /// let start_slot = 0;
2256 /// let end_slot = 9;
2257 /// let blocks = rpc_client.get_blocks(start_slot, Some(end_slot))?;
2258 /// # Ok::<(), ClientError>(())
2259 /// ```
2260 pub fn get_blocks(&self, start_slot: Slot, end_slot: Option<Slot>) -> ClientResult<Vec<Slot>> {
2261 self.invoke(self.rpc_client.get_blocks(start_slot, end_slot))
2262 }
2263
2264 /// Returns a list of confirmed blocks between two slots.
2265 ///
2266 /// The range is inclusive, with results including the block for both
2267 /// `start_slot` and `end_slot`.
2268 ///
2269 /// If `end_slot` is not provided, then the end slot is for the latest
2270 /// block with the given [commitment level][cl].
2271 ///
2272 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2273 ///
2274 /// This method may not return blocks for the full range of slots if some
2275 /// slots do not have corresponding blocks. To simply get a specific number
2276 /// of sequential blocks, use the [`get_blocks_with_limit_and_commitment`]
2277 /// method.
2278 ///
2279 /// [`get_blocks_with_limit_and_commitment`]: RpcClient::get_blocks_with_limit_and_commitment.
2280 ///
2281 /// # Errors
2282 ///
2283 /// This method returns an error if the range is greater than 500,000 slots.
2284 ///
2285 /// This method returns an error if the given commitment level is below
2286 /// [`Confirmed`].
2287 ///
2288 /// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
2289 ///
2290 /// # RPC Reference
2291 ///
2292 /// This method corresponds directly to the [`getBlocks`] RPC method, unless
2293 /// the remote node version is less than 1.7, in which case it maps to the
2294 /// [`getConfirmedBlocks`] RPC method.
2295 ///
2296 /// [`getBlocks`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblocks
2297 /// [`getConfirmedBlocks`]: https://docs.solana.com/developing/clients/jsonrpc-api#getConfirmedblocks
2298 ///
2299 /// # Examples
2300 ///
2301 /// ```
2302 /// # use solana_sdk::commitment_config::CommitmentConfig;
2303 /// # use safecoin_client::{
2304 /// # rpc_client::RpcClient,
2305 /// # client_error::ClientError,
2306 /// # };
2307 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2308 /// // Get up to the first 10 blocks
2309 /// let start_slot = 0;
2310 /// let end_slot = 9;
2311 /// // Method does not support commitment below `confirmed`
2312 /// let commitment_config = CommitmentConfig::confirmed();
2313 /// let blocks = rpc_client.get_blocks_with_commitment(
2314 /// start_slot,
2315 /// Some(end_slot),
2316 /// commitment_config,
2317 /// )?;
2318 /// # Ok::<(), ClientError>(())
2319 /// ```
2320 pub fn get_blocks_with_commitment(
2321 &self,
2322 start_slot: Slot,
2323 end_slot: Option<Slot>,
2324 commitment_config: CommitmentConfig,
2325 ) -> ClientResult<Vec<Slot>> {
2326 self.invoke(self.rpc_client.get_blocks_with_commitment(
2327 start_slot,
2328 end_slot,
2329 commitment_config,
2330 ))
2331 }
2332
2333 /// Returns a list of finalized blocks starting at the given slot.
2334 ///
2335 /// This method uses the [`Finalized`] [commitment level][cl].
2336 ///
2337 /// [`Finalized`]: CommitmentLevel::Finalized.
2338 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2339 ///
2340 /// # Errors
2341 ///
2342 /// This method returns an error if the limit is greater than 500,000 slots.
2343 ///
2344 /// # RPC Reference
2345 ///
2346 /// This method corresponds directly to the [`getBlocksWithLimit`] RPC
2347 /// method, unless the remote node version is less than 1.7, in which case
2348 /// it maps to the [`getConfirmedBlocksWithLimit`] RPC method.
2349 ///
2350 /// [`getBlocksWithLimit`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblockswithlimit
2351 /// [`getConfirmedBlocksWithLimit`]: https://docs.solana.com/developing/clients/jsonrpc-api#getconfirmedblockswithlimit
2352 ///
2353 /// # Examples
2354 ///
2355 /// ```
2356 /// # use safecoin_client::{
2357 /// # rpc_client::RpcClient,
2358 /// # client_error::ClientError,
2359 /// # };
2360 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2361 /// // Get the first 10 blocks
2362 /// let start_slot = 0;
2363 /// let limit = 10;
2364 /// let blocks = rpc_client.get_blocks_with_limit(start_slot, limit)?;
2365 /// # Ok::<(), ClientError>(())
2366 /// ```
2367 pub fn get_blocks_with_limit(&self, start_slot: Slot, limit: usize) -> ClientResult<Vec<Slot>> {
2368 self.invoke(self.rpc_client.get_blocks_with_limit(start_slot, limit))
2369 }
2370
2371 /// Returns a list of confirmed blocks starting at the given slot.
2372 ///
2373 /// # Errors
2374 ///
2375 /// This method returns an error if the limit is greater than 500,000 slots.
2376 ///
2377 /// This method returns an error if the given [commitment level][cl] is below
2378 /// [`Confirmed`].
2379 ///
2380 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2381 /// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
2382 ///
2383 /// # RPC Reference
2384 ///
2385 /// This method corresponds directly to the [`getBlocksWithLimit`] RPC
2386 /// method, unless the remote node version is less than 1.7, in which case
2387 /// it maps to the `getConfirmedBlocksWithLimit` RPC method.
2388 ///
2389 /// [`getBlocksWithLimit`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblockswithlimit
2390 /// [`getConfirmedBlocksWithLimit`]: https://docs.solana.com/developing/clients/jsonrpc-api#getconfirmedblockswithlimit
2391 ///
2392 /// # Examples
2393 ///
2394 /// ```
2395 /// # use solana_sdk::commitment_config::CommitmentConfig;
2396 /// # use safecoin_client::{
2397 /// # rpc_client::RpcClient,
2398 /// # client_error::ClientError,
2399 /// # };
2400 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2401 /// // Get the first 10 blocks
2402 /// let start_slot = 0;
2403 /// let limit = 10;
2404 /// let commitment_config = CommitmentConfig::confirmed();
2405 /// let blocks = rpc_client.get_blocks_with_limit_and_commitment(
2406 /// start_slot,
2407 /// limit,
2408 /// commitment_config,
2409 /// )?;
2410 /// # Ok::<(), ClientError>(())
2411 /// ```
2412 pub fn get_blocks_with_limit_and_commitment(
2413 &self,
2414 start_slot: Slot,
2415 limit: usize,
2416 commitment_config: CommitmentConfig,
2417 ) -> ClientResult<Vec<Slot>> {
2418 self.invoke(self.rpc_client.get_blocks_with_limit_and_commitment(
2419 start_slot,
2420 limit,
2421 commitment_config,
2422 ))
2423 }
2424
2425 #[deprecated(since = "1.7.0", note = "Please use RpcClient::get_blocks() instead")]
2426 #[allow(deprecated)]
2427 pub fn get_confirmed_blocks(
2428 &self,
2429 start_slot: Slot,
2430 end_slot: Option<Slot>,
2431 ) -> ClientResult<Vec<Slot>> {
2432 self.invoke(self.rpc_client.get_confirmed_blocks(start_slot, end_slot))
2433 }
2434
2435 #[deprecated(
2436 since = "1.7.0",
2437 note = "Please use RpcClient::get_blocks_with_commitment() instead"
2438 )]
2439 #[allow(deprecated)]
2440 pub fn get_confirmed_blocks_with_commitment(
2441 &self,
2442 start_slot: Slot,
2443 end_slot: Option<Slot>,
2444 commitment_config: CommitmentConfig,
2445 ) -> ClientResult<Vec<Slot>> {
2446 self.invoke(self.rpc_client.get_confirmed_blocks_with_commitment(
2447 start_slot,
2448 end_slot,
2449 commitment_config,
2450 ))
2451 }
2452
2453 #[deprecated(
2454 since = "1.7.0",
2455 note = "Please use RpcClient::get_blocks_with_limit() instead"
2456 )]
2457 #[allow(deprecated)]
2458 pub fn get_confirmed_blocks_with_limit(
2459 &self,
2460 start_slot: Slot,
2461 limit: usize,
2462 ) -> ClientResult<Vec<Slot>> {
2463 self.invoke(
2464 self.rpc_client
2465 .get_confirmed_blocks_with_limit(start_slot, limit),
2466 )
2467 }
2468
2469 #[deprecated(
2470 since = "1.7.0",
2471 note = "Please use RpcClient::get_blocks_with_limit_and_commitment() instead"
2472 )]
2473 #[allow(deprecated)]
2474 pub fn get_confirmed_blocks_with_limit_and_commitment(
2475 &self,
2476 start_slot: Slot,
2477 limit: usize,
2478 commitment_config: CommitmentConfig,
2479 ) -> ClientResult<Vec<Slot>> {
2480 self.invoke(
2481 self.rpc_client
2482 .get_confirmed_blocks_with_limit_and_commitment(
2483 start_slot,
2484 limit,
2485 commitment_config,
2486 ),
2487 )
2488 }
2489
2490 /// Get confirmed signatures for transactions involving an address.
2491 ///
2492 /// Returns up to 1000 signatures, ordered from newest to oldest.
2493 ///
2494 /// This method uses the [`Finalized`] [commitment level][cl].
2495 ///
2496 /// [`Finalized`]: CommitmentLevel::Finalized.
2497 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2498 ///
2499 /// # RPC Reference
2500 ///
2501 /// This method corresponds directly to the [`getSignaturesForAddress`] RPC
2502 /// method, unless the remote node version is less than 1.7, in which case
2503 /// it maps to the [`getSignaturesForAddress2`] RPC method.
2504 ///
2505 /// [`getSignaturesForAddress`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturesforaddress
2506 /// [`getSignaturesForAddress2`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturesforaddress2
2507 ///
2508 /// # Examples
2509 ///
2510 /// ```
2511 /// # use safecoin_client::{
2512 /// # client_error::ClientError,
2513 /// # rpc_client::RpcClient,
2514 /// # };
2515 /// # use solana_sdk::{
2516 /// # signature::Signer,
2517 /// # signer::keypair::Keypair,
2518 /// # system_transaction,
2519 /// # };
2520 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2521 /// # let alice = Keypair::new();
2522 /// let signatures = rpc_client.get_signatures_for_address(
2523 /// &alice.pubkey(),
2524 /// )?;
2525 /// # Ok::<(), ClientError>(())
2526 /// ```
2527 pub fn get_signatures_for_address(
2528 &self,
2529 address: &Pubkey,
2530 ) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
2531 self.invoke(self.rpc_client.get_signatures_for_address(address))
2532 }
2533
2534 /// Get confirmed signatures for transactions involving an address.
2535 ///
2536 /// # Errors
2537 ///
2538 /// This method returns an error if the given [commitment level][cl] is below
2539 /// [`Confirmed`].
2540 ///
2541 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2542 /// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
2543 ///
2544 /// # RPC Reference
2545 ///
2546 /// This method corresponds directly to the [`getSignaturesForAddress`] RPC
2547 /// method, unless the remote node version is less than 1.7, in which case
2548 /// it maps to the [`getSignaturesForAddress2`] RPC method.
2549 ///
2550 /// [`getSignaturesForAddress`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturesforaddress
2551 /// [`getSignaturesForAddress2`]: https://docs.solana.com/developing/clients/jsonrpc-api#getsignaturesforaddress2
2552 ///
2553 /// # Examples
2554 ///
2555 /// ```
2556 /// # use safecoin_client::{
2557 /// # client_error::ClientError,
2558 /// # rpc_client::RpcClient,
2559 /// # rpc_client::GetConfirmedSignaturesForAddress2Config,
2560 /// # };
2561 /// # use solana_sdk::{
2562 /// # signature::Signer,
2563 /// # signer::keypair::Keypair,
2564 /// # system_transaction,
2565 /// # commitment_config::CommitmentConfig,
2566 /// # };
2567 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2568 /// # let alice = Keypair::new();
2569 /// # let bob = Keypair::new();
2570 /// # let lamports = 50;
2571 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
2572 /// # let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
2573 /// # let signature = rpc_client.send_and_confirm_transaction(&tx)?;
2574 /// let config = GetConfirmedSignaturesForAddress2Config {
2575 /// before: None,
2576 /// until: None,
2577 /// limit: Some(3),
2578 /// commitment: Some(CommitmentConfig::confirmed()),
2579 /// };
2580 /// let signatures = rpc_client.get_signatures_for_address_with_config(
2581 /// &alice.pubkey(),
2582 /// config,
2583 /// )?;
2584 /// # Ok::<(), ClientError>(())
2585 /// ```
2586 pub fn get_signatures_for_address_with_config(
2587 &self,
2588 address: &Pubkey,
2589 config: GetConfirmedSignaturesForAddress2Config,
2590 ) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
2591 self.invoke(
2592 self.rpc_client
2593 .get_signatures_for_address_with_config(address, config),
2594 )
2595 }
2596
2597 #[deprecated(
2598 since = "1.7.0",
2599 note = "Please use RpcClient::get_signatures_for_address() instead"
2600 )]
2601 #[allow(deprecated)]
2602 pub fn get_confirmed_signatures_for_address2(
2603 &self,
2604 address: &Pubkey,
2605 ) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
2606 self.invoke(
2607 self.rpc_client
2608 .get_confirmed_signatures_for_address2(address),
2609 )
2610 }
2611
2612 #[deprecated(
2613 since = "1.7.0",
2614 note = "Please use RpcClient::get_signatures_for_address_with_config() instead"
2615 )]
2616 #[allow(deprecated)]
2617 pub fn get_confirmed_signatures_for_address2_with_config(
2618 &self,
2619 address: &Pubkey,
2620 config: GetConfirmedSignaturesForAddress2Config,
2621 ) -> ClientResult<Vec<RpcConfirmedTransactionStatusWithSignature>> {
2622 self.invoke(
2623 self.rpc_client
2624 .get_confirmed_signatures_for_address2_with_config(address, config),
2625 )
2626 }
2627
2628 /// Returns transaction details for a confirmed transaction.
2629 ///
2630 /// This method uses the [`Finalized`] [commitment level][cl].
2631 ///
2632 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
2633 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2634 ///
2635 /// # RPC Reference
2636 ///
2637 /// This method corresponds directly to the [`getTransaction`] RPC method,
2638 /// unless the remote node version is less than 1.7, in which case it maps
2639 /// to the [`getConfirmedTransaction`] RPC method.
2640 ///
2641 /// [`getTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#gettransaction
2642 /// [`getConfirmedTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#getconfirmedtransaction
2643 ///
2644 /// # Examples
2645 ///
2646 /// ```
2647 /// # use safecoin_client::{
2648 /// # client_error::ClientError,
2649 /// # rpc_client::RpcClient,
2650 /// # };
2651 /// # use solana_sdk::{
2652 /// # signature::Signer,
2653 /// # signature::Signature,
2654 /// # signer::keypair::Keypair,
2655 /// # system_transaction,
2656 /// # };
2657 /// # use safecoin_transaction_status::UiTransactionEncoding;
2658 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2659 /// # let alice = Keypair::new();
2660 /// # let bob = Keypair::new();
2661 /// # let lamports = 50;
2662 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
2663 /// # let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
2664 /// let signature = rpc_client.send_and_confirm_transaction(&tx)?;
2665 /// let transaction = rpc_client.get_transaction(
2666 /// &signature,
2667 /// UiTransactionEncoding::Json,
2668 /// )?;
2669 /// # Ok::<(), ClientError>(())
2670 /// ```
2671 pub fn get_transaction(
2672 &self,
2673 signature: &Signature,
2674 encoding: UiTransactionEncoding,
2675 ) -> ClientResult<EncodedConfirmedTransactionWithStatusMeta> {
2676 self.invoke(self.rpc_client.get_transaction(signature, encoding))
2677 }
2678
2679 /// Returns transaction details for a confirmed transaction.
2680 ///
2681 /// # Errors
2682 ///
2683 /// This method returns an error if the given [commitment level][cl] is below
2684 /// [`Confirmed`].
2685 ///
2686 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2687 /// [`Confirmed`]: solana_sdk::commitment_config::CommitmentLevel::Confirmed
2688 ///
2689 /// # RPC Reference
2690 ///
2691 /// This method corresponds directly to the [`getTransaction`] RPC method,
2692 /// unless the remote node version is less than 1.7, in which case it maps
2693 /// to the [`getConfirmedTransaction`] RPC method.
2694 ///
2695 /// [`getTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#gettransaction
2696 /// [`getConfirmedTransaction`]: https://docs.solana.com/developing/clients/jsonrpc-api#getconfirmedtransaction
2697 ///
2698 /// # Examples
2699 ///
2700 /// ```
2701 /// # use safecoin_client::{
2702 /// # client_error::ClientError,
2703 /// # rpc_client::RpcClient,
2704 /// # rpc_config::RpcTransactionConfig,
2705 /// # };
2706 /// # use solana_sdk::{
2707 /// # signature::Signer,
2708 /// # signature::Signature,
2709 /// # signer::keypair::Keypair,
2710 /// # system_transaction,
2711 /// # commitment_config::CommitmentConfig,
2712 /// # };
2713 /// # use safecoin_transaction_status::UiTransactionEncoding;
2714 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2715 /// # let alice = Keypair::new();
2716 /// # let bob = Keypair::new();
2717 /// # let lamports = 50;
2718 /// # let latest_blockhash = rpc_client.get_latest_blockhash()?;
2719 /// # let tx = system_transaction::transfer(&alice, &bob.pubkey(), lamports, latest_blockhash);
2720 /// let signature = rpc_client.send_and_confirm_transaction(&tx)?;
2721 /// let config = RpcTransactionConfig {
2722 /// encoding: Some(UiTransactionEncoding::Json),
2723 /// commitment: Some(CommitmentConfig::confirmed()),
2724 /// max_supported_transaction_version: Some(0),
2725 /// };
2726 /// let transaction = rpc_client.get_transaction_with_config(
2727 /// &signature,
2728 /// config,
2729 /// )?;
2730 /// # Ok::<(), ClientError>(())
2731 /// ```
2732 pub fn get_transaction_with_config(
2733 &self,
2734 signature: &Signature,
2735 config: RpcTransactionConfig,
2736 ) -> ClientResult<EncodedConfirmedTransactionWithStatusMeta> {
2737 self.invoke(
2738 self.rpc_client
2739 .get_transaction_with_config(signature, config),
2740 )
2741 }
2742
2743 #[deprecated(
2744 since = "1.7.0",
2745 note = "Please use RpcClient::get_transaction() instead"
2746 )]
2747 #[allow(deprecated)]
2748 pub fn get_confirmed_transaction(
2749 &self,
2750 signature: &Signature,
2751 encoding: UiTransactionEncoding,
2752 ) -> ClientResult<EncodedConfirmedTransactionWithStatusMeta> {
2753 self.invoke(
2754 self.rpc_client
2755 .get_confirmed_transaction(signature, encoding),
2756 )
2757 }
2758
2759 #[deprecated(
2760 since = "1.7.0",
2761 note = "Please use RpcClient::get_transaction_with_config() instead"
2762 )]
2763 #[allow(deprecated)]
2764 pub fn get_confirmed_transaction_with_config(
2765 &self,
2766 signature: &Signature,
2767 config: RpcConfirmedTransactionConfig,
2768 ) -> ClientResult<EncodedConfirmedTransactionWithStatusMeta> {
2769 self.invoke(
2770 self.rpc_client
2771 .get_confirmed_transaction_with_config(signature, config),
2772 )
2773 }
2774
2775 /// Returns the estimated production time of a block.
2776 ///
2777 /// # RPC Reference
2778 ///
2779 /// This method corresponds directly to the [`getBlockTime`] RPC method.
2780 ///
2781 /// [`getBlockTime`]: https://docs.solana.com/developing/clients/jsonrpc-api#getblocktime
2782 ///
2783 /// # Examples
2784 ///
2785 /// ```
2786 /// # use safecoin_client::{
2787 /// # client_error::ClientError,
2788 /// # rpc_client::RpcClient,
2789 /// # };
2790 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2791 /// // Get the time of the most recent finalized block
2792 /// let slot = rpc_client.get_slot()?;
2793 /// let block_time = rpc_client.get_block_time(slot)?;
2794 /// # Ok::<(), ClientError>(())
2795 /// ```
2796 pub fn get_block_time(&self, slot: Slot) -> ClientResult<UnixTimestamp> {
2797 self.invoke(self.rpc_client.get_block_time(slot))
2798 }
2799
2800 /// Returns information about the current epoch.
2801 ///
2802 /// This method uses the configured default [commitment level][cl].
2803 ///
2804 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2805 ///
2806 /// # RPC Reference
2807 ///
2808 /// This method corresponds directly to the [`getEpochInfo`] RPC method.
2809 ///
2810 /// [`getEpochInfo`]: https://docs.solana.com/developing/clients/jsonrpc-api#getepochinfo
2811 ///
2812 /// # Examples
2813 ///
2814 /// ```
2815 /// # use safecoin_client::{
2816 /// # client_error::ClientError,
2817 /// # rpc_client::RpcClient,
2818 /// # };
2819 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2820 /// let epoch_info = rpc_client.get_epoch_info()?;
2821 /// # Ok::<(), ClientError>(())
2822 /// ```
2823 pub fn get_epoch_info(&self) -> ClientResult<EpochInfo> {
2824 self.invoke(self.rpc_client.get_epoch_info())
2825 }
2826
2827 /// Returns information about the current epoch.
2828 ///
2829 /// # RPC Reference
2830 ///
2831 /// This method corresponds directly to the [`getEpochInfo`] RPC method.
2832 ///
2833 /// [`getEpochInfo`]: https://docs.solana.com/developing/clients/jsonrpc-api#getepochinfo
2834 ///
2835 /// # Examples
2836 ///
2837 /// ```
2838 /// # use safecoin_client::{
2839 /// # client_error::ClientError,
2840 /// # rpc_client::RpcClient,
2841 /// # };
2842 /// # use solana_sdk::commitment_config::CommitmentConfig;
2843 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2844 /// let commitment_config = CommitmentConfig::confirmed();
2845 /// let epoch_info = rpc_client.get_epoch_info_with_commitment(
2846 /// commitment_config,
2847 /// )?;
2848 /// # Ok::<(), ClientError>(())
2849 /// ```
2850 pub fn get_epoch_info_with_commitment(
2851 &self,
2852 commitment_config: CommitmentConfig,
2853 ) -> ClientResult<EpochInfo> {
2854 self.invoke(
2855 self.rpc_client
2856 .get_epoch_info_with_commitment(commitment_config),
2857 )
2858 }
2859
2860 /// Returns the leader schedule for an epoch.
2861 ///
2862 /// This method uses the configured default [commitment level][cl].
2863 ///
2864 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
2865 ///
2866 /// # RPC Reference
2867 ///
2868 /// This method corresponds directly to the [`getLeaderSchedule`] RPC method.
2869 ///
2870 /// [`getLeaderSchedule`]: https://docs.solana.com/developing/clients/jsonrpc-api#getleaderschedule
2871 ///
2872 /// # Examples
2873 ///
2874 /// ```
2875 /// # use safecoin_client::{
2876 /// # client_error::ClientError,
2877 /// # rpc_client::RpcClient,
2878 /// # };
2879 /// # use solana_sdk::commitment_config::CommitmentConfig;
2880 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2881 /// # let slot = rpc_client.get_slot()?;
2882 /// let leader_schedule = rpc_client.get_leader_schedule(
2883 /// Some(slot),
2884 /// )?;
2885 /// # Ok::<(), ClientError>(())
2886 /// ```
2887 pub fn get_leader_schedule(
2888 &self,
2889 slot: Option<Slot>,
2890 ) -> ClientResult<Option<RpcLeaderSchedule>> {
2891 self.invoke(self.rpc_client.get_leader_schedule(slot))
2892 }
2893
2894 /// Returns the leader schedule for an epoch.
2895 ///
2896 /// # RPC Reference
2897 ///
2898 /// This method corresponds directly to the [`getLeaderSchedule`] RPC method.
2899 ///
2900 /// [`getLeaderSchedule`]: https://docs.solana.com/developing/clients/jsonrpc-api#getleaderschedule
2901 ///
2902 /// # Examples
2903 ///
2904 /// ```
2905 /// # use safecoin_client::{
2906 /// # client_error::ClientError,
2907 /// # rpc_client::RpcClient,
2908 /// # };
2909 /// # use solana_sdk::commitment_config::CommitmentConfig;
2910 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2911 /// # let slot = rpc_client.get_slot()?;
2912 /// let commitment_config = CommitmentConfig::processed();
2913 /// let leader_schedule = rpc_client.get_leader_schedule_with_commitment(
2914 /// Some(slot),
2915 /// commitment_config,
2916 /// )?;
2917 /// # Ok::<(), ClientError>(())
2918 /// ```
2919 pub fn get_leader_schedule_with_commitment(
2920 &self,
2921 slot: Option<Slot>,
2922 commitment_config: CommitmentConfig,
2923 ) -> ClientResult<Option<RpcLeaderSchedule>> {
2924 self.invoke(
2925 self.rpc_client
2926 .get_leader_schedule_with_commitment(slot, commitment_config),
2927 )
2928 }
2929
2930 /// Returns the leader schedule for an epoch.
2931 ///
2932 /// # RPC Reference
2933 ///
2934 /// This method corresponds directly to the [`getLeaderSchedule`] RPC method.
2935 ///
2936 /// [`getLeaderSchedule`]: https://docs.solana.com/developing/clients/jsonrpc-api#getleaderschedule
2937 ///
2938 /// # Examples
2939 ///
2940 /// ```
2941 /// # use safecoin_client::{
2942 /// # client_error::ClientError,
2943 /// # rpc_client::RpcClient,
2944 /// # };
2945 /// # use safecoin_client::rpc_config::RpcLeaderScheduleConfig;
2946 /// # use solana_sdk::commitment_config::CommitmentConfig;
2947 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2948 /// # let slot = rpc_client.get_slot()?;
2949 /// # let validator_pubkey_str = "7AYmEYBBetok8h5L3Eo3vi3bDWnjNnaFbSXfSNYV5ewB".to_string();
2950 /// let config = RpcLeaderScheduleConfig {
2951 /// identity: Some(validator_pubkey_str),
2952 /// commitment: Some(CommitmentConfig::processed()),
2953 /// };
2954 /// let leader_schedule = rpc_client.get_leader_schedule_with_config(
2955 /// Some(slot),
2956 /// config,
2957 /// )?;
2958 /// # Ok::<(), ClientError>(())
2959 /// ```
2960 pub fn get_leader_schedule_with_config(
2961 &self,
2962 slot: Option<Slot>,
2963 config: RpcLeaderScheduleConfig,
2964 ) -> ClientResult<Option<RpcLeaderSchedule>> {
2965 self.invoke(
2966 self.rpc_client
2967 .get_leader_schedule_with_config(slot, config),
2968 )
2969 }
2970
2971 /// Returns epoch schedule information from this cluster's genesis config.
2972 ///
2973 /// # RPC Reference
2974 ///
2975 /// This method corresponds directly to the [`getEpochSchedule`] RPC method.
2976 ///
2977 /// [`getEpochSchedule`]: https://docs.solana.com/developing/clients/jsonrpc-api#getepochschedule
2978 ///
2979 /// # Examples
2980 ///
2981 /// ```
2982 /// # use safecoin_client::{
2983 /// # client_error::ClientError,
2984 /// # rpc_client::RpcClient,
2985 /// # };
2986 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
2987 /// let epoch_schedule = rpc_client.get_epoch_schedule()?;
2988 /// # Ok::<(), ClientError>(())
2989 /// ```
2990 pub fn get_epoch_schedule(&self) -> ClientResult<EpochSchedule> {
2991 self.invoke(self.rpc_client.get_epoch_schedule())
2992 }
2993
2994 /// Returns a list of recent performance samples, in reverse slot order.
2995 ///
2996 /// Performance samples are taken every 60 seconds and include the number of
2997 /// transactions and slots that occur in a given time window.
2998 ///
2999 /// # RPC Reference
3000 ///
3001 /// This method corresponds directly to the [`getRecentPerformanceSamples`] RPC method.
3002 ///
3003 /// [`getRecentPerformanceSamples`]: https://docs.solana.com/developing/clients/jsonrpc-api#getrecentperformancesamples
3004 ///
3005 /// # Examples
3006 ///
3007 /// ```
3008 /// # use safecoin_client::{
3009 /// # client_error::ClientError,
3010 /// # rpc_client::RpcClient,
3011 /// # };
3012 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3013 /// let limit = 10;
3014 /// let performance_samples = rpc_client.get_recent_performance_samples(
3015 /// Some(limit),
3016 /// )?;
3017 /// # Ok::<(), ClientError>(())
3018 /// ```
3019 pub fn get_recent_performance_samples(
3020 &self,
3021 limit: Option<usize>,
3022 ) -> ClientResult<Vec<RpcPerfSample>> {
3023 self.invoke(self.rpc_client.get_recent_performance_samples(limit))
3024 }
3025
3026 /// Returns a list of minimum prioritization fees from recent blocks.
3027 /// Takes an optional vector of addresses; if any addresses are provided, the response will
3028 /// reflect the minimum prioritization fee to land a transaction locking all of the provided
3029 /// accounts as writable.
3030 ///
3031 /// Currently, a node's prioritization-fee cache stores data from up to 150 blocks.
3032 ///
3033 /// # RPC Reference
3034 ///
3035 /// This method corresponds directly to the [`getRecentPrioritizationFees`] RPC method.
3036 ///
3037 /// [`getRecentPrioritizationFees`]: https://docs.solana.com/developing/clients/jsonrpc-api#getrecentprioritizationfees
3038 ///
3039 /// # Examples
3040 ///
3041 /// ```
3042 /// # use safecoin_client::{
3043 /// # client_error::ClientError,
3044 /// # rpc_client::RpcClient,
3045 /// # };
3046 /// # use solana_sdk::signature::{Keypair, Signer};
3047 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3048 /// # let alice = Keypair::new();
3049 /// # let bob = Keypair::new();
3050 /// let addresses = vec![alice.pubkey(), bob.pubkey()];
3051 /// let prioritization_fees = rpc_client.get_recent_prioritization_fees(
3052 /// &addresses,
3053 /// )?;
3054 /// # Ok::<(), ClientError>(())
3055 /// ```
3056 pub fn get_recent_prioritization_fees(
3057 &self,
3058 addresses: &[Pubkey],
3059 ) -> ClientResult<Vec<RpcPrioritizationFee>> {
3060 self.invoke(self.rpc_client.get_recent_prioritization_fees(addresses))
3061 }
3062
3063 /// Returns the identity pubkey for the current node.
3064 ///
3065 /// # RPC Reference
3066 ///
3067 /// This method corresponds directly to the [`getIdentity`] RPC method.
3068 ///
3069 /// [`getIdentity`]: https://docs.solana.com/developing/clients/jsonrpc-api#getidentity
3070 ///
3071 /// # Examples
3072 ///
3073 /// ```
3074 /// # use safecoin_client::{
3075 /// # client_error::ClientError,
3076 /// # rpc_client::RpcClient,
3077 /// # };
3078 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3079 /// let identity = rpc_client.get_identity()?;
3080 /// # Ok::<(), ClientError>(())
3081 /// ```
3082 pub fn get_identity(&self) -> ClientResult<Pubkey> {
3083 self.invoke(self.rpc_client.get_identity())
3084 }
3085
3086 /// Returns the current inflation governor.
3087 ///
3088 /// This method uses the [`Finalized`] [commitment level][cl].
3089 ///
3090 /// [`Finalized`]: solana_sdk::commitment_config::CommitmentLevel::Finalized
3091 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
3092 ///
3093 /// # RPC Reference
3094 ///
3095 /// This method corresponds directly to the [`getInflationGovernor`] RPC
3096 /// method.
3097 ///
3098 /// [`getInflationGovernor`]: https://docs.solana.com/developing/clients/jsonrpc-api#getinflationgovernor
3099 ///
3100 /// # Examples
3101 ///
3102 /// ```
3103 /// # use safecoin_client::{
3104 /// # client_error::ClientError,
3105 /// # rpc_client::RpcClient,
3106 /// # };
3107 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3108 /// let inflation_governor = rpc_client.get_inflation_governor()?;
3109 /// # Ok::<(), ClientError>(())
3110 /// ```
3111 pub fn get_inflation_governor(&self) -> ClientResult<RpcInflationGovernor> {
3112 self.invoke(self.rpc_client.get_inflation_governor())
3113 }
3114
3115 /// Returns the specific inflation values for the current epoch.
3116 ///
3117 /// # RPC Reference
3118 ///
3119 /// This method corresponds directly to the [`getInflationRate`] RPC method.
3120 ///
3121 /// [`getInflationRate`]: https://docs.solana.com/developing/clients/jsonrpc-api#getinflationrate
3122 ///
3123 /// # Examples
3124 ///
3125 /// ```
3126 /// # use safecoin_client::{
3127 /// # client_error::ClientError,
3128 /// # rpc_client::RpcClient,
3129 /// # };
3130 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3131 /// let inflation_rate = rpc_client.get_inflation_rate()?;
3132 /// # Ok::<(), ClientError>(())
3133 /// ```
3134 pub fn get_inflation_rate(&self) -> ClientResult<RpcInflationRate> {
3135 self.invoke(self.rpc_client.get_inflation_rate())
3136 }
3137
3138 /// Returns the inflation reward for a list of addresses for an epoch.
3139 ///
3140 /// This method uses the configured [commitment level][cl].
3141 ///
3142 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
3143 ///
3144 /// # RPC Reference
3145 ///
3146 /// This method corresponds directly to the [`getInflationReward`] RPC method.
3147 ///
3148 /// [`getInflationReward`]: https://docs.solana.com/developing/clients/jsonrpc-api#getinflationreward
3149 ///
3150 /// # Examples
3151 ///
3152 /// ```
3153 /// # use safecoin_client::{
3154 /// # client_error::ClientError,
3155 /// # rpc_client::RpcClient,
3156 /// # };
3157 /// # use solana_sdk::signature::{Keypair, Signer};
3158 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3159 /// # let epoch_info = rpc_client.get_epoch_info()?;
3160 /// # let epoch = epoch_info.epoch;
3161 /// # let alice = Keypair::new();
3162 /// # let bob = Keypair::new();
3163 /// let addresses = vec![alice.pubkey(), bob.pubkey()];
3164 /// let inflation_reward = rpc_client.get_inflation_reward(
3165 /// &addresses,
3166 /// Some(epoch),
3167 /// )?;
3168 /// # Ok::<(), ClientError>(())
3169 /// ```
3170 pub fn get_inflation_reward(
3171 &self,
3172 addresses: &[Pubkey],
3173 epoch: Option<Epoch>,
3174 ) -> ClientResult<Vec<Option<RpcInflationReward>>> {
3175 self.invoke(self.rpc_client.get_inflation_reward(addresses, epoch))
3176 }
3177
3178 /// Returns the current safecoin version running on the node.
3179 ///
3180 /// # RPC Reference
3181 ///
3182 /// This method corresponds directly to the [`getVersion`] RPC method.
3183 ///
3184 /// [`getVersion`]: https://docs.solana.com/developing/clients/jsonrpc-api#getversion
3185 ///
3186 /// # Examples
3187 ///
3188 /// ```
3189 /// # use safecoin_client::{
3190 /// # client_error::ClientError,
3191 /// # rpc_client::RpcClient,
3192 /// # };
3193 /// # use solana_sdk::signature::{Keypair, Signer};
3194 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3195 /// let expected_version = semver::Version::new(1, 7, 0);
3196 /// let version = rpc_client.get_version()?;
3197 /// let version = semver::Version::parse(&version.solana_core)?;
3198 /// assert!(version >= expected_version);
3199 /// # Ok::<(), Box<dyn std::error::Error>>(())
3200 /// ```
3201 pub fn get_version(&self) -> ClientResult<RpcVersionInfo> {
3202 self.invoke(self.rpc_client.get_version())
3203 }
3204
3205 /// Returns the lowest slot that the node has information about in its ledger.
3206 ///
3207 /// This value may increase over time if the node is configured to purge
3208 /// older ledger data.
3209 ///
3210 /// # RPC Reference
3211 ///
3212 /// This method corresponds directly to the [`minimumLedgerSlot`] RPC
3213 /// method.
3214 ///
3215 /// [`minimumLedgerSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#minimumledgerslot
3216 ///
3217 /// # Examples
3218 ///
3219 /// ```
3220 /// # use safecoin_client::{
3221 /// # client_error::ClientError,
3222 /// # rpc_client::RpcClient,
3223 /// # };
3224 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3225 /// let slot = rpc_client.minimum_ledger_slot()?;
3226 /// # Ok::<(), ClientError>(())
3227 /// ```
3228 pub fn minimum_ledger_slot(&self) -> ClientResult<Slot> {
3229 self.invoke(self.rpc_client.minimum_ledger_slot())
3230 }
3231
3232 /// Returns all information associated with the account of the provided pubkey.
3233 ///
3234 /// This method uses the configured [commitment level][cl].
3235 ///
3236 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
3237 ///
3238 /// To get multiple accounts at once, use the [`get_multiple_accounts`] method.
3239 ///
3240 /// [`get_multiple_accounts`]: RpcClient::get_multiple_accounts
3241 ///
3242 /// # Errors
3243 ///
3244 /// If the account does not exist, this method returns
3245 /// [`RpcError::ForUser`]. This is unlike [`get_account_with_commitment`],
3246 /// which returns `Ok(None)` if the account does not exist.
3247 ///
3248 /// [`RpcError::ForUser`]: crate::rpc_request::RpcError::ForUser
3249 /// [`get_account_with_commitment`]: RpcClient::get_account_with_commitment
3250 ///
3251 /// # RPC Reference
3252 ///
3253 /// This method is built on the [`getAccountInfo`] RPC method.
3254 ///
3255 /// [`getAccountInfo`]: https://docs.solana.com/developing/clients/jsonrpc-api#getaccountinfo
3256 ///
3257 /// # Examples
3258 ///
3259 /// ```
3260 /// # use safecoin_client::{
3261 /// # rpc_client::{self, RpcClient},
3262 /// # client_error::ClientError,
3263 /// # };
3264 /// # use solana_sdk::{
3265 /// # signature::Signer,
3266 /// # signer::keypair::Keypair,
3267 /// # pubkey::Pubkey,
3268 /// # };
3269 /// # use std::str::FromStr;
3270 /// # let mocks = rpc_client::create_rpc_client_mocks();
3271 /// # let rpc_client = RpcClient::new_mock_with_mocks("succeeds".to_string(), mocks);
3272 /// let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
3273 /// let account = rpc_client.get_account(&alice_pubkey)?;
3274 /// # Ok::<(), ClientError>(())
3275 /// ```
3276 pub fn get_account(&self, pubkey: &Pubkey) -> ClientResult<Account> {
3277 self.invoke(self.rpc_client.get_account(pubkey))
3278 }
3279
3280 /// Returns all information associated with the account of the provided pubkey.
3281 ///
3282 /// If the account does not exist, this method returns `Ok(None)`.
3283 ///
3284 /// To get multiple accounts at once, use the [`get_multiple_accounts_with_commitment`] method.
3285 ///
3286 /// [`get_multiple_accounts_with_commitment`]: RpcClient::get_multiple_accounts_with_commitment
3287 ///
3288 /// # RPC Reference
3289 ///
3290 /// This method is built on the [`getAccountInfo`] RPC method.
3291 ///
3292 /// [`getAccountInfo`]: https://docs.solana.com/developing/clients/jsonrpc-api#getaccountinfo
3293 ///
3294 /// # Examples
3295 ///
3296 /// ```
3297 /// # use safecoin_client::{
3298 /// # rpc_client::{self, RpcClient},
3299 /// # client_error::ClientError,
3300 /// # };
3301 /// # use solana_sdk::{
3302 /// # signature::Signer,
3303 /// # signer::keypair::Keypair,
3304 /// # pubkey::Pubkey,
3305 /// # commitment_config::CommitmentConfig,
3306 /// # };
3307 /// # use std::str::FromStr;
3308 /// # let mocks = rpc_client::create_rpc_client_mocks();
3309 /// # let rpc_client = RpcClient::new_mock_with_mocks("succeeds".to_string(), mocks);
3310 /// let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
3311 /// let commitment_config = CommitmentConfig::processed();
3312 /// let account = rpc_client.get_account_with_commitment(
3313 /// &alice_pubkey,
3314 /// commitment_config,
3315 /// )?;
3316 /// assert!(account.value.is_some());
3317 /// # Ok::<(), ClientError>(())
3318 /// ```
3319 pub fn get_account_with_commitment(
3320 &self,
3321 pubkey: &Pubkey,
3322 commitment_config: CommitmentConfig,
3323 ) -> RpcResult<Option<Account>> {
3324 self.invoke(
3325 self.rpc_client
3326 .get_account_with_commitment(pubkey, commitment_config),
3327 )
3328 }
3329
3330 /// Returns all information associated with the account of the provided pubkey.
3331 ///
3332 /// If the account does not exist, this method returns `Ok(None)`.
3333 ///
3334 /// To get multiple accounts at once, use the [`get_multiple_accounts_with_config`] method.
3335 ///
3336 /// [`get_multiple_accounts_with_config`]: RpcClient::get_multiple_accounts_with_config
3337 ///
3338 /// # RPC Reference
3339 ///
3340 /// This method is built on the [`getAccountInfo`] RPC method.
3341 ///
3342 /// [`getAccountInfo`]: https://docs.solana.com/developing/clients/jsonrpc-api#getaccountinfo
3343 ///
3344 /// # Examples
3345 ///
3346 /// ```
3347 /// # use safecoin_client::{
3348 /// # rpc_client::{self, RpcClient},
3349 /// # rpc_config::RpcAccountInfoConfig,
3350 /// # client_error::ClientError,
3351 /// # };
3352 /// # use solana_sdk::{
3353 /// # signature::Signer,
3354 /// # signer::keypair::Keypair,
3355 /// # pubkey::Pubkey,
3356 /// # commitment_config::CommitmentConfig,
3357 /// # };
3358 /// # use safecoin_account_decoder::UiAccountEncoding;
3359 /// # use std::str::FromStr;
3360 /// # let mocks = rpc_client::create_rpc_client_mocks();
3361 /// # let rpc_client = RpcClient::new_mock_with_mocks("succeeds".to_string(), mocks);
3362 /// let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
3363 /// let commitment_config = CommitmentConfig::processed();
3364 /// let config = RpcAccountInfoConfig {
3365 /// encoding: Some(UiAccountEncoding::Base64),
3366 /// commitment: Some(commitment_config),
3367 /// .. RpcAccountInfoConfig::default()
3368 /// };
3369 /// let account = rpc_client.get_account_with_config(
3370 /// &alice_pubkey,
3371 /// config,
3372 /// )?;
3373 /// assert!(account.value.is_some());
3374 /// # Ok::<(), ClientError>(())
3375 /// ```
3376 pub fn get_account_with_config(
3377 &self,
3378 pubkey: &Pubkey,
3379 config: RpcAccountInfoConfig,
3380 ) -> RpcResult<Option<Account>> {
3381 self.invoke(self.rpc_client.get_account_with_config(pubkey, config))
3382 }
3383
3384 /// Get the max slot seen from retransmit stage.
3385 ///
3386 /// # RPC Reference
3387 ///
3388 /// This method corresponds directly to the [`getMaxRetransmitSlot`] RPC
3389 /// method.
3390 ///
3391 /// [`getMaxRetransmitSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#getmaxretransmitslot
3392 ///
3393 /// # Examples
3394 ///
3395 /// ```
3396 /// # use safecoin_client::{
3397 /// # rpc_client::RpcClient,
3398 /// # client_error::ClientError,
3399 /// # };
3400 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3401 /// let slot = rpc_client.get_max_retransmit_slot()?;
3402 /// # Ok::<(), ClientError>(())
3403 pub fn get_max_retransmit_slot(&self) -> ClientResult<Slot> {
3404 self.invoke(self.rpc_client.get_max_retransmit_slot())
3405 }
3406
3407 /// Get the max slot seen from after [shred](https://docs.solana.com/terminology#shred) insert.
3408 ///
3409 /// # RPC Reference
3410 ///
3411 /// This method corresponds directly to the
3412 /// [`getMaxShredInsertSlot`] RPC method.
3413 ///
3414 /// [`getMaxShredInsertSlot`]: https://docs.solana.com/developing/clients/jsonrpc-api#getmaxshredinsertslot
3415 ///
3416 /// # Examples
3417 ///
3418 /// ```
3419 /// # use safecoin_client::{
3420 /// # rpc_client::RpcClient,
3421 /// # client_error::ClientError,
3422 /// # };
3423 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3424 /// let slot = rpc_client.get_max_shred_insert_slot()?;
3425 /// # Ok::<(), ClientError>(())
3426 pub fn get_max_shred_insert_slot(&self) -> ClientResult<Slot> {
3427 self.invoke(self.rpc_client.get_max_shred_insert_slot())
3428 }
3429
3430 /// Returns the account information for a list of pubkeys.
3431 ///
3432 /// This method uses the configured [commitment level][cl].
3433 ///
3434 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
3435 ///
3436 /// # RPC Reference
3437 ///
3438 /// This method is built on the [`getMultipleAccounts`] RPC method.
3439 ///
3440 /// [`getMultipleAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getmultipleaccounts
3441 ///
3442 /// # Examples
3443 ///
3444 /// ```
3445 /// # use safecoin_client::{
3446 /// # rpc_client::RpcClient,
3447 /// # client_error::ClientError,
3448 /// # };
3449 /// # use solana_sdk::{
3450 /// # signature::Signer,
3451 /// # signer::keypair::Keypair,
3452 /// # };
3453 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3454 /// # let alice = Keypair::new();
3455 /// # let bob = Keypair::new();
3456 /// let pubkeys = vec![alice.pubkey(), bob.pubkey()];
3457 /// let accounts = rpc_client.get_multiple_accounts(&pubkeys)?;
3458 /// # Ok::<(), ClientError>(())
3459 /// ```
3460 pub fn get_multiple_accounts(&self, pubkeys: &[Pubkey]) -> ClientResult<Vec<Option<Account>>> {
3461 self.invoke(self.rpc_client.get_multiple_accounts(pubkeys))
3462 }
3463
3464 /// Returns the account information for a list of pubkeys.
3465 ///
3466 /// # RPC Reference
3467 ///
3468 /// This method is built on the [`getMultipleAccounts`] RPC method.
3469 ///
3470 /// [`getMultipleAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getmultipleaccounts
3471 ///
3472 /// # Examples
3473 ///
3474 /// ```
3475 /// # use safecoin_client::{
3476 /// # rpc_client::RpcClient,
3477 /// # client_error::ClientError,
3478 /// # };
3479 /// # use solana_sdk::{
3480 /// # signature::Signer,
3481 /// # signer::keypair::Keypair,
3482 /// # commitment_config::CommitmentConfig,
3483 /// # };
3484 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3485 /// # let alice = Keypair::new();
3486 /// # let bob = Keypair::new();
3487 /// let pubkeys = vec![alice.pubkey(), bob.pubkey()];
3488 /// let commitment_config = CommitmentConfig::processed();
3489 /// let accounts = rpc_client.get_multiple_accounts_with_commitment(
3490 /// &pubkeys,
3491 /// commitment_config,
3492 /// )?;
3493 /// # Ok::<(), ClientError>(())
3494 /// ```
3495 pub fn get_multiple_accounts_with_commitment(
3496 &self,
3497 pubkeys: &[Pubkey],
3498 commitment_config: CommitmentConfig,
3499 ) -> RpcResult<Vec<Option<Account>>> {
3500 self.invoke(
3501 self.rpc_client
3502 .get_multiple_accounts_with_commitment(pubkeys, commitment_config),
3503 )
3504 }
3505
3506 /// Returns the account information for a list of pubkeys.
3507 ///
3508 /// # RPC Reference
3509 ///
3510 /// This method is built on the [`getMultipleAccounts`] RPC method.
3511 ///
3512 /// [`getMultipleAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getmultipleaccounts
3513 ///
3514 /// # Examples
3515 ///
3516 /// ```
3517 /// # use safecoin_client::{
3518 /// # rpc_client::RpcClient,
3519 /// # rpc_config::RpcAccountInfoConfig,
3520 /// # client_error::ClientError,
3521 /// # };
3522 /// # use solana_sdk::{
3523 /// # signature::Signer,
3524 /// # signer::keypair::Keypair,
3525 /// # commitment_config::CommitmentConfig,
3526 /// # };
3527 /// # use safecoin_account_decoder::UiAccountEncoding;
3528 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3529 /// # let alice = Keypair::new();
3530 /// # let bob = Keypair::new();
3531 /// let pubkeys = vec![alice.pubkey(), bob.pubkey()];
3532 /// let commitment_config = CommitmentConfig::processed();
3533 /// let config = RpcAccountInfoConfig {
3534 /// encoding: Some(UiAccountEncoding::Base64),
3535 /// commitment: Some(commitment_config),
3536 /// .. RpcAccountInfoConfig::default()
3537 /// };
3538 /// let accounts = rpc_client.get_multiple_accounts_with_config(
3539 /// &pubkeys,
3540 /// config,
3541 /// )?;
3542 /// # Ok::<(), ClientError>(())
3543 /// ```
3544 pub fn get_multiple_accounts_with_config(
3545 &self,
3546 pubkeys: &[Pubkey],
3547 config: RpcAccountInfoConfig,
3548 ) -> RpcResult<Vec<Option<Account>>> {
3549 self.invoke(
3550 self.rpc_client
3551 .get_multiple_accounts_with_config(pubkeys, config),
3552 )
3553 }
3554
3555 /// Gets the raw data associated with an account.
3556 ///
3557 /// This is equivalent to calling [`get_account`] and then accessing the
3558 /// [`data`] field of the returned [`Account`].
3559 ///
3560 /// [`get_account`]: RpcClient::get_account
3561 /// [`data`]: Account::data
3562 ///
3563 /// # RPC Reference
3564 ///
3565 /// This method is built on the [`getAccountInfo`] RPC method.
3566 ///
3567 /// [`getAccountInfo`]: https://docs.solana.com/developing/clients/jsonrpc-api#getaccountinfo
3568 ///
3569 /// # Examples
3570 ///
3571 /// ```
3572 /// # use safecoin_client::{
3573 /// # rpc_client::{self, RpcClient},
3574 /// # client_error::ClientError,
3575 /// # };
3576 /// # use solana_sdk::{
3577 /// # signature::Signer,
3578 /// # signer::keypair::Keypair,
3579 /// # pubkey::Pubkey,
3580 /// # };
3581 /// # use std::str::FromStr;
3582 /// # let mocks = rpc_client::create_rpc_client_mocks();
3583 /// # let rpc_client = RpcClient::new_mock_with_mocks("succeeds".to_string(), mocks);
3584 /// let alice_pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
3585 /// let account_data = rpc_client.get_account_data(&alice_pubkey)?;
3586 /// # Ok::<(), ClientError>(())
3587 /// ```
3588 pub fn get_account_data(&self, pubkey: &Pubkey) -> ClientResult<Vec<u8>> {
3589 self.invoke(self.rpc_client.get_account_data(pubkey))
3590 }
3591
3592 /// Returns minimum balance required to make an account with specified data length rent exempt.
3593 ///
3594 /// # RPC Reference
3595 ///
3596 /// This method corresponds directly to the
3597 /// [`getMinimumBalanceForRentExemption`] RPC method.
3598 ///
3599 /// [`getMinimumBalanceForRentExemption`]: https://docs.solana.com/developing/clients/jsonrpc-api#getminimumbalanceforrentexemption
3600 ///
3601 /// # Examples
3602 ///
3603 /// ```
3604 /// # use safecoin_client::{
3605 /// # rpc_client::RpcClient,
3606 /// # client_error::ClientError,
3607 /// # };
3608 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3609 /// let data_len = 300;
3610 /// let balance = rpc_client.get_minimum_balance_for_rent_exemption(data_len)?;
3611 /// # Ok::<(), ClientError>(())
3612 /// ```
3613 pub fn get_minimum_balance_for_rent_exemption(&self, data_len: usize) -> ClientResult<u64> {
3614 self.invoke(
3615 self.rpc_client
3616 .get_minimum_balance_for_rent_exemption(data_len),
3617 )
3618 }
3619
3620 /// Request the balance of the provided account pubkey.
3621 ///
3622 /// This method uses the configured [commitment level][cl].
3623 ///
3624 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
3625 ///
3626 /// # RPC Reference
3627 ///
3628 /// This method corresponds directly to the [`getBalance`] RPC method.
3629 ///
3630 /// [`getBalance`]: https://docs.solana.com/developing/clients/jsonrpc-api#getbalance
3631 ///
3632 /// # Examples
3633 ///
3634 /// ```
3635 /// # use safecoin_client::{
3636 /// # rpc_client::RpcClient,
3637 /// # client_error::ClientError,
3638 /// # };
3639 /// # use solana_sdk::{
3640 /// # signature::Signer,
3641 /// # signer::keypair::Keypair,
3642 /// # };
3643 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3644 /// # let alice = Keypair::new();
3645 /// let balance = rpc_client.get_balance(&alice.pubkey())?;
3646 /// # Ok::<(), ClientError>(())
3647 /// ```
3648 pub fn get_balance(&self, pubkey: &Pubkey) -> ClientResult<u64> {
3649 self.invoke(self.rpc_client.get_balance(pubkey))
3650 }
3651
3652 /// Request the balance of the provided account pubkey.
3653 ///
3654 /// # RPC Reference
3655 ///
3656 /// This method corresponds directly to the [`getBalance`] RPC method.
3657 ///
3658 /// [`getBalance`]: https://docs.solana.com/developing/clients/jsonrpc-api#getbalance
3659 ///
3660 /// # Examples
3661 ///
3662 /// ```
3663 /// # use safecoin_client::{
3664 /// # rpc_client::RpcClient,
3665 /// # client_error::ClientError,
3666 /// # };
3667 /// # use solana_sdk::{
3668 /// # signature::Signer,
3669 /// # signer::keypair::Keypair,
3670 /// # commitment_config::CommitmentConfig,
3671 /// # };
3672 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3673 /// # let alice = Keypair::new();
3674 /// let commitment_config = CommitmentConfig::processed();
3675 /// let balance = rpc_client.get_balance_with_commitment(
3676 /// &alice.pubkey(),
3677 /// commitment_config,
3678 /// )?;
3679 /// # Ok::<(), ClientError>(())
3680 /// ```
3681 pub fn get_balance_with_commitment(
3682 &self,
3683 pubkey: &Pubkey,
3684 commitment_config: CommitmentConfig,
3685 ) -> RpcResult<u64> {
3686 self.invoke(
3687 self.rpc_client
3688 .get_balance_with_commitment(pubkey, commitment_config),
3689 )
3690 }
3691
3692 /// Returns all accounts owned by the provided program pubkey.
3693 ///
3694 /// This method uses the configured [commitment level][cl].
3695 ///
3696 /// [cl]: https://docs.solana.com/developing/clients/jsonrpc-api#configuring-state-commitment
3697 ///
3698 /// # RPC Reference
3699 ///
3700 /// This method corresponds directly to the [`getProgramAccounts`] RPC
3701 /// method.
3702 ///
3703 /// [`getProgramAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getprogramaccounts
3704 ///
3705 /// # Examples
3706 ///
3707 /// ```
3708 /// # use safecoin_client::{
3709 /// # rpc_client::RpcClient,
3710 /// # client_error::ClientError,
3711 /// # };
3712 /// # use solana_sdk::{
3713 /// # signature::Signer,
3714 /// # signer::keypair::Keypair,
3715 /// # };
3716 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3717 /// # let alice = Keypair::new();
3718 /// let accounts = rpc_client.get_program_accounts(&alice.pubkey())?;
3719 /// # Ok::<(), ClientError>(())
3720 /// ```
3721 pub fn get_program_accounts(&self, pubkey: &Pubkey) -> ClientResult<Vec<(Pubkey, Account)>> {
3722 self.invoke(self.rpc_client.get_program_accounts(pubkey))
3723 }
3724
3725 /// Returns all accounts owned by the provided program pubkey.
3726 ///
3727 /// # RPC Reference
3728 ///
3729 /// This method is built on the [`getProgramAccounts`] RPC method.
3730 ///
3731 /// [`getProgramAccounts`]: https://docs.solana.com/developing/clients/jsonrpc-api#getprogramaccounts
3732 ///
3733 /// # Examples
3734 ///
3735 /// ```
3736 /// # use safecoin_client::{
3737 /// # rpc_client::RpcClient,
3738 /// # client_error::ClientError,
3739 /// # rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig},
3740 /// # rpc_filter::{MemcmpEncodedBytes, RpcFilterType, Memcmp},
3741 /// # };
3742 /// # use solana_sdk::{
3743 /// # signature::Signer,
3744 /// # signer::keypair::Keypair,
3745 /// # commitment_config::CommitmentConfig,
3746 /// # };
3747 /// # use safecoin_account_decoder::{UiDataSliceConfig, UiAccountEncoding};
3748 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3749 /// # let alice = Keypair::new();
3750 /// # let base64_bytes = "\
3751 /// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
3752 /// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\
3753 /// # AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";
3754 /// let memcmp = RpcFilterType::Memcmp(Memcmp {
3755 /// offset: 0,
3756 /// bytes: MemcmpEncodedBytes::Base64(base64_bytes.to_string()),
3757 /// encoding: None,
3758 /// });
3759 /// let config = RpcProgramAccountsConfig {
3760 /// filters: Some(vec![
3761 /// RpcFilterType::DataSize(128),
3762 /// memcmp,
3763 /// ]),
3764 /// account_config: RpcAccountInfoConfig {
3765 /// encoding: Some(UiAccountEncoding::Base64),
3766 /// data_slice: Some(UiDataSliceConfig {
3767 /// offset: 0,
3768 /// length: 5,
3769 /// }),
3770 /// commitment: Some(CommitmentConfig::processed()),
3771 /// min_context_slot: Some(1234),
3772 /// },
3773 /// with_context: Some(false),
3774 /// };
3775 /// let accounts = rpc_client.get_program_accounts_with_config(
3776 /// &alice.pubkey(),
3777 /// config,
3778 /// )?;
3779 /// # Ok::<(), ClientError>(())
3780 /// ```
3781 pub fn get_program_accounts_with_config(
3782 &self,
3783 pubkey: &Pubkey,
3784 config: RpcProgramAccountsConfig,
3785 ) -> ClientResult<Vec<(Pubkey, Account)>> {
3786 self.invoke(
3787 self.rpc_client
3788 .get_program_accounts_with_config(pubkey, config),
3789 )
3790 }
3791
3792 /// Returns the stake minimum delegation, in lamports.
3793 ///
3794 /// # RPC Reference
3795 ///
3796 /// This method corresponds directly to the [`getStakeMinimumDelegation`] RPC method.
3797 ///
3798 /// [`getStakeMinimumDelegation`]: https://docs.solana.com/developing/clients/jsonrpc-api#getstakeminimumdelegation
3799 ///
3800 /// # Examples
3801 ///
3802 /// ```
3803 /// # use safecoin_client::{
3804 /// # rpc_client::RpcClient,
3805 /// # client_error::ClientError,
3806 /// # };
3807 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3808 /// let stake_minimum_delegation = rpc_client.get_stake_minimum_delegation()?;
3809 /// # Ok::<(), ClientError>(())
3810 /// ```
3811 pub fn get_stake_minimum_delegation(&self) -> ClientResult<u64> {
3812 self.invoke(self.rpc_client.get_stake_minimum_delegation())
3813 }
3814
3815 /// Returns the stake minimum delegation, in lamports, based on the commitment level.
3816 ///
3817 /// # RPC Reference
3818 ///
3819 /// This method corresponds directly to the [`getStakeMinimumDelegation`] RPC method.
3820 ///
3821 /// [`getStakeMinimumDelegation`]: https://docs.solana.com/developing/clients/jsonrpc-api#getstakeminimumdelegation
3822 ///
3823 /// # Examples
3824 ///
3825 /// ```
3826 /// # use safecoin_client::{
3827 /// # rpc_client::RpcClient,
3828 /// # client_error::ClientError,
3829 /// # };
3830 /// # use solana_sdk::commitment_config::CommitmentConfig;
3831 /// # let rpc_client = RpcClient::new_mock("succeeds".to_string());
3832 /// let stake_minimum_delegation =
3833 /// rpc_client.get_stake_minimum_delegation_with_commitment(CommitmentConfig::confirmed())?;
3834 /// # Ok::<(), ClientError>(())
3835 /// ```
3836 pub fn get_stake_minimum_delegation_with_commitment(
3837 &self,
3838 commitment_config: CommitmentConfig,
3839 ) -> ClientResult<u64> {
3840 self.invoke(
3841 self.rpc_client
3842 .get_stake_minimum_delegation_with_commitment(commitment_config),
3843 )
3844 }
3845
3846 /// Request the transaction count.
3847 pub fn get_transaction_count(&self) -> ClientResult<u64> {
3848 self.invoke(self.rpc_client.get_transaction_count())
3849 }
3850
3851 pub fn get_transaction_count_with_commitment(
3852 &self,
3853 commitment_config: CommitmentConfig,
3854 ) -> ClientResult<u64> {
3855 self.invoke(
3856 self.rpc_client
3857 .get_transaction_count_with_commitment(commitment_config),
3858 )
3859 }
3860
3861 #[deprecated(
3862 since = "1.9.0",
3863 note = "Please use `get_latest_blockhash` and `get_fee_for_message` instead"
3864 )]
3865 #[allow(deprecated)]
3866 pub fn get_fees(&self) -> ClientResult<Fees> {
3867 self.invoke(self.rpc_client.get_fees())
3868 }
3869
3870 #[deprecated(
3871 since = "1.9.0",
3872 note = "Please use `get_latest_blockhash_with_commitment` and `get_fee_for_message` instead"
3873 )]
3874 #[allow(deprecated)]
3875 pub fn get_fees_with_commitment(&self, commitment_config: CommitmentConfig) -> RpcResult<Fees> {
3876 self.invoke(self.rpc_client.get_fees_with_commitment(commitment_config))
3877 }
3878
3879 #[deprecated(since = "1.9.0", note = "Please use `get_latest_blockhash` instead")]
3880 #[allow(deprecated)]
3881 pub fn get_recent_blockhash(&self) -> ClientResult<(Hash, FeeCalculator)> {
3882 self.invoke(self.rpc_client.get_recent_blockhash())
3883 }
3884
3885 #[deprecated(
3886 since = "1.9.0",
3887 note = "Please use `get_latest_blockhash_with_commitment` instead"
3888 )]
3889 #[allow(deprecated)]
3890 pub fn get_recent_blockhash_with_commitment(
3891 &self,
3892 commitment_config: CommitmentConfig,
3893 ) -> RpcResult<(Hash, FeeCalculator, Slot)> {
3894 self.invoke(
3895 self.rpc_client
3896 .get_recent_blockhash_with_commitment(commitment_config),
3897 )
3898 }
3899
3900 #[deprecated(since = "1.9.0", note = "Please `get_fee_for_message` instead")]
3901 #[allow(deprecated)]
3902 pub fn get_fee_calculator_for_blockhash(
3903 &self,
3904 blockhash: &Hash,
3905 ) -> ClientResult<Option<FeeCalculator>> {
3906 self.invoke(self.rpc_client.get_fee_calculator_for_blockhash(blockhash))
3907 }
3908
3909 #[deprecated(
3910 since = "1.9.0",
3911 note = "Please `get_latest_blockhash_with_commitment` and `get_fee_for_message` instead"
3912 )]
3913 #[allow(deprecated)]
3914 pub fn get_fee_calculator_for_blockhash_with_commitment(
3915 &self,
3916 blockhash: &Hash,
3917 commitment_config: CommitmentConfig,
3918 ) -> RpcResult<Option<FeeCalculator>> {
3919 self.invoke(
3920 self.rpc_client
3921 .get_fee_calculator_for_blockhash_with_commitment(blockhash, commitment_config),
3922 )
3923 }
3924
3925 #[deprecated(
3926 since = "1.9.0",
3927 note = "Please do not use, will no longer be available in the future"
3928 )]
3929 #[allow(deprecated)]
3930 pub fn get_fee_rate_governor(&self) -> RpcResult<FeeRateGovernor> {
3931 self.invoke(self.rpc_client.get_fee_rate_governor())
3932 }
3933
3934 #[deprecated(
3935 since = "1.9.0",
3936 note = "Please do not use, will no longer be available in the future"
3937 )]
3938 #[allow(deprecated)]
3939 pub fn get_new_blockhash(&self, blockhash: &Hash) -> ClientResult<(Hash, FeeCalculator)> {
3940 self.invoke(self.rpc_client.get_new_blockhash(blockhash))
3941 }
3942
3943 pub fn get_first_available_block(&self) -> ClientResult<Slot> {
3944 self.invoke(self.rpc_client.get_first_available_block())
3945 }
3946
3947 pub fn get_genesis_hash(&self) -> ClientResult<Hash> {
3948 self.invoke(self.rpc_client.get_genesis_hash())
3949 }
3950
3951 pub fn get_health(&self) -> ClientResult<()> {
3952 self.invoke(self.rpc_client.get_health())
3953 }
3954
3955 pub fn get_token_account(&self, pubkey: &Pubkey) -> ClientResult<Option<UiTokenAccount>> {
3956 self.invoke(self.rpc_client.get_token_account(pubkey))
3957 }
3958
3959 pub fn get_token_account_with_commitment(
3960 &self,
3961 pubkey: &Pubkey,
3962 commitment_config: CommitmentConfig,
3963 ) -> RpcResult<Option<UiTokenAccount>> {
3964 self.invoke(
3965 self.rpc_client
3966 .get_token_account_with_commitment(pubkey, commitment_config),
3967 )
3968 }
3969
3970 pub fn get_token_account_balance(&self, pubkey: &Pubkey) -> ClientResult<UiTokenAmount> {
3971 self.invoke(self.rpc_client.get_token_account_balance(pubkey))
3972 }
3973
3974 pub fn get_token_account_balance_with_commitment(
3975 &self,
3976 pubkey: &Pubkey,
3977 commitment_config: CommitmentConfig,
3978 ) -> RpcResult<UiTokenAmount> {
3979 self.invoke(
3980 self.rpc_client
3981 .get_token_account_balance_with_commitment(pubkey, commitment_config),
3982 )
3983 }
3984
3985 pub fn get_token_accounts_by_delegate(
3986 &self,
3987 delegate: &Pubkey,
3988 token_account_filter: TokenAccountsFilter,
3989 ) -> ClientResult<Vec<RpcKeyedAccount>> {
3990 self.invoke(
3991 self.rpc_client
3992 .get_token_accounts_by_delegate(delegate, token_account_filter),
3993 )
3994 }
3995
3996 pub fn get_token_accounts_by_delegate_with_commitment(
3997 &self,
3998 delegate: &Pubkey,
3999 token_account_filter: TokenAccountsFilter,
4000 commitment_config: CommitmentConfig,
4001 ) -> RpcResult<Vec<RpcKeyedAccount>> {
4002 self.invoke(
4003 self.rpc_client
4004 .get_token_accounts_by_delegate_with_commitment(
4005 delegate,
4006 token_account_filter,
4007 commitment_config,
4008 ),
4009 )
4010 }
4011
4012 pub fn get_token_accounts_by_owner(
4013 &self,
4014 owner: &Pubkey,
4015 token_account_filter: TokenAccountsFilter,
4016 ) -> ClientResult<Vec<RpcKeyedAccount>> {
4017 self.invoke(
4018 self.rpc_client
4019 .get_token_accounts_by_owner(owner, token_account_filter),
4020 )
4021 }
4022
4023 pub fn get_token_accounts_by_owner_with_commitment(
4024 &self,
4025 owner: &Pubkey,
4026 token_account_filter: TokenAccountsFilter,
4027 commitment_config: CommitmentConfig,
4028 ) -> RpcResult<Vec<RpcKeyedAccount>> {
4029 self.invoke(self.rpc_client.get_token_accounts_by_owner_with_commitment(
4030 owner,
4031 token_account_filter,
4032 commitment_config,
4033 ))
4034 }
4035
4036 pub fn get_token_supply(&self, mint: &Pubkey) -> ClientResult<UiTokenAmount> {
4037 self.invoke(self.rpc_client.get_token_supply(mint))
4038 }
4039
4040 pub fn get_token_supply_with_commitment(
4041 &self,
4042 mint: &Pubkey,
4043 commitment_config: CommitmentConfig,
4044 ) -> RpcResult<UiTokenAmount> {
4045 self.invoke(
4046 self.rpc_client
4047 .get_token_supply_with_commitment(mint, commitment_config),
4048 )
4049 }
4050
4051 pub fn request_airdrop(&self, pubkey: &Pubkey, lamports: u64) -> ClientResult<Signature> {
4052 self.invoke(self.rpc_client.request_airdrop(pubkey, lamports))
4053 }
4054
4055 pub fn request_airdrop_with_blockhash(
4056 &self,
4057 pubkey: &Pubkey,
4058 lamports: u64,
4059 recent_blockhash: &Hash,
4060 ) -> ClientResult<Signature> {
4061 self.invoke(self.rpc_client.request_airdrop_with_blockhash(
4062 pubkey,
4063 lamports,
4064 recent_blockhash,
4065 ))
4066 }
4067
4068 pub fn request_airdrop_with_config(
4069 &self,
4070 pubkey: &Pubkey,
4071 lamports: u64,
4072 config: RpcRequestAirdropConfig,
4073 ) -> ClientResult<Signature> {
4074 self.invoke(
4075 self.rpc_client
4076 .request_airdrop_with_config(pubkey, lamports, config),
4077 )
4078 }
4079
4080 pub fn poll_get_balance_with_commitment(
4081 &self,
4082 pubkey: &Pubkey,
4083 commitment_config: CommitmentConfig,
4084 ) -> ClientResult<u64> {
4085 self.invoke(
4086 self.rpc_client
4087 .poll_get_balance_with_commitment(pubkey, commitment_config),
4088 )
4089 }
4090
4091 pub fn wait_for_balance_with_commitment(
4092 &self,
4093 pubkey: &Pubkey,
4094 expected_balance: Option<u64>,
4095 commitment_config: CommitmentConfig,
4096 ) -> Option<u64> {
4097 self.invoke(self.rpc_client.wait_for_balance_with_commitment(
4098 pubkey,
4099 expected_balance,
4100 commitment_config,
4101 ))
4102 .ok()
4103 }
4104
4105 /// Poll the server to confirm a transaction.
4106 pub fn poll_for_signature(&self, signature: &Signature) -> ClientResult<()> {
4107 self.invoke(self.rpc_client.poll_for_signature(signature))
4108 }
4109
4110 /// Poll the server to confirm a transaction.
4111 pub fn poll_for_signature_with_commitment(
4112 &self,
4113 signature: &Signature,
4114 commitment_config: CommitmentConfig,
4115 ) -> ClientResult<()> {
4116 self.invoke(
4117 self.rpc_client
4118 .poll_for_signature_with_commitment(signature, commitment_config),
4119 )
4120 }
4121
4122 /// Poll the server to confirm a transaction.
4123 pub fn poll_for_signature_confirmation(
4124 &self,
4125 signature: &Signature,
4126 min_confirmed_blocks: usize,
4127 ) -> ClientResult<usize> {
4128 self.invoke(
4129 self.rpc_client
4130 .poll_for_signature_confirmation(signature, min_confirmed_blocks),
4131 )
4132 }
4133
4134 pub fn get_num_blocks_since_signature_confirmation(
4135 &self,
4136 signature: &Signature,
4137 ) -> ClientResult<usize> {
4138 self.invoke(
4139 self.rpc_client
4140 .get_num_blocks_since_signature_confirmation(signature),
4141 )
4142 }
4143
4144 pub fn get_latest_blockhash(&self) -> ClientResult<Hash> {
4145 self.invoke(self.rpc_client.get_latest_blockhash())
4146 }
4147
4148 #[allow(deprecated)]
4149 pub fn get_latest_blockhash_with_commitment(
4150 &self,
4151 commitment: CommitmentConfig,
4152 ) -> ClientResult<(Hash, u64)> {
4153 self.invoke(
4154 self.rpc_client
4155 .get_latest_blockhash_with_commitment(commitment),
4156 )
4157 }
4158
4159 #[allow(deprecated)]
4160 pub fn is_blockhash_valid(
4161 &self,
4162 blockhash: &Hash,
4163 commitment: CommitmentConfig,
4164 ) -> ClientResult<bool> {
4165 self.invoke(self.rpc_client.is_blockhash_valid(blockhash, commitment))
4166 }
4167
4168 #[allow(deprecated)]
4169 pub fn get_fee_for_message(&self, message: &impl SerializableMessage) -> ClientResult<u64> {
4170 self.invoke(self.rpc_client.get_fee_for_message(message))
4171 }
4172
4173 pub fn get_new_latest_blockhash(&self, blockhash: &Hash) -> ClientResult<Hash> {
4174 self.invoke(self.rpc_client.get_new_latest_blockhash(blockhash))
4175 }
4176
4177 pub fn get_transport_stats(&self) -> RpcTransportStats {
4178 self.rpc_client.get_transport_stats()
4179 }
4180
4181 fn invoke<T, F: std::future::Future<Output = ClientResult<T>>>(&self, f: F) -> ClientResult<T> {
4182 // `block_on()` panics if called within an asynchronous execution context. Whereas
4183 // `block_in_place()` only panics if called from a current_thread runtime, which is the
4184 // lesser evil.
4185 tokio::task::block_in_place(move || self.runtime.as_ref().expect("runtime").block_on(f))
4186 }
4187}
4188
4189/// Mocks for documentation examples
4190#[doc(hidden)]
4191pub fn create_rpc_client_mocks() -> crate::mock_sender::Mocks {
4192 let mut mocks = std::collections::HashMap::new();
4193
4194 let get_account_request = RpcRequest::GetAccountInfo;
4195 let get_account_response = serde_json::to_value(Response {
4196 context: RpcResponseContext {
4197 slot: 1,
4198 api_version: None,
4199 },
4200 value: {
4201 let pubkey = Pubkey::from_str("BgvYtJEfmZYdVKiptmMjxGzv8iQoo4MWjsP3QsTkhhxa").unwrap();
4202 let account = Account {
4203 lamports: 1_000_000,
4204 data: vec![],
4205 owner: pubkey,
4206 executable: false,
4207 rent_epoch: 0,
4208 };
4209 UiAccount::encode(&pubkey, &account, UiAccountEncoding::Base64, None, None)
4210 },
4211 })
4212 .unwrap();
4213
4214 mocks.insert(get_account_request, get_account_response);
4215
4216 mocks
4217}
4218
4219#[cfg(test)]
4220mod tests {
4221 use {
4222 super::*,
4223 crate::{client_error::ClientErrorKind, mock_sender::PUBKEY},
4224 assert_matches::assert_matches,
4225 crossbeam_channel::unbounded,
4226 jsonrpc_core::{futures::prelude::*, Error, IoHandler, Params},
4227 jsonrpc_http_server::{AccessControlAllowOrigin, DomainsValidation, ServerBuilder},
4228 serde_json::{json, Number},
4229 solana_sdk::{
4230 instruction::InstructionError,
4231 signature::{Keypair, Signer},
4232 system_transaction,
4233 transaction::TransactionError,
4234 },
4235 std::{io, thread},
4236 };
4237
4238 #[test]
4239 fn test_send() {
4240 _test_send();
4241 }
4242
4243 #[tokio::test(flavor = "current_thread")]
4244 #[should_panic(expected = "can call blocking only when running on the multi-threaded runtime")]
4245 async fn test_send_async_current_thread() {
4246 _test_send();
4247 }
4248
4249 #[tokio::test(flavor = "multi_thread")]
4250 async fn test_send_async_multi_thread() {
4251 _test_send();
4252 }
4253
4254 fn _test_send() {
4255 let (sender, receiver) = unbounded();
4256 thread::spawn(move || {
4257 let rpc_addr = "0.0.0.0:0".parse().unwrap();
4258 let mut io = IoHandler::default();
4259 // Successful request
4260 io.add_method("getBalance", |_params: Params| {
4261 future::ok(Value::Number(Number::from(50)))
4262 });
4263 // Failed request
4264 io.add_method("getRecentBlockhash", |params: Params| {
4265 if params != Params::None {
4266 future::err(Error::invalid_request())
4267 } else {
4268 future::ok(Value::String(
4269 "deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx".to_string(),
4270 ))
4271 }
4272 });
4273
4274 let server = ServerBuilder::new(io)
4275 .threads(1)
4276 .cors(DomainsValidation::AllowOnly(vec![
4277 AccessControlAllowOrigin::Any,
4278 ]))
4279 .start_http(&rpc_addr)
4280 .expect("Unable to start RPC server");
4281 sender.send(*server.address()).unwrap();
4282 server.wait();
4283 });
4284
4285 let rpc_addr = receiver.recv().unwrap();
4286 let rpc_client = RpcClient::new_socket(rpc_addr);
4287
4288 let balance: u64 = rpc_client
4289 .send(
4290 RpcRequest::GetBalance,
4291 json!(["deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx"]),
4292 )
4293 .unwrap();
4294 assert_eq!(balance, 50);
4295
4296 #[allow(deprecated)]
4297 let blockhash: String = rpc_client
4298 .send(RpcRequest::GetRecentBlockhash, Value::Null)
4299 .unwrap();
4300 assert_eq!(blockhash, "deadbeefXjn8o3yroDHxUtKsZZgoy4GPkPPXfouKNHhx");
4301
4302 // Send erroneous parameter
4303 #[allow(deprecated)]
4304 let blockhash: ClientResult<String> =
4305 rpc_client.send(RpcRequest::GetRecentBlockhash, json!(["parameter"]));
4306 assert!(blockhash.is_err());
4307 }
4308
4309 #[test]
4310 fn test_send_transaction() {
4311 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4312
4313 let key = Keypair::new();
4314 let to = solana_sdk::pubkey::new_rand();
4315 let blockhash = Hash::default();
4316 let tx = system_transaction::transfer(&key, &to, 50, blockhash);
4317
4318 let signature = rpc_client.send_transaction(&tx);
4319 assert_eq!(signature.unwrap(), tx.signatures[0]);
4320
4321 let rpc_client = RpcClient::new_mock("fails".to_string());
4322
4323 let signature = rpc_client.send_transaction(&tx);
4324 assert!(signature.is_err());
4325
4326 // Test bad signature returned from rpc node
4327 let rpc_client = RpcClient::new_mock("malicious".to_string());
4328 let signature = rpc_client.send_transaction(&tx);
4329 assert!(signature.is_err());
4330 }
4331
4332 #[test]
4333 fn test_get_recent_blockhash() {
4334 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4335
4336 let expected_blockhash: Hash = PUBKEY.parse().unwrap();
4337
4338 let blockhash = rpc_client.get_latest_blockhash().expect("blockhash ok");
4339 assert_eq!(blockhash, expected_blockhash);
4340
4341 let rpc_client = RpcClient::new_mock("fails".to_string());
4342
4343 #[allow(deprecated)]
4344 let result = rpc_client.get_recent_blockhash();
4345 assert!(result.is_err());
4346 }
4347
4348 #[test]
4349 fn test_custom_request() {
4350 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4351
4352 let slot = rpc_client.get_slot().unwrap();
4353 assert_eq!(slot, 0);
4354
4355 let custom_slot = rpc_client
4356 .send::<Slot>(RpcRequest::Custom { method: "getSlot" }, Value::Null)
4357 .unwrap();
4358
4359 assert_eq!(slot, custom_slot);
4360 }
4361
4362 #[test]
4363 fn test_get_signature_status() {
4364 let signature = Signature::default();
4365
4366 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4367 let status = rpc_client.get_signature_status(&signature).unwrap();
4368 assert_eq!(status, Some(Ok(())));
4369
4370 let rpc_client = RpcClient::new_mock("sig_not_found".to_string());
4371 let status = rpc_client.get_signature_status(&signature).unwrap();
4372 assert_eq!(status, None);
4373
4374 let rpc_client = RpcClient::new_mock("account_in_use".to_string());
4375 let status = rpc_client.get_signature_status(&signature).unwrap();
4376 assert_eq!(status, Some(Err(TransactionError::AccountInUse)));
4377 }
4378
4379 #[test]
4380 fn test_send_and_confirm_transaction() {
4381 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4382
4383 let key = Keypair::new();
4384 let to = solana_sdk::pubkey::new_rand();
4385 let blockhash = Hash::default();
4386 let tx = system_transaction::transfer(&key, &to, 50, blockhash);
4387 let result = rpc_client.send_and_confirm_transaction(&tx);
4388 result.unwrap();
4389
4390 let rpc_client = RpcClient::new_mock("account_in_use".to_string());
4391 let result = rpc_client.send_and_confirm_transaction(&tx);
4392 assert!(result.is_err());
4393
4394 let rpc_client = RpcClient::new_mock("instruction_error".to_string());
4395 let result = rpc_client.send_and_confirm_transaction(&tx);
4396 assert_matches!(
4397 result.unwrap_err().kind(),
4398 ClientErrorKind::TransactionError(TransactionError::InstructionError(
4399 0,
4400 InstructionError::UninitializedAccount
4401 ))
4402 );
4403
4404 let rpc_client = RpcClient::new_mock("sig_not_found".to_string());
4405 let result = rpc_client.send_and_confirm_transaction(&tx);
4406 if let ClientErrorKind::Io(err) = result.unwrap_err().kind() {
4407 assert_eq!(err.kind(), io::ErrorKind::Other);
4408 }
4409 }
4410
4411 #[test]
4412 fn test_rpc_client_thread() {
4413 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4414 thread::spawn(move || rpc_client);
4415 }
4416
4417 // Regression test that the get_block_production_with_config
4418 // method internally creates the json params array correctly.
4419 #[test]
4420 fn get_block_production_with_config_no_error() -> ClientResult<()> {
4421 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4422
4423 let config = RpcBlockProductionConfig {
4424 identity: Some(Keypair::new().pubkey().to_string()),
4425 range: None,
4426 commitment: None,
4427 };
4428
4429 let prod = rpc_client.get_block_production_with_config(config)?.value;
4430
4431 assert!(!prod.by_identity.is_empty());
4432
4433 Ok(())
4434 }
4435
4436 #[test]
4437 fn test_get_latest_blockhash() {
4438 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4439
4440 let expected_blockhash: Hash = PUBKEY.parse().unwrap();
4441
4442 let blockhash = rpc_client.get_latest_blockhash().expect("blockhash ok");
4443 assert_eq!(blockhash, expected_blockhash);
4444
4445 let rpc_client = RpcClient::new_mock("fails".to_string());
4446
4447 #[allow(deprecated)]
4448 let is_err = rpc_client.get_latest_blockhash().is_err();
4449 assert!(is_err);
4450 }
4451
4452 #[test]
4453 fn test_get_stake_minimum_delegation() {
4454 let expected_minimum_delegation: u64 = 123_456_789;
4455 let rpc_client = RpcClient::new_mock("succeeds".to_string());
4456
4457 // Test: without commitment
4458 {
4459 let actual_minimum_delegation = rpc_client.get_stake_minimum_delegation().unwrap();
4460 assert_eq!(expected_minimum_delegation, actual_minimum_delegation);
4461 }
4462
4463 // Test: with commitment
4464 {
4465 let actual_minimum_delegation = rpc_client
4466 .get_stake_minimum_delegation_with_commitment(CommitmentConfig::confirmed())
4467 .unwrap();
4468 assert_eq!(expected_minimum_delegation, actual_minimum_delegation);
4469 }
4470 }
4471
4472 #[test]
4473 fn test_get_program_accounts_with_config() {
4474 let program_id = Pubkey::new_unique();
4475 let pubkey = Pubkey::new_unique();
4476 let account = Account {
4477 lamports: 1_000_000,
4478 data: vec![],
4479 owner: program_id,
4480 executable: false,
4481 rent_epoch: 0,
4482 };
4483 let keyed_account = RpcKeyedAccount {
4484 pubkey: pubkey.to_string(),
4485 account: UiAccount::encode(&pubkey, &account, UiAccountEncoding::Base64, None, None),
4486 };
4487 let expected_result = vec![(pubkey, account)];
4488 // Test: without context
4489 {
4490 let mocks: Mocks = [(
4491 RpcRequest::GetProgramAccounts,
4492 serde_json::to_value(OptionalContext::NoContext(vec![keyed_account.clone()]))
4493 .unwrap(),
4494 )]
4495 .into_iter()
4496 .collect();
4497 let rpc_client = RpcClient::new_mock_with_mocks("mock_client".to_string(), mocks);
4498 let result = rpc_client
4499 .get_program_accounts_with_config(
4500 &program_id,
4501 RpcProgramAccountsConfig {
4502 filters: None,
4503 account_config: RpcAccountInfoConfig {
4504 encoding: Some(UiAccountEncoding::Base64),
4505 data_slice: None,
4506 commitment: None,
4507 min_context_slot: None,
4508 },
4509 with_context: None,
4510 },
4511 )
4512 .unwrap();
4513 assert_eq!(expected_result, result);
4514 }
4515
4516 // Test: with context
4517 {
4518 let mocks: Mocks = [(
4519 RpcRequest::GetProgramAccounts,
4520 serde_json::to_value(OptionalContext::Context(Response {
4521 context: RpcResponseContext {
4522 slot: 1,
4523 api_version: None,
4524 },
4525 value: vec![keyed_account],
4526 }))
4527 .unwrap(),
4528 )]
4529 .into_iter()
4530 .collect();
4531 let rpc_client = RpcClient::new_mock_with_mocks("mock_client".to_string(), mocks);
4532 let result = rpc_client
4533 .get_program_accounts_with_config(
4534 &program_id,
4535 RpcProgramAccountsConfig {
4536 filters: None,
4537 account_config: RpcAccountInfoConfig {
4538 encoding: Some(UiAccountEncoding::Base64),
4539 data_slice: None,
4540 commitment: None,
4541 min_context_slot: None,
4542 },
4543 with_context: Some(true),
4544 },
4545 )
4546 .unwrap();
4547 assert_eq!(expected_result, result);
4548 }
4549 }
4550}