pub struct ShadowDriveClient<T>where
    T: Signer,
{ /* private fields */ }
Expand description

Client that allows a user to interact with the Shadow Drive.

Implementations§

Adds storage capacity to the specified immutable StorageAccount. This will fail if the StorageAccount is not immutable.

  • storage_account_key - The public key of the immutable StorageAccount.
  • size - The additional amount of storage you want to add. E.g if you have an existing StorageAccount with 1MB of storage but you need 2MB total, size should equal 1MB. When specifying size, only KB, MB, and GB storage units are currently supported.
Example
let add_immutable_storage_response = shdw_drive_client
    .add_immutable_storage(storage_account_key, Byte::from_str("1MB").expect("invalid byte string"))
    .await?;

Adds storage capacity to the specified StorageAccount.

  • storage_account_key - The public key of the StorageAccount.
  • size - The additional amount of storage you want to add. E.g if you have an existing StorageAccount with 1MB of storage but you need 2MB total, size should equal 1MB. When specifying size, only KB, MB, and GB storage units are currently supported.
Example
let add_storage_response = shdw_drive_client
    .add_storage(&storage_account_key, added_bytes)
    .await?;

Unmarks a StorageAccount for deletion from the Shadow Drive. To prevent deletion, this method must be called before the end of the Solana epoch in which delete_storage_account is called.

  • storage_account_key - The public key of the StorageAccount that you want to unmark for deletion.
Example
let cancel_delete_storage_account_response = shdw_drive_client
    .cancel_delete_storage_account(&storage_account_key)
    .await?;

Claims any available stake as a result of the reduce_storage command. After reducing storage amount, users must wait until the end of the epoch to successfully claim their stake.

  • storage_account_key - The public key of the StorageAccount that you want to claim excess stake from.
Example
let claim_stake = shdw_drive_client
    .claim_stake(&storage_account_key)
    .await?;

Creates a StorageAccount on the Shadow Drive. [StorageAccount]’s can hold multiple files, and are paid for using the SHDW token.

  • name - The name of the StorageAccount. Does not need to be unique.
  • size - The amount of storage the StorageAccount should be initialized with. When specifying size, only KB, MB, and GB storage units are currently supported.

Marks a file for deletion from the Shadow Drive. Files marked for deletion are deleted at the end of each Solana epoch. Marking a file for deletion can be undone with cancel_delete_file, but this must be done before the end of the Solana epoch.

  • storage_account_key - The public key of the StorageAccount that contains the file.
  • url - The Shadow Drive url of the file you want to mark for deletion.
Example
let delete_file_response = shdw_drive_client
    .delete_file(&storage_account_key, url)
    .await?;

Marks a StorageAccount for deletion from the Shadow Drive. If an account is marked for deletion, all files within the account will be deleted as well. Any stake remaining in the StorageAccount will be refunded to the creator. Accounts marked for deletion are deleted at the end of each Solana epoch. Marking a StorageAccount for deletion can be undone with cancel_delete_storage_account, but this must be done before the end of the Solana epoch.

  • storage_account_key - The public key of the StorageAccount that you want to mark for deletion.
Example
let delete_storage_account_response = shdw_drive_client
    .delete_storage_account(&storage_account_key)
    .await?;

Replace an existing file on the Shadow Drive with the given updated file.

  • storage_account_key - The public key of the StorageAccount that contains the file.
  • url - The Shadow Drive url of the file you want to replace.
  • data - The updated ShadowFile.
Example
let edit_file_response = shdw_drive_client
    .edit_file(&storage_account_key, url, file)
    .await?;

Returns the StorageAccount associated with the pubkey provided by a user.

Example
let storage_account = shdw_drive_client
    .get_storage_account(&storage_account_key)
    .await
    .expect("failed to get storage account");
Examples found in repository?
src/client/make_storage_immutable.rs (line 56)
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    pub async fn make_storage_immutable(
        &self,
        storage_account_key: &Pubkey,
    ) -> ShadowDriveResult<StorageResponse> {
        let selected_storage_acct = self.get_storage_account(storage_account_key).await?;

        let txn_encoded = match selected_storage_acct {
            StorageAcct::V1(storage_account) => {
                self.make_storage_immutable_v1(storage_account_key, storage_account)
                    .await?
            }
            StorageAcct::V2(storage_account) => {
                self.make_storage_immutable_v2(storage_account_key, storage_account)
                    .await?
            }
        };

        self.send_shdw_txn("make-immutable", txn_encoded).await
    }
