Skip to content

Get Started with the StorageHub SDK

The StorageHub SDK is a modular toolkit that makes it easy to build on DataHaven, giving developers direct access to functionalities for managing storage, buckets, and proofs. It simplifies both on-chain and off-chain interactions so you can focus on your application logic rather than low-level integrations.

This guide introduces and compares the functionalities of the StorageHub SDK packages. You can use the StorageHub SDK for every step in the storage request and retrieval process. For more information, see the Workflow Overview.

Workflow Overview

A high-level look at how data moves through DataHaven, from storage requests to upload, verification, and retrieval.

Get Started with StorageHub SDK

Set up your development environment, install the StorageHub SDK, and prepare your project to start interacting with the DataHaven network.

Create a Bucket

Connect your wallet or app identity, select a Main Storage Provider (MSP), and create or reuse a bucket.

Authenticate with SIWE and JWT

Use Sign-In with Ethereum (SIWE) and JSON Web Tokens (JWT) for secure authentication.

Upload a File

Issue a Storage Request, verify it, then upload a file to the connected MSP. Includes steps to verify upload success.

Retrieve Your Data

Use your file key to download your file from the MSP client and save it programmatically.

StorageHub SDK Packages

The StorageHub SDK contains the following packages:

Package
Description When to Use Environments
@storagehub-sdk/core Foundational, backend-agnostic building blocks for StorageHub. Chain-facing interactions Node.js, Browsers
@storagehub-sdk/msp-client High-level client for interacting with Main Storage Provider (MSP) services. Provider-facing operations Node.js, Browsers
@storagehub-sdk/core

The primary functions of @storagehub-sdk/core are to act as backend-agnostic building blocks including:

  • Wallets and signing
  • EIP-1193
  • Precompile helpers for bridging between Substrate and EVM
  • Merkle and WASM utilities
  • Low-level HTTP
  • Types and constants shared across the SDK.

This package includes EVM account-typed helpers, WASM-backed file utilities, and stable primitives usable without any backend.

@storagehub-sdk/msp-client

The primary functions of @storagehub-sdk/msp-client are as follows:

  • Retrieve MSP-specific client information, such as:
    • Health
    • Authorization nonce/verify
    • Upload and download endpoints
  • Talk to an MSP backend for authorization and file transfer.
  • Includes REST contracts for MSP, token handling, and streaming or multipart upload and download helpers.

This package includes all MSP-tied logic.

Prerequisites

Before you begin, ensure you have the following:

Need a starter project?

If you don't have an existing project, follow these steps to create a TypeScript project you can use to follow the guides in this section:

  1. Create a new project folder by executing the following command in the terminal:

    mkdir datahaven-project && cd datahaven-project
    
  2. Initialize a package.json file using the correct command for your package manager:

    pnpm init
    
    yarn init
    
    npm init --y
    
  3. Add the TypeScript and Node type definitions to your projects using the correct command for your package manager:

    pnpm add -D typescript ts-node @types/node
    
    yarn add -D typescript ts-node @types/node
    
    npm install -D typescript ts-node @types/node
    
  4. Create a tsconfig.json file in the root of your project and paste the following configuration:

    tsconfig.json
    {
        "compilerOptions": {
            "target": "ES2022",
            "module": "nodenext",
            "moduleResolution": "NodeNext",
            "esModuleInterop": true,
            "strict": true,
            "skipLibCheck": true,
            "outDir": "dist",
            "declaration": true,
            "sourceMap": true
        },
        "include": ["src/**/*.ts"]
    }
    
  5. Initialize the src directory:

    mkdir src && touch src/index.ts
    

Install the StorageHub SDK

Add the core and MSP client packages to your project. These libraries provide the APIs and utilities needed to interact with DataHaven’s storage network.

pnpm add @storagehub-sdk/core @storagehub-sdk/msp-client
yarn add @storagehub-sdk/core @storagehub-sdk/msp-client
npm install @storagehub-sdk/core @storagehub-sdk/msp-client

Initialize the StorageHub SDK

Follow the steps in this section to set up the clients needed to work with the StorageHub SDK, allowing you to interact with DataHaven and manage your data.

Install Client Dependencies

