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 */
  wallet: SolanaWallet | null;
}
ParameterTypeRequiredDescription
clientShelbyClientYesThe Shelby client instance
walletSolanaWallet | nullYesThe connected Solana wallet

SolanaWallet Interface

The SolanaWallet interface is compatible with @solana/react-hooks:

interface SolanaWallet {
  account: {
    address: { toString(): string };
  };
  signMessage?: (message: Uint8Array) => Promise<Uint8Array>;
  signIn?: (input: SolanaSignInInput) => Promise<SolanaSignInOutput>;
}

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 { useWalletConnection } from "@solana/react-hooks";
import { useMemo } from "react";

function StorageComponent() {
  const { wallet } = useWalletConnection();

  // 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,
    wallet: wallet,
  });

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

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

Using with @solana/wallet-adapter-react

If you're using @solana/wallet-adapter-react, adapt the wallet to the expected shape:

import { useWallet } from "@solana/wallet-adapter-react";

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

  const { storageAccountAddress } = useStorageAccount({
    client: shelbyClient,
    wallet: publicKey
      ? {
          account: { address: publicKey },
          signMessage,
          signIn,
        }
      : null,
  });

  // ...
}

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..."