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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@axlabs/neofs-sdk-ts-node

v0.0.4

Published

TypeScript SDK for NeoFS - Node.js Edition

Readme

NeoFS TypeScript SDK for Node.js

A Node.js TypeScript SDK for NeoFS - a decentralized, distributed object storage network.

Features

  • Native Node.js: Uses @grpc/grpc-js for optimal performance
  • Streaming Support: Efficient streaming for large file uploads/downloads
  • Full NeoFS API: Containers, objects, sessions, EACL, bearer tokens
  • Type Safety: Complete TypeScript definitions
  • Async/Await: Modern Promise-based API

Installation

npm install neofs-sdk-ts-node

Quick Start

import { NeoFSClient, ECDSASigner } from 'neofs-sdk-ts-node';

// Create a signer from your private key
const signer = ECDSASigner.fromHex(privateKeyHex);

// Initialize the client
const client = new NeoFSClient({
  endpoint: 'grpc.testnet.neofs.io:8082',
  signer,
});

// Create a container
const containerId = await client.container().put({
  container: {
    placementPolicy: { replicas: [{ count: 2 }] },
    basicAcl: 0x1fbf8cff, // PUBLIC_READ
  },
});

console.log('Container created:', containerId);

// Upload an object
const objectId = await client.object().put({
  header: { containerId },
  payload: Buffer.from('Hello, NeoFS!'),
  attributes: [
    { key: 'FileName', value: 'hello.txt' },
    { key: 'ContentType', value: 'text/plain' },
  ],
});

console.log('Object uploaded:', objectId);

// Download the object
const result = await client.object().get({
  address: { containerId, objectId },
});

console.log('Content:', Buffer.from(result.payload).toString());

API Overview

Client Initialization

import { NeoFSClient, ECDSASigner, ECDSASignerRFC6979 } from 'neofs-sdk-ts-node';

// From hex private key
const signer = ECDSASigner.fromHex('your-private-key-hex');

// Or generate a new key pair
const signer = ECDSASigner.generate();

// Or use RFC6979 deterministic signatures
const signer = ECDSASignerRFC6979.fromHex('your-private-key-hex');

const client = new NeoFSClient({
  endpoint: 'grpc.testnet.neofs.io:8082',
  signer,
  // Optional: TLS configuration
  // credentials: grpc.credentials.createSsl(),
});

Container Operations

// Create a container
const containerId = await client.container().put({
  container: {
    placementPolicy: { replicas: [{ count: 3 }] },
    basicAcl: 0x1fbf8cff,
    attributes: [
      { key: 'Name', value: 'my-container' },
    ],
  },
});

// Get container info
const container = await client.container().get({ containerId });
console.log('Owner:', container?.ownerId);
console.log('Policy:', container?.placementPolicy);

// List containers
const containers = await client.container().list({});

// Delete a container
await client.container().delete({ containerId });

Object Operations

// Upload an object
const objectId = await client.object().put({
  header: { containerId },
  payload: Buffer.from('Hello, World!'),
  attributes: [
    { key: 'FileName', value: 'hello.txt' },
    { key: 'ContentType', value: 'text/plain' },
  ],
});

// Get object metadata (HEAD)
const header = await client.object().head({
  address: { containerId, objectId },
});
console.log('Size:', header?.payloadLength);

// Download an object
const result = await client.object().get({
  address: { containerId, objectId },
});
console.log('Payload:', result.payload);

// Search objects
const objectIds = await client.object().search({
  containerId,
  filters: [
    { key: 'FileName', value: 'hello', matchType: 3 }, // COMMON_PREFIX
  ],
});

// Delete an object
await client.object().delete({
  address: { containerId, objectId },
});

Large File Streaming

For large files, use the streaming client:

import { StreamingObjectClient } from 'neofs-sdk-ts-node';

// The streaming client handles chunked uploads automatically
const objectId = await client.object().put({
  header: { containerId },
  payload: largeBuffer, // Can be any size
  attributes: [{ key: 'FileName', value: 'large-file.zip' }],
});

Network Information

// Get current epoch
const { networkInfo } = await client.netmap().networkInfo();
console.log('Epoch:', networkInfo?.currentEpoch);

// Get local node info
const localInfo = await client.netmap().localNodeInfo();
console.log('Version:', localInfo?.version);

// Get network snapshot
const snapshot = await client.netmap().netmapSnapshot();
console.log('Nodes:', snapshot?.body?.netmap?.nodes?.length);

Session Management

// Create a session
const session = await client.session().create({
  expiration: BigInt(currentEpoch + 100),
});
console.log('Session ID:', session.id);

EACL (Extended Access Control)

import { Table, Target, Record, Operation, publicReadEACL } from 'neofs-sdk-ts-node';

// Use a preset
const eacl = publicReadEACL(containerId);

// Or build custom rules
const customEacl = new Table(containerId)
  .allowRead([Target.others()])
  .denyWrite([Target.others()])
  .allow(Operation.PUT, [Target.userId(friendId)]);

// Set EACL on container
await client.container().setEACL({
  containerId,
  eaclTable: eacl.toProto(),
});

// Get EACL
const currentEacl = await client.container().getEACL({ containerId });

Bearer Tokens

import { BearerToken, publicReadEACL } from 'neofs-sdk-ts-node';

// Create a bearer token for delegated access
const token = new BearerToken()
  .setEACL(publicReadEACL(containerId))
  .forUser(friendUserId)
  .setIssuer(myUserId)
  .setLifetime({
    iat: currentEpoch,
    nbf: currentEpoch,
    exp: currentEpoch + 100n,
  })
  .sign(signer);

// Serialize to share
const tokenBytes = token.serialize();

Waiter (Async Confirmation)

import { Waiter } from 'neofs-sdk-ts-node';

const waiter = new Waiter(client);

// Create container and wait for confirmation
const containerId = await waiter.containerPut({
  container: { /* ... */ },
});
// Container is guaranteed to exist at this point

// Upload object and wait for confirmation
const objectId = await waiter.objectPut({
  header: { containerId },
  payload: data,
});
// Object is guaranteed to be readable

Configuration

interface ClientConfig {
  /** gRPC endpoint (host:port) */
  endpoint: string;
  
  /** Signer for authentication */
  signer: Signer;
  
  /** Optional gRPC credentials (for TLS) */
  credentials?: grpc.ChannelCredentials;
  
  /** Optional gRPC channel options */
  options?: grpc.ChannelOptions;
}

TLS Configuration

import * as grpc from '@grpc/grpc-js';
import * as fs from 'fs';

const client = new NeoFSClient({
  endpoint: 'grpc.example.com:8082',
  signer,
  credentials: grpc.credentials.createSsl(
    fs.readFileSync('ca.pem'),
    fs.readFileSync('client-key.pem'),
    fs.readFileSync('client-cert.pem'),
  ),
});

Error Handling

try {
  const result = await client.object().get({
    address: { containerId, objectId },
  });
} catch (error) {
  if (error.code === 2049) {
    console.log('Object not found');
  } else if (error.code === 3072) {
    console.log('Container not found');
  } else {
    throw error;
  }
}

Example Application

See the example directory for a complete Express.js application demonstrating:

  • Container management
  • File upload/download
  • Object search
  • Web interface
cd example
npm install
npm start
# Open http://localhost:3000

Development

# Build
npm run build

# Run tests
npm test

# Generate protobuf types
npm run generate:all

# Lint
npm run lint

# Format
npm run format

License

Apache 2.0 - see LICENSE for details.