storacha-sol
Version:
Crypto-native payments for storage on Storacha with SOL. No credit card needed.
245 lines (238 loc) • 8.52 kB
TypeScript
import { Address, Signature } from '@solana/kit';
import { PublicKey, Connection, Transaction } from '@solana/web3.js';
interface ServerOptions {
/** URL pointing to the backend (mostly Storacha's) */
url?: string;
}
/**
* Options needed to create an on-chain deposit for storage
*/
interface UploadOptions {
/** content identifier for the data to be uploaded */
cid: string;
/** file/upload size in bytes */
size: number;
/** duration in days for how long the data should be retained */
duration: number;
/** wallet responsible for paying the deposit */
payer: Address;
/** optional Solana connection override (for testing or custom RPC) */
connection?: any;
/** Signature or transaction hash as proof of on-chain deposit */
signature?: string;
}
/**
* Result returned after a successful file upload
*/
interface UploadResult {
/** message from the deposit transaction. could be an error or success message */
message?: string;
/** similar to message above but for error cases. can extrapoloate this later */
error?: string;
/** signature of the succesful transaction */
signature: Signature;
/** status of the request. successful or not. */
success: boolean;
/** CID of the uploaded content */
cid: string;
/** full URL where the content was uploaded to (on IPFS) */
url: string;
/** information of the file that was uploaded */
fileInfo?: {
/** file type */
type: string;
/** size of the uploaded content (in bytes) */
size: number;
/** UNIX timestamp (in seconds) of the time the file was uploaded */
uploadedAt: string;
/** name of the file uploaded */
filename: string;
};
}
/**
* Stored item entry returned when listing wallet space
*/
interface WalletItem {
/** CID of the stored item */
cid: string;
/** file size in bytes */
size: number;
/** expiration timestamp in seconds */
expiresAt: number;
}
/**
* Config values fetched from the on-chain ConfigAccount
*/
interface OnChainConfig {
/** current rate in lamports per byte per day */
ratePerBytePerDay: bigint;
/** minimum required duration in days */
minDurationDays: number;
/** wallet where provider can withdraw claimed funds */
withdrawalWallet: Address;
}
/**
* Deposit details stored on-chain for each user upload
*/
interface OnChainDeposit {
/** public key of the depositor */
depositor: Address;
/** file object containing metadata about the upload */
file: File;
/** storage duration (days) */
duration: number;
/** amount deposited in lamports */
depositAmount: bigint;
/** slot when deposit was made */
depositSlot: number;
/** last claimed slot for reward release */
lastClaimedSlot: number;
}
interface DepositResult extends Pick<UploadResult, 'message' | 'error'> {
/** CID of the stored item */
cid: string;
/** transaction instruction */
instructions: Array<{
programId: string;
keys: Array<{
pubkey: string;
isSigner: boolean;
isWritable: boolean;
}>;
data: string;
}>;
/** result of a successful upload */
object: UploadResult;
}
interface CreateDepositArgs extends Omit<OnChainDeposit, 'depositAmount' | 'depositor' | 'depositSlot' | 'lastClaimedSlot'> {
/** Public key of the user paying for the upload */
payer: PublicKey;
/** Wallet connection used to query chain state or recent blockhash */
connection: Connection;
/**
* a callback function to authorize the transaction via the solana wallet lib
* @example
* const {publickKey, signTransaction} = useSolanaWallet()
* const signTransaction = await signTransaction(tx)
* */
signTransaction: (tx: Transaction) => Promise<Transaction>;
}
/**
* Individual deposit history entry from the backend
*/
interface DepositHistoryEntry {
/** Unique identifier for the deposit */
id: number;
/** User's wallet address (deposit key) */
deposit_key: string;
/** Content identifier of the uploaded file */
content_cid: string;
/** Duration in days the file is stored for */
duration_days: number;
/** Amount deposited in lamports */
deposit_amount: number;
/** Slot when the deposit was made */
deposit_slot: number;
/** Last slot when rewards were claimed */
last_claimed_slot: number;
/** Timestamp when the deposit was created */
created_at: string;
}
/**
* Response from the getUserUploadHistory endpoint
*/
interface DepositHistoryResponse {
/** Array of deposit history entries */
userHistory: DepositHistoryEntry[] | null;
/** The user address that was queried */
userAddress: string;
}
declare enum Environment {
mainnet = "mainnet-beta",
testnet = "testnet",
devnet = "devnet"
}
declare function getRpcUrl(env: Environment): string;
interface ClientOptions {
/** Solana RPC endpoint to use for chain interactions */
environment: Environment;
}
interface DepositParams extends Pick<CreateDepositArgs, 'signTransaction'> {
/** Wallet public key of the payer */
payer: PublicKey;
/** File to be stored */
file: File;
/** Duration in days to store the data */
durationDays: number;
}
/**
* Solana Storage Client — simplified (no fee estimation)
*/
declare class Client {
private rpcUrl;
constructor(options: ClientOptions);
/**
* Creates a deposit transaction ready to be signed & sent by user's wallet.
*
* @param {Object} params
* @param {PublicKey} params.payer - The public key (wallet address) of the connected wallet.
* @param {File} params.file - The file to be uploaded.
* @param {number} params.durationDays - How long (in days) the file should be stored.
* @param {(tx: Transaction) => Promise<Transaction>} params.signTransaction -
* A callback function to authorize the transaction via the Solana wallet library.
*
* @example
* const { publicKey, signTransaction } = useSolanaWallet();
* const result = await createDeposit({
* payer: publicKey,
* file,
* durationDays: 30,
* signTransaction,
* });
*
* @returns {Promise<UploadResult>} The upload result after transaction is processed.
*/
createDeposit({ payer, file, durationDays, signTransaction, }: DepositParams): Promise<UploadResult>;
/**
* estimates the cost for a file based on the amount of days it should be stored for
* @param {File} file - a file to be uploaded
* @param {number} duration - how long (in seconds) the file should be stored for
*/
estimateStorageCost: (file: File, duration: number) => {
sol: number;
lamports: number;
};
getUserUploadHistory(userAddress: string): Promise<DepositHistoryResponse>;
}
/**
* Calls the deposit API for on-chain storage and returns a Transaction
* which must be signed and sent externally by the user.
*
* @param params - {
* cid: string;
* file: File;
* duration: number;
* payer: PublicKey;
* connection: Connection;
* }
* @returns Transaction
*/
declare function createDepositTxn({ file, duration, payer, connection, signTransaction, }: CreateDepositArgs): Promise<UploadResult>;
declare const useDeposit: (environment: ClientOptions["environment"]) => Client;
/**
* Fetches the deposit history for a given user address from the backend
*
* @param userAddress - The wallet address of the user to fetch deposit history for
* @param options - Optional server configuration
* @returns Promise<DepositHistoryResponse> - The user's deposit history
*
* @example
* ```typescript
* const history = await fetchUserDepositHistory('9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM');
* console.log('User deposit history:', history.userHistory);
* ```
*
* @throws {Error} When the user address is invalid or the request fails
*/
declare function fetchUserDepositHistory(userAddress: string, options?: ServerOptions): Promise<DepositHistoryResponse>;
export { Client, type ClientOptions, type CreateDepositArgs, type DepositHistoryEntry, type DepositHistoryResponse, type DepositParams, type DepositResult, Environment, type OnChainConfig, type OnChainDeposit, type ServerOptions, type UploadOptions, type UploadResult, type WalletItem, createDepositTxn, fetchUserDepositHistory, getRpcUrl, useDeposit };