shadow_drive_sdk/client/
cancel_delete_storage_account.rs

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