npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@ftheirs/core

v3.0.0

Published

Core primitives for StorageHub SDK (types, crypto, filemanager, storage, wasm bindings)

Readme

StorageHub SDK — Core

Foundational, backend-agnostic building blocks for StorageHub. This package contains StorageHub-specific logic that does not depend on the MSP backend implementation: wallet utilities, blockchain interaction helpers, precompile bindings, Merkle tooling, cryptography/WASM helpers, low-level HTTP utilities, and shared types. Its goal is to let developers integrate StorageHub without needing to understand network implementation details (nodes, pallets, EVM precompiles), by exposing stable, typed primitives and adapters.

What this package is

  • Wallet and signing: Local wallet utilities and EIP-1193 adapter for injected wallets.
  • Blockchain interaction: Helpers for StorageHub chain types/encodings with EVM account types.
  • Precompile helpers: Bridge Substrate and EVM via precompiles to enable smart‑contract flows (issue storage requests, create buckets, etc.).
  • Merkle utilities: Build/verify trees and proofs used by StorageHub.
  • Crypto/WASM helpers: Performance-critical primitives via WASM (e.g., FileManager's Merkle/trie and hashing).
  • HTTP utilities: Minimal HttpClient and types for consistent networking.
  • Shared types/constants: Common shapes used across SDK packages.

What this package is not

  • Not an MSP client: No MSP auth, upload/download, or REST contracts. See @storagehub-sdk/msp-client.
  • Not app-specific: No UI/product code; only reusable SDK primitives.

Install

pnpm add @storagehub-sdk/core
# or
npm i @storagehub-sdk/core
# or
yarn add @storagehub-sdk/core

Quick start

import { HttpClient, type HttpClientConfig } from '@storagehub-sdk/core';

const http = new HttpClient({
  baseUrl: 'https://example.invalid',
} satisfies HttpClientConfig);

EVM Integration with StorageHub

The Core SDK provides seamless integration with StorageHub's EVM precompiles, offering automatic gas estimation, type safety, and a clean developer experience.

ABI Generation

  • Solidity contracts are automatically compiled to ABI during prebuild using solc-js
  • Generated ABIs are strongly typed using viem and abitype
  • No code generation required - pure TypeScript type inference

StorageHubClient - Unified EVM Interface

import { StorageHubClient } from '@storagehub-sdk/core';
import { createWalletClient, defineChain, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';

// Define your StorageHub chain
const storageHubChain = defineChain({
  id: 181222,
  name: 'StorageHub',
  nativeCurrency: { name: 'StorageHub', symbol: 'SH', decimals: 18 },
  rpcUrls: { default: { http: ['http://localhost:9944'] } },
});

// Create wallet client
const account = privateKeyToAccount('0x...');
const walletClient = createWalletClient({
  chain: storageHubChain,
  account,
  transport: http('http://localhost:9944')
});

// Create StorageHub client - handles everything automatically
const hub = new StorageHubClient({
  rpcUrl: 'http://localhost:9944',
  chain: storageHubChain,
  walletClient
});

Basic Usage

// Read operations (no gas required)
const name = new TextEncoder().encode('my-bucket');
const bucketId = await hub.deriveBucketId('0xOwnerAddress', name);
const pendingRequests = await hub.getPendingFileDeletionRequestsCount('0xUserAddress');

// Write operations (automatic gas estimation)
const txHash = await hub.createBucket(
  '0xMspId',           // MSP ID
  name,               // Bucket name (max 100 bytes)
  false,              // isPrivate
  '0xValuePropId'     // Value proposition ID
);

// Write with custom gas options
const txHash2 = await hub.updateBucketPrivacy('0xBucketId', true, {
  gasMultiplier: 8,        // Higher safety margin
  gasPrice: parseGwei('2') // Custom gas price
});

Available Methods

Bucket Management:

  • createBucket(mspId, name, isPrivate, valuePropId, options?)
  • deleteBucket(bucketId, options?)
  • updateBucketPrivacy(bucketId, isPrivate, options?)
  • requestMoveBucket(bucketId, newMspId, newValuePropId, options?)

Storage Operations:

  • issueStorageRequest(bucketId, location, fingerprint, size, mspId, peerIds, replicationTarget, customReplicationTarget, options?)
  • revokeStorageRequest(fileKey, options?)
  • requestDeleteFile(signedIntention, signature, bucketId, location, size, fingerprint, options?)

Collections:

  • createAndAssociateCollectionWithBucket(bucketId, options?)

Read Operations:

  • deriveBucketId(owner, name)
  • getPendingFileDeletionRequestsCount(user)

Gas Handling

The SDK provides intelligent gas estimation with Frontier chain optimizations:

// Automatic gas estimation (recommended)
await hub.createBucket(mspId, name, false, valuePropId);

// Custom gas options
await hub.createBucket(mspId, name, false, valuePropId, {
  gasMultiplier: 6,           // Safety multiplier (default: 5)
  gasPrice: parseGwei('1.5'), // Legacy gas pricing
  // OR EIP-1559 fees:
  maxFeePerGas: parseGwei('2'),
  maxPriorityFeePerGas: parseGwei('0.5')
});

// Explicit gas limit
await hub.createBucket(mspId, name, false, valuePropId, {
  gas: 500_000n  // Skip estimation, use exact amount
});

Error Handling

try {
  await hub.createBucket(mspId, name, false, valuePropId);
} catch (error) {
  if (error.message.includes('exceeds maximum length')) {
    // Handle validation errors
  } else if (error.message.includes('OutOfGas')) {
    // Handle gas estimation issues
  }
}

Type Safety

All methods are fully typed with parameter validation:

// ✅ Type-safe parameters
const name = new TextEncoder().encode('bucket-name'); // Uint8Array
const mspId = '0x...' as `0x${string}`;              // Hex string type

// ❌ Compile-time errors for invalid types
await hub.createBucket('invalid', 'string', false, mspId); // TypeScript error

Local wallet

import { LocalWallet } from '@storagehub-sdk/core';

const wallet = LocalWallet.fromPrivateKey('0xYourPrivateKey');
const address = await wallet.getAddress();
const signature = await wallet.signMessage('hello');

EIP-1193 wallet (browser)

import { Eip1193Wallet } from '@storagehub-sdk/core';

const wallet = await Eip1193Wallet.connect(); // prompts injected wallet (e.g., MetaMask)
const address = await wallet.getAddress();
const signature = await wallet.signMessage('hello');

FileManager (WASM-backed)

import { FileManager } from '@storagehub-sdk/core';
import { createReadStream, statSync } from 'node:fs';
import { Readable } from 'node:stream';

const path = './path/to/file.bin';
const size = statSync(path).size;
const webStream = Readable.toWeb(createReadStream(path)) as unknown as ReadableStream<Uint8Array>;

const fm = new FileManager({ size, stream: () => webStream });
const fingerprint = await fm.getFingerprint(); // H256

Design principles

  • Backend-agnostic: No MSP-specific behavior here.
  • Composable and typed: Small utilities, strong types, clear errors.
  • Runtime-friendly: Browser and Node support; fetch is properly bound in browsers.
  • Separation of concerns: Core primitives live here; MSP flows live in msp-client.

Roadmap

  • Typed precompile interfaces: Strongly-typed bindings and ABI-like helpers.
  • Proof tooling: End-to-end generation/verification for storage proofs.
  • Chunking/commitment utilities: Streaming chunker and deterministic trees.

When to use core vs msp-client

  • Use @storagehub-sdk/core for primitives that must work without any backend (wallets, Merkle, precompiles, chain helpers, low-level HTTP).
  • Use @storagehub-sdk/msp-client for MSP endpoints, auth/nonce/sign/verify flows, and file transfer APIs.

Environments

Supported environments: web browsers and Node.js.