pnpm add @storagehub/types-bundle @polkadot/api @storagehub/api-augment viem
yarn add @storagehub/types-bundle @polkadot/api @storagehub/api-augment viem
npm install @storagehub/types-bundle @polkadot/api @storagehub/api-augment viem
Why do I need these dependencies?
  • @storagehub/types-bundle: Describes DataHaven's custom on-chain types.

  • @polkadot/api: The core JavaScript library used to talk to any Substrate-based blockchain, which in our case is DataHaven.

  • @storagehub/api-augment: Extends @polkadot/api with DataHaven's custom pallets and RPC methods. You will import it in your index.ts file where your main script logic will be executed.

  • viem: Lightweight library for building Ethereum-compatible applications.

Set Up Client Service

You'll need to set up the necessary clients to connect to the DataHaven network, which runs on a dual-protocol architecture (Substrate for core logic and EVM for compatibility).

  1. In the folder where your index.ts (or main code file) is located, create a new folder called services:

    mkdir services && cd services
    
  2. Create a clientService.ts file.

  3. Add the following code:

    Note

    The code below uses DataHaven testnet configuration values, which include the chain ID RPC URL, WSS URL, MSP URL, and token metadata. If you’re running a local devnet, make sure to replace these with your local configuration parameters. You can find all the relevant local devnet values in the Local Devnet page.

    clientService.ts
    import { privateKeyToAccount } from 'viem/accounts';
    import { Chain, defineChain } from 'viem';
    import {
      createPublicClient,
      createWalletClient,
      http,
      WalletClient,
      PublicClient,
    } from 'viem';
    import { StorageHubClient } from '@storagehub-sdk/core';
    import { ApiPromise, WsProvider } from '@polkadot/api';
    import { types } from '@storagehub/types-bundle';
    
    const account = privateKeyToAccount('INSERT_PRIVATE_KEY' as `0x${string}`);
    const address = account.address;
    
    const NETWORKS = {
      devnet: {
        id: 181222,
        name: 'DataHaven Local Devnet',
        rpcUrl: 'http://127.0.0.1:9666',
        wsUrl: 'wss://127.0.0.1:9666',
        mspUrl: 'http://127.0.0.1:8080/',
        nativeCurrency: { name: 'StorageHub', symbol: 'SH', decimals: 18 },
      },
      testnet: {
        id: 55931,
        name: 'DataHaven Testnet',
        rpcUrl: 'https://services.datahaven-testnet.network/testnet',
        wsUrl: 'wss://services.datahaven-testnet.network/testnet',
        mspUrl: 'https://deo-dh-backend.testnet.datahaven-infra.network/',
        nativeCurrency: { name: 'Mock', symbol: 'MOCK', decimals: 18 },
      },
    };
    
    const chain: Chain = defineChain({
      id: NETWORKS.testnet.id,
      name: NETWORKS.testnet.name,
      nativeCurrency: NETWORKS.testnet.nativeCurrency,
      rpcUrls: { default: { http: [NETWORKS.testnet.rpcUrl] } },
    });
    
    const walletClient: WalletClient = createWalletClient({
      chain,
      account,
      transport: http(NETWORKS.testnet.rpcUrl),
    });
    
    const publicClient: PublicClient = createPublicClient({
      chain,
      transport: http(NETWORKS.testnet.rpcUrl),
    });
    
    // Create StorageHub client
    const storageHubClient: StorageHubClient = new StorageHubClient({
      rpcUrl: NETWORKS.testnet.rpcUrl,
      chain: chain,
      walletClient: walletClient,
      filesystemContractAddress:
        '0x0000000000000000000000000000000000000404' as `0x${string}`,
    });
    
    // Create Polkadot API client
    const provider = new WsProvider(NETWORKS.testnet.wsUrl);
    const polkadotApi: ApiPromise = await ApiPromise.create({
      provider,
      typesBundle: types,
      noInitWarn: true,
    });
    
    export {
      account,
      address,
      publicClient,
      walletClient,
      storageHubClient,
      polkadotApi,
    };
    

    Warning

    It is assumed that private keys are securely stored and managed in accordance with standard security practices.

    With the above code in place, you now have the following:

    • walletClient: Used for signing and broadcasting transactions using the derived private key.
    • publicClient: Used for reading general public data from the chain, such as checking transaction receipts or block status.
    • storageHubClient: Used for interacting with the StorageHub network APIs, including creating buckets, issuing storage requests, uploading or deleting files, and managing storage proofs.
    • polkadotApi: Used for reading code chain logic and state data from the underlying DataHaven Substrate node.

Set Up MSP Service

