nonblocking.rs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. use crate::{
  2. ClientError, Config, EventContext, EventUnsubscriber, Program, ProgramAccountsIterator,
  3. RequestBuilder,
  4. };
  5. use anchor_lang::{prelude::Pubkey, AccountDeserialize, Discriminator};
  6. use solana_client::{rpc_config::RpcSendTransactionConfig, rpc_filter::RpcFilterType};
  7. use solana_sdk::{
  8. commitment_config::CommitmentConfig, signature::Signature, signer::Signer,
  9. transaction::Transaction,
  10. };
  11. use std::{marker::PhantomData, ops::Deref, sync::Arc};
  12. use tokio::sync::RwLock;
  13. impl<'a> EventUnsubscriber<'a> {
  14. /// Unsubscribe gracefully.
  15. pub async fn unsubscribe(self) {
  16. self.unsubscribe_internal().await
  17. }
  18. }
  19. impl<C: Deref<Target = impl Signer> + Clone> Program<C> {
  20. pub fn new(program_id: Pubkey, cfg: Config<C>) -> Result<Self, ClientError> {
  21. Ok(Self {
  22. program_id,
  23. cfg,
  24. sub_client: Arc::new(RwLock::new(None)),
  25. })
  26. }
  27. /// Returns the account at the given address.
  28. pub async fn account<T: AccountDeserialize>(&self, address: Pubkey) -> Result<T, ClientError> {
  29. self.account_internal(address).await
  30. }
  31. /// Returns all program accounts of the given type matching the given filters
  32. pub async fn accounts<T: AccountDeserialize + Discriminator>(
  33. &self,
  34. filters: Vec<RpcFilterType>,
  35. ) -> Result<Vec<(Pubkey, T)>, ClientError> {
  36. self.accounts_lazy(filters).await?.collect()
  37. }
  38. /// Returns all program accounts of the given type matching the given filters as an iterator
  39. /// Deserialization is executed lazily
  40. pub async fn accounts_lazy<T: AccountDeserialize + Discriminator>(
  41. &self,
  42. filters: Vec<RpcFilterType>,
  43. ) -> Result<ProgramAccountsIterator<T>, ClientError> {
  44. self.accounts_lazy_internal(filters).await
  45. }
  46. /// Subscribe to program logs.
  47. ///
  48. /// Returns an [`EventUnsubscriber`] to unsubscribe and close connection gracefully.
  49. pub async fn on<T: anchor_lang::Event + anchor_lang::AnchorDeserialize>(
  50. &self,
  51. f: impl Fn(&EventContext, T) + Send + 'static,
  52. ) -> Result<EventUnsubscriber, ClientError> {
  53. let (handle, rx) = self.on_internal(f).await?;
  54. Ok(EventUnsubscriber {
  55. handle,
  56. rx,
  57. _lifetime_marker: PhantomData,
  58. })
  59. }
  60. }
  61. impl<'a, C: Deref<Target = impl Signer> + Clone> RequestBuilder<'a, C> {
  62. pub fn from(
  63. program_id: Pubkey,
  64. cluster: &str,
  65. payer: C,
  66. options: Option<CommitmentConfig>,
  67. ) -> Self {
  68. Self {
  69. program_id,
  70. payer,
  71. cluster: cluster.to_string(),
  72. accounts: Vec::new(),
  73. options: options.unwrap_or_default(),
  74. instructions: Vec::new(),
  75. instruction_data: None,
  76. signers: Vec::new(),
  77. }
  78. }
  79. pub async fn signed_transaction(&self) -> Result<Transaction, ClientError> {
  80. self.signed_transaction_internal().await
  81. }
  82. pub async fn send(self) -> Result<Signature, ClientError> {
  83. self.send_internal().await
  84. }
  85. pub async fn send_with_spinner_and_config(
  86. self,
  87. config: RpcSendTransactionConfig,
  88. ) -> Result<Signature, ClientError> {
  89. self.send_with_spinner_and_config_internal(config).await
  90. }
  91. }