shadow_drive_sdk/client/
get_storage_account.rs

1use anchor_lang::AccountDeserialize;
2use futures::future::join_all;
3use serde_json::json;
4use solana_sdk::{pubkey::Pubkey, signer::Signer};
5
6use super::ShadowDriveClient;
7use crate::{
8    constants::SHDW_DRIVE_ENDPOINT,
9    derived_addresses,
10    models::{storage_acct::StorageAcct, *},
11};
12
13impl<T> ShadowDriveClient<T>
14where
15    T: Signer,
16{
17    /// Returns the [`StorageAccount`](crate::models::StorageAccount) associated with the pubkey provided by a user.
18    /// * `key` - The public key of the [`StorageAccount`](crate::models::StorageAccount).
19    ///
20    /// # Example
21    ///
22    /// ```
23    /// # use shadow_drive_rust::{ShadowDriveClient, derived_addresses::storage_account};
24    /// # use solana_client::rpc_client::RpcClient;
25    /// # use solana_sdk::{
26    /// # pubkey::Pubkey,
27    /// # signature::Keypair,
28    /// # signer::{keypair::read_keypair_file, Signer},
29    /// # };
30    /// #
31    /// # let keypair = read_keypair_file(KEYPAIR_PATH).expect("failed to load keypair at path");
32    /// # let user_pubkey = keypair.pubkey();
33    /// # let rpc_client = RpcClient::new("https://ssc-dao.genesysgo.net");
34    /// # let shdw_drive_client = ShadowDriveClient::new(keypair, rpc_client);
35    /// # let (storage_account_key, _) = storage_account(&user_pubkey, 0);
36    /// #
37    /// let storage_account = shdw_drive_client
38    ///     .get_storage_account(&storage_account_key)
39    ///     .await
40    ///     .expect("failed to get storage account");
41    /// ```
42    pub async fn get_storage_account(&self, key: &Pubkey) -> ShadowDriveResult<StorageAcct> {
43        let response = self
44            .http_client
45            .post(format!("{}/storage-account-info", SHDW_DRIVE_ENDPOINT))
46            .json(&json!({
47                "storage_account": key.to_string()
48            }))
49            .send()
50            .await?
51            .json()
52            .await?;
53
54        Ok(response)
55    }
56
57    /// Returns all [`StorageAccount`]s associated with the public key provided by a user.
58    /// * `owner` - The public key that is the owner of all the returned [`StorageAccount`]s.
59    ///
60    /// # Example
61    ///
62    /// ```
63    /// # use shadow_drive_rust::ShadowDriveClient;
64    /// # use solana_client::rpc_client::RpcClient;
65    /// # use solana_sdk::{
66    /// # pubkey::Pubkey,
67    /// # signature::Keypair,
68    /// # signer::{keypair::read_keypair_file, Signer},
69    /// # };
70    /// #
71    /// # let keypair = read_keypair_file(KEYPAIR_PATH).expect("failed to load keypair at path");
72    /// # let user_pubkey = keypair.pubkey();
73    /// # let rpc_client = RpcClient::new("https://ssc-dao.genesysgo.net");
74    /// # let shdw_drive_client = ShadowDriveClient::new(keypair, rpc_client);
75    /// #
76    /// let storage_accounts = shdw_drive_client
77    ///     .get_storage_accounts(&user_pubkey)
78    ///     .await
79    ///     .expect("failed to get storage account");
80    /// ```
81    pub async fn get_storage_accounts(
82        &self,
83        owner: &Pubkey,
84    ) -> ShadowDriveResult<Vec<StorageAcct>> {
85        let (user_info_key, _) = derived_addresses::user_info(owner);
86        let user_info = self.rpc_client.get_account_data(&user_info_key).await?;
87        let user_info = UserInfo::try_deserialize(&mut user_info.as_slice())?;
88
89        let accounts_to_fetch = (0..user_info.account_counter)
90            .map(|account_seed| derived_addresses::storage_account(owner, account_seed).0);
91
92        let accounts = accounts_to_fetch.map(|storage_account_key| async move {
93            self.get_storage_account(&storage_account_key).await
94        });
95
96        let (accounts, errors): (
97            Vec<ShadowDriveResult<StorageAcct>>,
98            Vec<ShadowDriveResult<StorageAcct>>,
99        ) = join_all(accounts)
100            .await
101            .into_iter()
102            .partition(Result::is_ok);
103
104        tracing::debug!(?errors, "encountered errors fetching storage_accounts");
105
106        //unwrap is safe due do the abve partition
107        Ok(accounts.into_iter().map(Result::unwrap).collect())
108    }
109}