More examples
Hide additional examples
src/client/claim_stake.rs (line 52)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
    pub async fn claim_stake(
        &self,
        storage_account_key: &Pubkey,
    ) -> ShadowDriveResult<ShdwDriveResponse> {
        let selected_account = self.get_storage_account(storage_account_key).await?;

        let txn = match selected_account {
            StorageAcct::V1(storage_account) => {
                self.claim_stake_v1(storage_account_key, storage_account)
                    .await?
            }
            StorageAcct::V2(storage_account) => {
                self.claim_stake_v2(storage_account_key, storage_account)
                    .await?
            }
        };

        let txn_result = self.rpc_client.send_and_confirm_transaction(&txn).await?;

        Ok(ShdwDriveResponse {
            txid: txn_result.to_string(),
        })
    }
src/client/cancel_delete_storage_account.rs (line 53)
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
    pub async fn cancel_delete_storage_account(
        &self,
        storage_account_key: &Pubkey,
    ) -> ShadowDriveResult<ShdwDriveResponse> {
        let selected_account = self.get_storage_account(storage_account_key).await?;

        let txn = match selected_account {
            StorageAcct::V1(v1) => {
                self.cancel_delete_storage_account_v1(storage_account_key, v1)
                    .await?
            }
            StorageAcct::V2(v2) => {
                self.cancel_delete_storage_account_v2(storage_account_key, v2)
                    .await?
            }
        };

        let txn_result = self.rpc_client.send_and_confirm_transaction(&txn).await?;

        Ok(ShdwDriveResponse {
            txid: txn_result.to_string(),
        })
    }
src/client/delete_storage_account.rs (line 51)
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
    pub async fn delete_storage_account(
        &self,
        storage_account_key: &Pubkey,
    ) -> ShadowDriveResult<ShdwDriveResponse> {
        let selected_account = self.get_storage_account(storage_account_key).await?;

        let txn = match selected_account {
            StorageAcct::V1(storage_account) => {
                self.delete_storage_account_v1(storage_account_key, storage_account)
                    .await?
            }
            StorageAcct::V2(storage_account) => {
                self.delete_storage_account_v2(storage_account_key, storage_account)
                    .await?
            }
        };

        let txn_result = self.rpc_client.send_and_confirm_transaction(&txn).await?;

        Ok(ShdwDriveResponse {
            txid: txn_result.to_string(),
        })
    }
src/client/reduce_storage.rs (line 68)
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
    pub async fn reduce_storage(
        &self,
        storage_account_key: &Pubkey,
        size: Byte,
    ) -> ShadowDriveResult<StorageResponse> {
        let size_as_bytes: u64 = size
            .get_bytes()
            .try_into()
            .map_err(|_| Error::InvalidStorage)?;

        let selected_storage_acct = self.get_storage_account(storage_account_key).await?;

        let txn_encoded = match selected_storage_acct {
            StorageAcct::V1(storage_account) => {
                self.reduce_storage_v1(storage_account_key, storage_account, size_as_bytes)
                    .await?
            }
            StorageAcct::V2(storage_account) => {
                self.reduce_storage_v2(storage_account_key, storage_account, size_as_bytes)
                    .await?
            }
        };

        self.send_shdw_txn("reduce-storage", txn_encoded).await
    }
src/client/get_storage_account.rs (line 93)
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
    pub async fn get_storage_accounts(
        &self,
        owner: &Pubkey,
    ) -> ShadowDriveResult<Vec<StorageAcct>> {
        let (user_info_key, _) = derived_addresses::user_info(owner);
        let user_info = self.rpc_client.get_account_data(&user_info_key).await?;
        let user_info = UserInfo::try_deserialize(&mut user_info.as_slice())?;

        let accounts_to_fetch = (0..user_info.account_counter)
            .map(|account_seed| derived_addresses::storage_account(owner, account_seed).0);

        let accounts = accounts_to_fetch.map(|storage_account_key| async move {
            self.get_storage_account(&storage_account_key).await
        });

        let (accounts, errors): (
            Vec<ShadowDriveResult<StorageAcct>>,
            Vec<ShadowDriveResult<StorageAcct>>,
        ) = join_all(accounts)
            .await
            .into_iter()
            .partition(Result::is_ok);

        tracing::debug!(?errors, "encountered errors fetching storage_accounts");

        //unwrap is safe due do the abve partition
        Ok(accounts.into_iter().map(Result::unwrap).collect())
    }

Returns all [StorageAccount]s associated with the public key provided by a user.

  • owner - The public key that is the owner of all the returned [StorageAccount]s.
