Use the Solana docs and examples here if you need help. We're going to focus on ShdwDrive SDK in these docs, so if you need a primer on how to build a React site with Solana, we can refer you to other resources.
Building components for various ShdwDrive operations
Let's start by instantiating the ShdwDrive connection class object. This will have all ShdwDrive methods and it implements the signing wallet within the class for all transactions.
At the simplest level, it is recommend for a React app to immediately try to load a connection to a user's ShdwDrives upon wallet connection. This can be done with the useEffect React hook.
This implementation is effectively the same for both Web and Node implementations. There are three params that are required to create a storage account:
name: a friendly name for your storage account
size: The size of your storage accounts with a human readable ending containing KB, MB, or GB
version: can be either v1 or v2. Note - v1 is completely deprecated and you shuold only use v2 moving forward.
This implementation is effectively the same for both Web and Node implementations. The only parameter required is either v1 or v2 for the version of storage account you created in the previous step.
constaccts=awaitdrive.getStorageAccounts("v2");// handle printing pubKey of first storage acctlet acctPubKey =newanchor.web3.PublicKey(accts[0].publicKey);console.log(acctPubKey.toBase58());
This implementation is effectively the same for both Web and Node implementations. The only parameter required is either a PublicKey object or a base-58 string of the public key.
key: A PublicKey object representing the public key of the Shdw Storage Account
data: A file of either the File object type or ShadowFile object type
Check the intellisense popup below when hovering over the method
File objects are implemented in web browsers, and ShadowFile is a custom type we implemented in TypeScript. So either you are using File in the web, or you are scripting in TS.
This is a nearly identical implementation to uploadFile, except that it requires a FileList or array of ShadowFiles and an optional concurrency parameter.
Recall that the default setting is to attempt to upload 3 files concurrently. Here you can override this and specify how many files you want to try to upload based on the cores and bandwith of your infrastructure.
Delete a File
The implementation of deleteFile is the same between web and Node. There are three required parameters to delete a file:
This is a method to decrease the storage limit of a storage account. This implementation only requires three params - the storage account key, the amount to reduce it by, and the version.
As the name implies, you can delete a storage account and all of its files. The storage account can still be recovered until the current epoch ends, but after that, it will be removed. This implementation only requires two params - a storage account key and a version.
You can still get your storage account back if the current epoch hasn't elapsed. This implementation only requires two params - an account public key and a version.
This method is used to create a new instance of the ShdwDrive class. It accepts a web3 connection object and a web3 wallet. It returns an instance of the ShdwDrive class.
// Javascript SDK example using the constructor method// this creates a new instance of the ShadowDrive class and initializes it with the given connection and wallet parameters
constshadowDrive=newShadowDrive(connection, wallet).init();
addStorage
Definition
addStorage is a method of the ShadowDrive class defined in index.ts at line 121. It takes three parameters: key, size, and version and returns a Promise<ShadowDriveResponse> with the confirmed transaction ID.
Parameters
key: PublicKey - Public Key of the existing storage to increase size on
size: string - Amount of storage you are requesting to add to your storage account. Should be in a string like '1KB', '1MB', '1GB'. Only KB, MB, and GB storage delineations are supported currently.
version: ShadowDriveVersion - ShadowDrive version (v1 or v2)
// Javascript SDK example using the addStorage method// This line retrieves the storage accounts with version "v2" using the `getStorageAccounts` method of the `drive` object and stores them in the `accts` variable.
constaccts=awaitdrive.getStorageAccounts("v2")// This line creates a new `PublicKey` object using the public key of the second storage account retrieved in the previous line and stores it in the `acctPubKey` variable.
let acctPubKey =newanchor.web3.PublicKey(accts[1].publicKey)// This line adds a new storage allocation of size "10MB" and version "v2" to the storage account identified by the public key in `acctPubKey`. The response is stored in the `addStgResp` variable.
constaddStgResp=awaitdrive.addStorage(acctPubKey,"10MB","v2"ca
cancelDeleteStorageAccount
Definition
Implementation of cancelDeleteStorageAccount defined in index.ts:135 This method is used to cancel a delete request for a Storage Account on ShdwDrive. It accepts a Public Key of the Storage Account and the ShdwDrive version (v1 or v2). It returns a Promise<{ txid: string }> containing the confirmed transaction ID of the undelete request.
// Javascript SDK example using the cancelDeleteStorageAccount method// Create a new public key object from a string representation of a Solana account public keyconstacctPubKey=newanchor.web3.PublicKey("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Call the "cancelDeleteStorageAccount" function of the ShdwDrive API, passing in the account public key object and a string indicating the storage account version to cancel deletion for
constcancelDelStg=awaitdrive.cancelDeleteStorageAccount(acctPubKey,"v2");
claimStake
Definition
This method is used to request a Stake on ShdwDrive. It accepts a PublicKey of the Storage Account and the ShdwDrive version (v1 or v2). It returns a Promise<{ txid: string }> containing the confirmed transaction ID of the claimStake request.
// Javascript SDK example using the claimStake method// Create a new public key object with the specified valueconstacctPubKey=newanchor.web3.PublicKey("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Call the 'claimStake' function on the 'drive' object with the account public key and 'v2' as parameters, and wait for its completion before proceeding
constclaimStake=awaitdrive.claimStake(acctPubKey,"v2");
createStorageAccount
Definition
Implementation of ShdwDrive.createStorageAccount defined in index.ts:120 This method is used to create a new Storage Account on ShdwDrive. It accepts the name of the Storage Account, the size of the requested Storage Account, and the ShdwDrive version (v1 or v2). It also accepts an optional secondary owner for the Storage Account. It returns a Promise containing the created Storage Account and the transaction signature.
Parameters
name: string - What you want your storage account to be named. (Does not have to be unique)
size: string - Amount of storage you are requesting to create. Should be in a string like '1KB', '1MB', '1GB'. Only KB, MB, and GB storage delineations are supported currently.
version: ShadowDriveVersion - ShdwDrive version(v1 or v2)
owner2 (optional): PublicKey - Optional secondary owner for the storage account.
// Javascript SDK example using the createStorageAccount method// Calls the 'createStorageAccount' function on the 'drive' object with "myDemoBucket", "10MB", and "v2" as parameters, and waits for its completion before proceeding. The result of the function call is assigned to the 'newAcct' variable.
constnewAcct=awaitdrive.createStorageAccount("myDemoBucket","10MB","v2");// Logs the value of the 'newAcct' variable to the consoleconsole.log(newAcct);
deleteFile
Definition
This method is used to delete a file on ShdwDrive. It accepts a Public Key of your Storage Account, the ShdwDrive URL of the file you are requesting to delete and the ShdwDrive version (v1 or v2). It returns a Promise containing the confirmed transaction ID of the delete request.
Parameters
key: PublicKey - Publickey of Storage Account
url: string - ShdwDrive URL of the file you are requesting to delete.
version: `ShdwDrive
Version` - ShdwDrive version (v1 or v2)
Returns
{"message": String,"error": String or not passed if no error}
// Javascript SDK example using the deleteFile method// Assigns a string value containing the URL of the file to be deleted to the 'url' variableconsturl="https://shdw-drive.genesysgo.net/4HUkENqjnTAZaUR4QLwff1BvQPCiYkNmu5PPSKGoKf9G/fape.png";// Creates a new public key object with a specific value and assigns it to the 'acctPubKey' variableconstacctPubKey=newanchor.web3.PublicKey("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Calls the 'deleteFile' function on the 'drive' object with the account public key, URL, and "v2" as parameters, and waits for its completion before proceeding. The result of the function call is assigned to the 'delFile' variable.
constdelFile=awaitdrive.deleteFile(acctPubKey, url,"v2");// Logs the value of the 'delFile' variable to the consoleconsole.log(delFile);
deleteStorageAccount
Definition
Implementation of ShadowDrive.deleteStorageAccount defined in index.ts:124 This method is used to delete a Storage Account on ShdwDrive. It accepts a Public Key of the Storage Account and the ShdwDrive version (v1 or v2). It returns a Promise<{ txid: string }> containing the confirmed transaction ID of the delete request.
Parameters
key: PublicKey - Publickey of a Storage Account
version: ShadowDriveVersion - ShdwDrive version (v1 or v2)
// Javascript SDK example using the deleteStorageAccount method// Creates a new public key object with a specific value and assigns it to the 'acctPubKey' variableconstacctPubKey=newanchor.web3.PublicKey("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Calls the 'deleteStorageAccount' function on the 'drive' object with the account public key and "v2" as parameters, and waits for its completion before proceeding. The result of the function call is assigned to the 'delAcct' variable.
constdelAcct=awaitdrive.deleteStorageAccount(acctPubKey,"v2");
editFile
Definition
This method is used to edit a file on ShdwDrive. It accepts a Public Key of your Storage Account, the URL of the existing file, the File or ShadowFile object, and the ShdwDrive version (v1 or v2). It returns a Promise containing the file location and the transaction signature.
Parameters
key: PublicKey - Publickey of Storage Account
url: string - URL of existing file
data: File | ShadowFile - File or ShadowFile object, file extensions should be included in the name property of ShadowFiles.
version: ShadowDriveVersion - ShdwDrive version (v1 or v2)
// Javascript SDK example using the editFile method// Creates an object containing the name and content of the file to upload and assigns it to the 'fileToUpload' variable
constfileToUpload:ShadowFile= { name:"mytext.txt", file: fileBuff,};// Assigns a string value containing the URL of the file to be edited to the 'url' variableconsturl="https://shdw-drive.genesysgo.net/4HUkENqjnTAZaUR4QLwff1BvQPCiYkNmu5PPSKGoKf9G/fape.png";// Creates a new public key object with a specific value and assigns it to the 'acctPubKey' variableconstacctPubKey=newanchor.web3.PublicKey("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Calls the 'editFile' function on the 'drive' object with the account public key, URL, "v2", and the file object as parameters, and waits for its completion before proceeding. The result of the function call is assigned to the 'editFile' variable.
consteditFile=awaitdrive.editFile(acctPubKey, url,"v2", fileToUpload);
getStorageAccount
Definition
This method is used to get the details of a Storage Account on ShdwDrive. It accepts a Public Key of the Storage Account and returns a Promise containing the Storage Account details.
// Javascript SDK example using the getStorageAccount method// Calls the 'getStorageAccount' function on the 'drive' object with the account public key as a parameter, and waits for its completion before proceeding. The result of the function call is assigned to the 'acct' variable.
constacct=awaitdrive.getStorageAccount("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Logs the resulting object to the consoleconsole.log(acct);
getStorageAccounts
Definition
This method is used to get a list of all the Storage Accounts associated with the current user. It accepts a ShdwDrive version (v1 or v2). It returns a Promise<StorageAccountResponse[]> containing the list of storage accounts.
Parameters
version: ShadowDriveVersion - ShdwDrive version (v1 or v2)
// Javascript SDK example using the getStorageAccounts method// Calls the 'getStorageAccounts' function on the 'drive' object with the version parameter "v2", and waits for its completion before proceeding. The result of the function call is assigned to the 'accts' variable.
constaccts=awaitdrive.getStorageAccounts("v2");// Uses the 'let' keyword to declare a variable 'acctPubKey', which is assigned the value of the publicKey of the first object in the 'accts' array. This value is converted to a string in Base58 format.
let acctPubKey =newanchor.web3.PublicKey(accts[0].publicKey);console.log(acctPubKey.toBase58());
listObjects
Definition
This method is used to list the Objects in a Storage Account on ShdwDrive. It accepts a Public Key of the Storage Account and returns a Promise containing the list of Objects in the Storage Account.
// Javascript SDK example using the listObjects method// Creates a new 'PublicKey' object using a specific public key string and assigns it to the 'acctPubKey' variable.constacctPubKey=newanchor.web3.PublicKey("EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN");// Calls the 'listObjects' function on the 'drive' object with the 'acctPubKey' variable as a parameter, and waits for its completion before proceeding. The result of the function call is assigned to the 'listItems' variable.
constlistItems=awaitdrive.listObjects(acctPubKey);// Logs the resulting object to the console.console.log(listItems);
makeStorageImmutable
Definition
This method is used to make a Storage Account immutable on ShdwDrive. It accepts a Public Key of the Storage Account and the ShdwDrive version (v1 or v2). It returns a Promise containing the confirmed transaction ID of the makeStorageImmutable request.
Parameters
key: PublicKey - Publickey of Storage Account
version: ShadowDriveVersion - ShdwDrive version (v1 or v2)
const key = new anchor.web3.PublicKey(
"EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN"
);
const result = await drive.makeStorageImmutable(key, "v2");
console.log(result);
// Javascript SDK example using the makeStorageImmutable method
// Create a new PublicKey object using a public key string.
const key = new anchor.web3.PublicKey(
"EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN"
);
// Call the makeStorageImmutable function with the PublicKey object and a version string, and wait for it to complete.
const result = await drive.makeStorageImmutable(key, "v2");
// Log the resulting object to the console.
console.log(result);
migrate
Definition
This method is used to migrate a Storage Account on ShdwDrive. It accepts a PublicKey of the Storage Account. It returns a Promise<{ txid: string }> containing the confirmed transaction ID of the migration request.
Parameters
key: PublicKey - Publickey of Storage Account
Returns
Confirmed transaction ID
const result = await drive.migrate(key);
// Javascript SDK example using the migrate method
// Call the migrate function on the drive object, passing in the PublicKey object as a parameter.
const result = await drive.migrate(key);
redeemRent
Definition
This method is used to redeem Rent on ShdwDrive. It accepts a Public Key of the Storage Account and the Public Key of the file account to close. It returns a Promise<{ txid: string }> containing the confirmed transaction ID of the redeemRent request.
Parameters
key: PublicKey - Publickey of Storage Account
fileAccount: PublicKey - PublicKey of the file account to close
Returns
Confirmed transaction ID
const fileAccount = new anchor.web3.PublicKey(
"3p6U9s1sGLpnpkMMwW8o4hr4RhQaQFV7MkyLuW8ycvG9"
);
const result = await drive.redeemRent(key, fileAccount);
// Javascript SDK example using the redeemRent method
// Create a new PublicKey object using a public key string for the file account.
const fileAccount = new anchor.web3.PublicKey(
"3p6U9s1sGLpnpkMMwW8o4hr4RhQaQFV7MkyLuW8ycvG9"
);
// Call the redeemRent function on the drive object, passing in both PublicKey objects as parameters.
const result = await drive.redeemRent(key, fileAccount);
reduceStorage
Definition
This method is used to reduce the storage of a Storage Account on ShdwDrive. It accepts a Public Key of the Storage Account, the amount of storage you are requesting to reduce from your storage account, and the ShdwDrive version (v1 or v2). It returns a Promise containing the confirmed transaction ID of the reduce storage request.
Parameters
key: PublicKey - Publickey of Storage Account
size: string - Amount of storage you are requesting to reduce from your storage account. Should be in a string like '1KB', '1MB', '1GB'. Only KB, MB, and GB storage delineations are supported currently.
version: ShadowDriveVersion - ShdwDrive version (v1 or v2)
// Javascript SDK example using the reduceStorage method
// Create a new public key object with the given string
const acctPubKey = new anchor.web3.PublicKey(
"EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN"
);
// Reduce the storage size of the storage account with the given public key
// to 10MB using the version specified
const shrinkAcct = await drive.reduceStorage(acctPubKey, "10MB", "v2");
storageConfigPDA
Definition
This exposes the PDA account in case developers have a need to display / use the data stored in the account.
Parameters
key: PublicKey - Publickey of Storage Account
data: File | ShadowFile - File or ShadowFile object, file extensions should be included in the name property of ShadowFiles.
Returns
Public Key
storageConfigPDA: PublicKey;
//storageConfigPDA is a method in the Shdw SDK that returns the public key of the program derived account (PDA) for the Shdw storage program's config. A program derived account is a special account on the Solana blockchain that is derived from a program's public key and a specific seed. The purpose of this method is to provide a convenient way to obtain the PDA for the Shdw storage program's config. The config contains important information such as the current storage rent exemption threshold and the data size limits for storage accounts. This public key can be used to interact with the Shdw storage program's config account, allowing the user to retrieve and modify the program's global configuration settings.
storageConfigPDA: PublicKey;
refreshStake
Definition
This method is used to update your storage account's stake amount. It is required to call this method after calling the `topUp` method in order for your stage account to update properly.
Parameters
key: PublicKey - Publickey of the Storage Account
version: can be either v1 or v2. Note - v1 is completely deprecated and you shuold only use v2 moving forward.
Returns
{
txid: string
}
topUp
Definition
This method is used to top up a storage account's $SHDW balance to cover any necessary fees, like mutable storage fees which are collected every epoch. It is necessary to call the `refreshStake` method after this.
Parameters
key: PublicKey - Publickey of the Storage Account
amount: Number - Amount of $SHDW to transfer to the stake account
Returns
{
txid: string;
}
uploadFile
Definition
This method is used to upload a file to ShdwDrive. It accepts a Public Key of your Storage Account and a File or ShadowFile object. The file extensions should be included in the name property of ShadowFiles. It returns a Promise containing the file location and the transaction signature.
Parameters
key: PublicKey - Publickey of Storage Account.
data: File | ShadowFile - File or ShadowFile object, file extensions should be included in the name property of ShadowFiles.
// Javascript SDK example of the uploadFile method
// This line calls the uploadFile method of the drive object and passes in two parameters:
// 1. acctPubKey: A PublicKey object representing the public key of the storage account where the file will be uploaded.
// 2. fileToUpload: A ShadowFile object containing the file name and file buffer to be uploaded.
const uploadFile = await drive.uploadFile(acctPubKey, fileToUpload);
uploadMultipleFiles
Definition
This method is used to upload multiple files to a Storage Account on ShdwDrive. It accepts the Storage Account's PublicKey, a data object containing the FileList or ShadowFile array of files to upload, an optional concurrent number for the number of files to concurrently upload, and an optional callback function for every batch of files uploaded. It returns a Promise<ShadowBatchUploadResponse[]> containing the file names, locations and transaction signatures for uploaded files.
Parameters
key: PublicKey - Storage account PublicKey to upload the files to.
data: FileList | ShadowFile[] -
concurrent (optional): number - Number of files to concurrently upload. Default: 3
callback (optional): Function - Callback function for every batch of files uploaded. A number will be passed into the callback like callback(num) indicating the number of files that were confirmed in that specific batch.
// Javascript SDK example of the uploadMultipleFiles method
// Create an instance of the ShdwDrive client
const drive = new ShadowDrive();
// Define the public key of the storage account where the files will be uploaded
const acctPubKey = new anchor.web3.PublicKey(
"EY8ZktbRmecPLfopBxJfNBGUPT1LMqZmDFVcWeMTGPcN"
);
// Define an array of files to upload
const files = [
{
name: "file1.txt",
file: new File(["hello"], "file1.txt"),
},
{
name: "file2.txt",
file: new File(["world"], "file2.txt"),
},
{
name: "file3.txt",
file: new File(["!"], "file3.txt"),
},
];
// Define the maximum number of concurrent uploads (optional)
const concurrentUploads = 2;
// Define a callback function to be called after each file is uploaded (optional)
const callback = (response) => {
console.log(`Uploaded file ${response.fileIndex}: ${response.fileName}`);
};
// Call the uploadMultipleFiles method to upload all the files
const responses = await drive.uploadMultipleFiles(
acctPubKey,
files,
concurrentUploads,
callback
);
// Print the responses returned by the server for each file uploaded
console.log(responses);
userInfo
Definition
userInfo: PublicKey
Example - Using POST API requests via the Javascript SDK to make an account immutable with solana transaction signing
// Import required modules and constants
import * as anchor from "@project-serum/anchor";
import { getStakeAccount, findAssociatedTokenAddress } from "../utils/helpers";
import {
emissions,
isBrowser,
SHDW_DRIVE_ENDPOINT,
tokenMint,
uploader,
} from "../utils/common";
import {
ASSOCIATED_TOKEN_PROGRAM_ID,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
import { ShadowDriveVersion, ShadowDriveResponse } from "../types";
import fetch from "node-fetch";
/**
*
* @param {anchor.web3.PublicKey} key - Publickey of a Storage Account
* @param {ShadowDriveVersion} version - ShadowDrive version (v1 or v2)
* @returns {ShadowDriveResponse} - Confirmed transaction ID
*/
export default async function makeStorageImmutable(
key: anchor.web3.PublicKey,
version: ShadowDriveVersion
): Promise<ShadowDriveResponse> {
let selectedAccount;
// Fetch the selected account based on the version
try {
switch (version.toLocaleLowerCase()) {
case "v1":
selectedAccount = await this.program.account.storageAccount.fetch(key);
break;
case "v2":
selectedAccount = await this.program.account.storageAccountV2.fetch(
key
);
break;
}
// Find associated token addresses
const ownerAta = await findAssociatedTokenAddress(
selectedAccount.owner1,
tokenMint
);
const emissionsAta = await findAssociatedTokenAddress(emissions, tokenMint);
// Get stake account
let stakeAccount = (await getStakeAccount(this.program, key))[0];
let txn;
// Create transaction based on the version
switch (version.toLocaleLowerCase()) {
case "v1":
txn = await this.program.methods
.makeAccountImmutable()
.accounts({
storageConfig: this.storageConfigPDA,
storageAccount: key,
stakeAccount,
emissionsWallet: emissionsAta,
owner: selectedAccount.owner1,
uploader: uploader,
ownerAta,
tokenMint: tokenMint,
systemProgram: anchor.web3.SystemProgram.programId,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
})
.transaction();
case "v2":
txn = await this.program.methods
.makeAccountImmutable2()
.accounts({
storageConfig: this.storageConfigPDA,
storageAccount: key,
owner: selectedAccount.owner1,
ownerAta,
stakeAccount,
uploader: uploader,
emissionsWallet: emissionsAta,
tokenMint: tokenMint,
systemProgram: anchor.web3.SystemProgram.programId,
tokenProgram: TOKEN_PROGRAM_ID,
associatedTokenProgram: ASSOCIATED_TOKEN_PROGRAM_ID,
rent: anchor.web3.SYSVAR_RENT_PUBKEY,
})
.transaction();
break;
}
// Set recent blockhash and fee payer
txn.recentBlockhash = (
await this.connection.getLatestBlockhash()
).blockhash;
txn.feePayer = this.wallet.publicKey;
let signedTx;
let serializedTxn;
// Sign and serialize the transaction
if (!isBrowser) {
await txn.partialSign(this.wallet.payer);
serializedTxn = txn.serialize({ requireAllSignatures: false });
} else {
signedTx = await this.wallet.signTransaction(txn);
serializedTxn = signedTx.serialize({ requireAllSignatures: false });
}
// Send the transaction to the server
const makeImmutableResponse = await fetch(
`${SHDW_DRIVE_ENDPOINT}/make-immutable`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
transaction: Buffer.from(serializedTxn.toJSON().data).toString(
"base64"
),
}),
}
);
// Handle server response
if (!makeImmutableResponse.ok) {
return Promise.reject(
new Error(`Server response status code: ${
makeImmutableResponse.status
} \n
Server response status message: ${(await makeImmutableResponse.json()).error}`)
);
}
// Return the response JSON
const responseJson = await makeImmutableResponse.json();
return Promise.resolve(responseJson);
} catch (e) {
return Promise.reject(new Error(e));
}
}