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

@net-protocol/storage

v0.1.3

Published

Net Storage SDK for key-value storage on the Net protocol

Readme

@net-protocol/storage

Status: Alpha - Usable but may have breaking changes over time. Suitable for early adopters and testing.

Net Storage SDK for permanent onchain key-value storage built on Net Protocol.

What is Net Storage?

Net Storage provides permanent, versioned key-value storage on the blockchain. Every write creates a new version, preserving complete history. Unlike traditional databases, Storage data is:

  • Immutable: Once stored, data cannot be modified
  • Versioned: Complete history of all changes preserved
  • Transparent: All data is publicly verifiable
  • Decentralized: No central servers or databases

Storage Types

Net Storage supports three storage patterns for different file sizes:

Regular Storage

Best for: Small data (< 20KB)
How it works: Stores data directly as Net messages
Use cases: User settings, configuration, small metadata

Chunked Storage

Best for: Medium files (20KB-80KB)
How it works: Compresses data (gzip) and splits into 20KB chunks
Use cases: Images, documents, medium-sized data

XML Storage

Best for: Large files (multi-MB)
How it works: Splits large files into 80KB pieces, stores each using ChunkedStorage, maintains references as XML metadata
Use cases: Videos, large images, datasets, any large file

What can you do with this package?

  • Store data permanently: Write key-value pairs that persist forever on the blockchain
  • Access version history: Read any historical version of stored data
  • Store files of any size: From small settings to multi-MB files
  • Build storage apps: Create applications that need permanent, verifiable data storage

This package provides both React hooks (for UI) and client classes (for non-React code).

Learn More

Installation

npm install @net-protocol/storage
# or
yarn add @net-protocol/storage

Dependencies

  • @net-protocol/core - Core Net protocol SDK
  • viem - Ethereum library
  • pako - Compression library (for chunked storage)
  • wagmi (peer dependency) - Required for React hooks only
  • react (peer dependency) - Required for React hooks only

Usage

React Hooks

import {
  useStorage,
  useXmlStorage,
  useStorageFromRouter,
} from "@net-protocol/storage";

// Basic storage read
function MyComponent() {
  const { data, isLoading, error } = useStorage({
    chainId: 8453,
    key: "my-key",
    operatorAddress: "0x...",
  });

  if (isLoading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  const [text, data] = data || [];
  return <div>{text}</div>;
}

// Storage with output format options
function StorageWithFormat() {
  // Get data as plain string (default is hex)
  const { data: stringData } = useStorage({
    chainId: 8453,
    key: "my-key",
    operatorAddress: "0x...",
    outputFormat: "string", // Returns plain string instead of hex
  });

  // Use StorageRouter for automatic detection (latest version only)
  const { data: routerData } = useStorage({
    chainId: 8453,
    key: "my-key",
    operatorAddress: "0x...",
    useRouter: true, // Automatically detects regular vs chunked storage
    outputFormat: "string",
  });

  // Get historical version
  const { data: historicalData } = useStorage({
    chainId: 8453,
    key: "my-key",
    operatorAddress: "0x...",
    index: 0, // 0-based index for historical versions
    outputFormat: "string",
  });
}

// XML storage with recursive resolution
function XmlComponent() {
  const { data, isLoading, isXml } = useXmlStorage({
    chainId: 8453,
    key: "my-xml-key",
    operatorAddress: "0x...",
  });

  return <div>{data}</div>;
}

// XML storage with format options
function XmlWithFormats() {
  // Return as tuple format with hex output
  const { data: tupleData } = useXmlStorage({
    chainId: 8453,
    key: "my-xml-key",
    operatorAddress: "0x...",
    returnFormat: "tuple", // Returns [text, data] tuple
    outputFormat: "hex", // Data is hex string (default)
    useRouter: true, // Use StorageRouter for automatic detection
  });

  // Return as tuple format with string output
  const { data: tupleStringData } = useXmlStorage({
    chainId: 8453,
    key: "my-xml-key",
    operatorAddress: "0x...",
    returnFormat: "tuple",
    outputFormat: "string", // Data is plain string
  });

  // Return as object format (default)
  const {
    data: objectData,
    filename,
    isXml,
  } = useXmlStorage({
    chainId: 8453,
    key: "my-xml-key",
    operatorAddress: "0x...",
    returnFormat: "object", // Returns { data, filename, isLoading, error, isXml }
  });
}

// Storage from router (handles chunked storage)
function StorageComponent() {
  const { data, isLoading } = useStorageFromRouter({
    chainId: 8453,
    storageKey: "0x...",
    operatorAddress: "0x...",
  });

  return <div>{data?.[1]}</div>;
}

StorageClient (Non-React)

import { StorageClient } from "@net-protocol/storage";

// Create client
const client = new StorageClient({
  chainId: 8453,
  overrides: { rpcUrls: ["https://custom-rpc.com"] }, // Optional
});

// Get storage value
const data = await client.get({
  key: "my-key",
  operator: "0x...",
});

// Get historical version
const historical = await client.getValueAtIndex({
  key: "my-key",
  operator: "0x...",
  index: 0, // 0-based index
});

// Get via StorageRouter (handles chunked storage)
const routerData = await client.getViaRouter({
  key: "my-key",
  operator: "0x...",
});

// Read with XML resolution
const xmlData = await client.readStorageData({
  key: "my-xml-key",
  operator: "0x...",
});

Utilities

import {
  getStorageKeyBytes,
  chunkDataForStorage,
  assembleChunks,
  parseNetReferences,
  processDataForStorage,
} from "@net-protocol/storage";

// Generate storage key bytes
const keyBytes = getStorageKeyBytes("my-key");

// Chunk data for storage
const chunks = chunkDataForStorage("large data string");

// Assemble chunks
const assembled = assembleChunks(chunks);

// Parse XML references
const references = parseNetReferences('<net k="hash" v="0.0.1" />');

// Process data for XML storage
const result = processDataForStorage(data, operatorAddress);

API Reference

React Hooks

  • useStorage - Read storage value (latest or historical)
  • useStorageForOperator - Get all storage keys for an operator
  • useStorageForOperatorAndKey - Get storage value by operator and key
  • useBulkStorage - Bulk read storage values
  • useStorageTotalWrites - Get total number of versions
  • useXmlStorage - Read XML storage with recursive resolution
  • useStorageFromRouter - Read from StorageRouter (handles chunked storage)

StorageClient Methods

  • get(params) - Get storage value (latest)
  • getValueAtIndex(params) - Get storage value at historical index
  • getTotalWrites(params) - Get total number of versions
  • bulkGet(params) - Bulk read storage values
  • getViaRouter(params) - Get via StorageRouter (handles chunked storage)
  • getChunkedMetadata(params) - Get chunked storage metadata
  • getChunked(params) - Get chunked storage chunks
  • getForOperator(params) - Get all keys for operator
  • getForOperatorAndKey(params) - Get storage by operator and key
  • readStorageData(params) - Read with XML resolution
  • readChunkedStorage(params) - Read chunked storage with decompression

Storage Types

Regular Storage

Simple key-value storage using Storage.sol. Values are stored directly on-chain.

Chunked Storage

Large data storage using ChunkedStorage.sol. Data is compressed (gzip) and split into 20KB chunks.

XML Storage

Hierarchical storage using XML references. Supports recursive resolution and operator inheritance.

License

MIT