Example
let storage_accounts = shdw_drive_client
    .get_storage_accounts(&user_pubkey)
    .await
    .expect("failed to get storage account");

Gets a list of all files associated with a storage account. The output contains all of the file names as strings.

  • storage_account_key - The public key of the StorageAccount that owns the files.
Example
let files = shdw_drive_client
    .list_objects(&storage_account_key)
    .await?;

Permanently locks a StorageAccount and all contained files. After a StorageAccount has been locked, a user will no longer be able to delete/edit files, add/reduce storage amount, or delete the StorageAccount.

  • storage_account_key - The public key of the StorageAccount that will be made immutable.
Example
let make_immutable_response = shdw_drive_client
    .make_storage_immutable(&storage_account_key)
    .await?;

Migrates a v1 StorageAccount to v2. This requires two separate transactions to reuse the original pubkey. To minimize chance of failure, it is recommended to call this method with a commitment level of Finalized

  • storage_account_key - The public key of the StorageAccount to be migrated.
Example
let migrate_response = shdw_drive_client
    .migrate(&storage_account_key)
    .await?;

First transaction step that migrates a v1 StorageAccount to v2. Consists of copying the existing account’s data into an intermediate account, and deleting the v1 storage account

Examples found in repository?
src/client/migrate.rs (line 48)
44
45
46
47
48
49
50
51
    pub async fn migrate(
        &self,
        storage_account_key: &Pubkey,
    ) -> ShadowDriveResult<(ShdwDriveResponse, ShdwDriveResponse)> {
        let step_1_response = self.migrate_step_1(storage_account_key).await?;
        let step_2_response = self.migrate_step_2(storage_account_key).await?;
        Ok((step_1_response, step_2_response))
    }

Second transaction step that migrates a v1 StorageAccount to v2. Consists of recreating the storage account using the original pubkey, and deleting the intermediate account

Examples found in repository?
src/client/migrate.rs (line 49)
44
45
46
47
48
49
50
51
    pub async fn migrate(
        &self,
        storage_account_key: &Pubkey,
    ) -> ShadowDriveResult<(ShdwDriveResponse, ShdwDriveResponse)> {
        let step_1_response = self.migrate_step_1(storage_account_key).await?;
        let step_2_response = self.migrate_step_2(storage_account_key).await?;
        Ok((step_1_response, step_2_response))
    }

Reclaims the Solana rent from any on-chain file accounts. Older versions of the Shadow Drive used to create accounts for uploaded files.

  • storage_account_key - The public key of the StorageAccount that contained the deleted file.
  • file_account_key - The public key of the File account to be closed.
Example
let redeem_rent_response = shdw_drive_client
    .redeem_rent(&storage_account_key, &file_account_key)
    .await?;

Reduces the amount of total storage available for the given storage account.

  • storage_account_key - The public key of the StorageAccount whose storage will be reduced.
  • size - The amount of storage you want to remove. E.g if you have an existing StorageAccount with 3MB of storage but you want 2MB total, size should equal 1MB. When specifying size, only KB, MB, and GB storage units are currently supported.
Example
let reduce_storage_response = shdw_drive_client
    .reduce_storage(&storage_account_key, reduced_bytes)
    .await?;

Creates a new ShadowDriveClient from the given Signer and URL.

  • wallet - A Signer that for signs all transactions generated by the client. Typically this is a user’s keypair.
  • rpc_url - An HTTP URL of a Solana RPC provider.

The underlying Solana RPC client is configured with 120s timeout and a commitment level of Finalized.

To customize RpcClient settings see new_with_rpc.

Example
use solana_sdk::signer::keypair::Keypair;    

let wallet = Keypair::generate();
let shdw_drive = ShadowDriveClient::new(wallet, "https://ssc-dao.genesysgo.net");

Creates a new ShadowDriveClient from the given Signer and RpcClient.

  • wallet - A Signer that for signs all transactions generated by the client. Typically this is a user’s keypair.
  • rpc_client - A Solana RpcClient that handles sending transactions and reading accounts from the blockchain.

Providng the RpcClient allows customization of timeout and committment level.

Example
use solana_client::rpc_client::RpcClient;
use solana_sdk::signer::keypair::Keypair;    
use solana_sdk::commitment_config::CommitmentConfig;

let wallet = Keypair::generate();
let solana_rpc = RpcClient::new_with_commitment("https://ssc-dao.genesysgo.net", CommitmentConfig::confirmed());
let shdw_drive = ShadowDriveClient::new_with_rpc(wallet, solana_rpc);

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Instruments this type with the current Span, returning an Instrumented wrapper. Read more

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
Should always be Self
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.
Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more