shadow_drive_sdk/client/
delete_storage_account.rs

1use anchor_lang::{system_program, InstructionData, ToAccountMetas};
2use shadow_drive_user_staking::accounts as shdw_drive_accounts;
3use shadow_drive_user_staking::instruction as shdw_drive_instructions;
4use solana_sdk::{
5    instruction::Instruction, pubkey::Pubkey, signer::Signer, transaction::Transaction,
6};
7
8use super::ShadowDriveClient;
9use crate::constants::{PROGRAM_ADDRESS, STORAGE_CONFIG_PDA, TOKEN_MINT};
10use crate::models::{
11    storage_acct::{StorageAccount, StorageAccountV2, StorageAcct},
12    ShadowDriveResult, ShdwDriveResponse,
13};
14
15impl<T> ShadowDriveClient<T>
16where
17    T: Signer,
18{
19    /// Marks a [`StorageAccount`](crate::models::StorageAccount) for deletion from the Shadow Drive.
20    /// If an account is marked for deletion, all files within the account will be deleted as well.
21    /// Any stake remaining in the [`StorageAccount`](crate::models::StorageAccount) will be refunded to the creator.
22    /// Accounts marked for deletion are deleted at the end of each Solana epoch.
23    /// Marking a [`StorageAccount`](crate::models::StorageAccount) for deletion can be undone with `cancel_delete_storage_account`,
24    /// but this must be done before the end of the Solana epoch.
25    /// * `storage_account_key` - The public key of the [`StorageAccount`](crate::models::StorageAccount) that you want to mark for deletion.
26    /// # Example
27    ///
28    /// ```
29    /// # use shadow_drive_rust::{ShadowDriveClient, derived_addresses::storage_account};
30    /// # use solana_client::rpc_client::RpcClient;
31    /// # use solana_sdk::{
32    /// # pubkey::Pubkey,
33    /// # signature::Keypair,
34    /// # signer::{keypair::read_keypair_file, Signer},
35    /// # };
36    /// #
37    /// # let keypair = read_keypair_file(KEYPAIR_PATH).expect("failed to load keypair at path");
38    /// # let user_pubkey = keypair.pubkey();
39    /// # let rpc_client = RpcClient::new("https://ssc-dao.genesysgo.net");
40    /// # let shdw_drive_client = ShadowDriveClient::new(keypair, rpc_client);
41    /// # let (storage_account_key, _) = storage_account(&user_pubkey, 0);
42    /// #
43    /// let delete_storage_account_response = shdw_drive_client
44    ///     .delete_storage_account(&storage_account_key)
45    ///     .await?;
46    /// ```
47    pub async fn delete_storage_account(
48        &self,
49        storage_account_key: &Pubkey,
50    ) -> ShadowDriveResult<ShdwDriveResponse> {
51        let selected_account = self.get_storage_account(storage_account_key).await?;
52
53        let txn = match selected_account {
54            StorageAcct::V1(storage_account) => {
55                self.delete_storage_account_v1(storage_account_key, storage_account)
56                    .await?
57            }
58            StorageAcct::V2(storage_account) => {
59                self.delete_storage_account_v2(storage_account_key, storage_account)
60                    .await?
61            }
62        };
63
64        let txn_result = self.rpc_client.send_and_confirm_transaction(&txn).await?;
65
66        Ok(ShdwDriveResponse {
67            txid: txn_result.to_string(),
68        })
69    }
70
71    async fn delete_storage_account_v1(
72        &self,
73        storage_account_key: &Pubkey,
74        storage_account: StorageAccount,
75    ) -> ShadowDriveResult<Transaction> {
76        let accounts = shdw_drive_accounts::RequestDeleteAccountV1 {
77            storage_config: *STORAGE_CONFIG_PDA,
78            storage_account: *storage_account_key,
79            owner: storage_account.owner_1,
80            token_mint: TOKEN_MINT,
81            system_program: system_program::ID,
82        };
83        let args = shdw_drive_instructions::RequestDeleteAccount {};
84
85        let instruction = Instruction {
86            program_id: PROGRAM_ADDRESS,
87            accounts: accounts.to_account_metas(None),
88            data: args.data(),
89        };
90
91        let txn = Transaction::new_signed_with_payer(
92            &[instruction],
93            Some(&self.wallet.pubkey()),
94            &[&self.wallet],
95            self.rpc_client.get_latest_blockhash().await?,
96        );
97
98        Ok(txn)
99    }
100
101    async fn delete_storage_account_v2(
102        &self,
103        storage_account_key: &Pubkey,
104        storage_account: StorageAccountV2,
105    ) -> ShadowDriveResult<Transaction> {
106        let accounts = shdw_drive_accounts::RequestDeleteAccountV2 {
107            storage_config: *STORAGE_CONFIG_PDA,
108            storage_account: *storage_account_key,
109            owner: storage_account.owner_1,
110            token_mint: TOKEN_MINT,
111            system_program: system_program::ID,
112        };
113
114        let args = shdw_drive_instructions::RequestDeleteAccount2 {};
115
116        let instruction = Instruction {
117            program_id: PROGRAM_ADDRESS,
118            accounts: accounts.to_account_metas(None),
119            data: args.data(),
120        };
121
122        let txn = Transaction::new_signed_with_payer(
123            &[instruction],
124            Some(&self.wallet.pubkey()),
125            &[&self.wallet],
126            self.rpc_client.get_latest_blockhash().await?,
127        );
128
129        Ok(txn)
130    }
131}