To interact with DataHaven's Main Storage Provider (MSP) services, you need to establish a connection using the MspClient from the StorageHub SDK. This involves configuring the HTTP client, setting up session management for authenticated requests, and initializing the MSP client itself.

  1. Create a mspService.ts file within your services folder.

  2. Add the following code:

    Note

    The code below uses DataHaven testnet configuration values, which include the chain ID, RPC URL, WSS URL, MSP URL, and token metadata. If you’re running a local devnet, make sure to replace these with your local configuration parameters. You can find all the relevant local devnet values in the Local Devnet page.

    mspService.ts
    import {
      HealthStatus,
      InfoResponse,
      MspClient,
      UserInfo,
    } from '@storagehub-sdk/msp-client';
    import { HttpClientConfig } from '@storagehub-sdk/core';
    import { address, walletClient } from './clientService.js';
    
    const NETWORKS = {
      devnet: {
        id: 181222,
        name: 'DataHaven Local Devnet',
        rpcUrl: 'http://127.0.0.1:9666',
        wsUrl: 'wss://127.0.0.1:9666',
        mspUrl: 'http://127.0.0.1:8080/',
        nativeCurrency: { name: 'StorageHub', symbol: 'SH', decimals: 18 },
      },
      testnet: {
        id: 55931,
        name: 'DataHaven Testnet',
        rpcUrl: 'https://services.datahaven-testnet.network/testnet',
        wsUrl: 'wss://services.datahaven-testnet.network/testnet',
        mspUrl: 'https://deo-dh-backend.testnet.datahaven-infra.network/',
        nativeCurrency: { name: 'Mock', symbol: 'MOCK', decimals: 18 },
      },
    };
    
    // Configure the HTTP client to point to the MSP backend
    const httpCfg: HttpClientConfig = { baseUrl: NETWORKS.testnet.mspUrl };
    
    // Initialize a session token for authenticated requests (updated after authentication
    // through SIWE)
    let sessionToken: string | undefined = undefined;
    
    // Provide session information to the MSP client whenever available
    // Returns a token and user address if authenticated, otherwise undefined
    const sessionProvider = async () =>
      sessionToken
        ? ({ token: sessionToken, user: { address: address } } as const)
        : undefined;
    
    // Establish a connection to the Main Storage Provider (MSP) backend
    const mspClient = await MspClient.connect(httpCfg, sessionProvider);
    
    // Retrieve MSP metadata, including its unique ID and version, and log it to the console
    const getMspInfo = async (): Promise<InfoResponse> => {
      const mspInfo = await mspClient.info.getInfo();
      console.log(`MSP ID: ${mspInfo.mspId}`);
      return mspInfo;
    };
    
    // Retrieve and log the MSP’s current health status
    const getMspHealth = async (): Promise<HealthStatus> => {
      const mspHealth = await mspClient.info.getHealth();
      console.log(`MSP Health: ${mspHealth}`);
      return mspHealth;
    };
    
    // Authenticate the user via SIWE (Sign-In With Ethereum) using the connected wallet
    // Once authenticated, store the returned session token and retrieve the user’s profile
    const authenticateUser = async (): Promise<UserInfo> => {
      console.log('Authenticating user with MSP via SIWE...');
    
      // In development domain and uri can be arbitrary placeholders,
      // but in production they must match your actual frontend origin.
      const domain = 'localhost';
      const uri = 'http://localhost';
    
      const siweSession = await mspClient.auth.SIWE(walletClient, domain, uri);
      console.log('SIWE Session:', siweSession);
      sessionToken = (siweSession as { token: string }).token;
    
      const profile: UserInfo = await mspClient.auth.getProfile();
      return profile;
    };
    
    // Export initialized client and helper functions for use in other modules
    export { mspClient, getMspInfo, getMspHealth, authenticateUser };
    

    With the above code in place, you now have the following:

    • mspClient: Used for interacting with a Main Storage Provider (MSP) backend — allowing you to authenticate via SIWE, retrieve MSP information and health status, and perform storage-related actions through REST-like endpoints.
    • getMspInfo: Fetches general MSP metadata such as its unique ID, version, and available endpoints.
    • getMspHealth: Checks the operational health of the MSP and reports whether it’s running normally or facing issues.
    • authenticateUser: Authenticates your wallet with the MSP via Sign-In With Ethereum (SIWE), creates a session token, and returns your user profile.

Next Steps

Now that you have the StorageHub SDK packages installed and all the necessary clients set up, you are ready to start building with DataHaven.

Last update: December 18, 2025
| Created: September 18, 2025