Solana Kit

useStorageAccount

React hook for Shelby storage account operations

The useStorageAccount hook provides a convenient way to interact with Shelby storage from React applications using a connected Solana wallet.

Overview

This hook:

  • Derives a Shelby storage account address from the connected Solana wallet
  • Provides functions to sign and submit transactions to Shelby
  • Handles the SIWS (Sign-In With Solana) authentication flow automatically

Import

import { useStorageAccount } from "@shelby-protocol/solana-kit/react";

Parameters

interface UseStorageAccountParams {
  /** The Shelby client instance */
  client: ShelbyClient;
  /** The connected Solana wallet address (base58 string) */
  solanaAddress?: string;
  /** Function to sign messages with the Solana wallet */
  signMessageFn?: (message: Uint8Array) => Promise<Uint8Array>;
}
ParameterTypeRequiredDescription
clientShelbyClientYesThe Shelby client instance
solanaAddressstringNoConnected wallet address (base58)
signMessageFn(message: Uint8Array) => Promise<Uint8Array>NoWallet's signMessage function

Return Value

interface UseStorageAccountResult {
  /** The derived Shelby storage account address */
  storageAccountAddress: AccountAddress | null;
  /** Sign a transaction for Shelby */
  signTransaction: (params: SignTransactionInput) => Promise<{
    authenticator: AccountAuthenticatorAbstraction;
    rawTransaction: AnyRawTransaction;
  }>;
  /** Submit a signed transaction to Shelby */
  submitTransaction: (
    params: SubmitTransactionInput
  ) => Promise<{ hash: string }>;
  /** Sign and submit a transaction in one call */
  signAndSubmitTransaction: (
    params: SignAndSubmitTransactionInput
  ) => Promise<{ hash: string }>;
}
PropertyTypeDescription
storageAccountAddressAccountAddress | nullThe derived storage account address
signTransactionfunctionSigns a transaction (returns authenticator)
submitTransactionfunctionSubmits a pre-signed transaction
signAndSubmitTransactionfunctionSigns and submits in one operation

Basic Usage

"use client";

import { useStorageAccount, Network } from "@shelby-protocol/solana-kit/react";
import { ShelbyClient } from "@shelby-protocol/sdk/browser";
import { useWallet } from "@solana/wallet-adapter-react";
import { useMemo } from "react";

function StorageComponent() {
  const { publicKey, signMessage } = useWallet();

  // Create client (memoize to prevent recreation)
  const shelbyClient = useMemo(
    () =>
      new ShelbyClient({
        network: Network.SHELBYNET,
        apiKey: process.env.NEXT_PUBLIC_SHELBY_API_KEY!,
      }),
    []
  );

  const { storageAccountAddress, signAndSubmitTransaction } = useStorageAccount(
    {
      client: shelbyClient,
      solanaAddress: publicKey?.toBase58(),
      signMessageFn: signMessage,
    }
  );

  if (!publicKey) {
    return <p>Please connect your wallet</p>;
  }

  return (
    <div>
      <p>Solana Address: {publicKey.toBase58()}</p>
      <p>Shelby Storage: {storageAccountAddress?.toString()}</p>
    </div>
  );
}

Domain Derivation

The storage account address is derived from:

  1. The connected Solana wallet's public key
  2. The current domain (window.location.host)

The same Solana wallet will have different storage account addresses on different domains. This provides application-level isolation.

// On app1.com
const { storageAccountAddress } = useStorageAccount({...});
// storageAccountAddress = "0x1111..."

// On app2.com (same wallet)
const { storageAccountAddress } = useStorageAccount({...});
// storageAccountAddress = "0x2222..."