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

@xenea.io/dacs-sdk

v1.0.2

Published

Official Node.js SDK for DACS (Decentralized Autonomous Contents Storage) infrastructure.

Readme

@xenea.io/dacs-sdk

Official Node.js SDK for DACS (Decentralized Autonomous Contents Storage) infrastructure.

Security Note: Server-Side Only

This SDK is designed strictly for server-side (Node.js) environments.

DO NOT use this SDK directly in a frontend application (React, Vue, etc.). Doing so will expose your project's apiKey to the public, allowing anyone to upload files to your quota or impersonate your project.

Recommended Architecture for Web Apps

If you need to interact with DACS from a web frontend:

  1. Create a secure endpoint on your own backend.
  2. Authenticate your frontend users using your preferred auth system.
  3. Use this SDK strictly within your backend environment.
  4. Proxy requests from your frontend to your backend.

Installation

npm install @xenea.io/dacs-sdk

Initialization

Initialize the DacsClient with your project credentials on your backend.

import { DacsClient } from "@xenea.io/dacs-sdk";

const client = new DacsClient({
  baseURL: "https://dacs-testnet.xenea.io",
  apiKey: process.env.DACS_API_KEY!,
});

High-Level Architecture (Hybrid Flow)

To protect your API Key while allowing direct browser-to-storage uploads, use the following Delegated Upload pattern:

  1. Frontend: Requests an upload plan from Your Backend.
  2. Your Backend: Uses the SDK (initializeUpload) to get a Presigned URL and fields.
  3. Your Backend: Returns the data to the Frontend.
  4. Frontend: Performs a POST directly to the storage.
  5. DACS: Automatically detects completion and syncs to IPFS/Blockchain.

DACS Upload Flow


Core Features & Usage

1. Delegated Upload (Recommended for Web Apps)

Allows users to upload directly to storage without exposing your API Key on the frontend.

Step A: Your Backend (Node.js)

// Parameters:
// - filename (string): The name of the file to be stored
// - size (number): File size in bytes
// - options (object, optional):
//    - tags (string[]): Multiple tags or hierarchical paths (e.g. ["Work", "Project", "2024"])
const result = await client.files.initializeUpload("image.png", 10245, {
  tags: ["Images", "Project-X"],
});

/**
 * result: {
 *   fileId: string;       // Internal ID for tracking status
 *   uploadUrl: string;    // S3/Storage endpoint URL
 *   uploadFields: object; // Security fields (signatures, policies) required by Storage
 * }
 */
res.json(result);

Step B: Your Frontend (Browser)

The uploadFields must be appended to the form before the actual file.

const formData = new FormData();

// 1. Append all received security fields first
Object.entries(uploadFields).forEach(([key, value]) => {
  formData.append(key, value);
});

// 2. Append the actual file content last
formData.append("file", fileFromInput);

// 3. Send directly to storage
await fetch(uploadUrl, { method: "POST", body: formData });

2. Direct Upload

If the file is already on your server, upload it in one call.

import fs from "fs";

// Parameters:
// - buffer (Buffer): Binary data of the file
// - filename (string): Desired storage name
// - options (object, optional):
//    - tags (string[]): Multiple tags (e.g. ["Music", "Lofi"])
const buffer = fs.readFileSync("image.png");
const result = await client.files.upload(buffer, "image.png", {
  tags: ["Icons", "Solid"],
});

/**
 * result: {
 *   fileId: string;   // Unique ID to track status
 *   message: string;  // Status message
 * }
 */

3. Track File Status

Check processing status as the file is synced to the DACS network. You can track a file from the moment it is initialized until it is fully registered on-chain.

// Parameters:
// - fileId (string): The ID received from upload/initialization
const status = await client.files.getStatus("your-file-id");

/**
 * status: {
 *   fileId: string;
 *   filename: string;
 *   size: number;
 *   status: "PENDING" | "PROCESSING" | "COMPLETED" | "FAILED";
 *   dacsId?: string;      // Decentralized CID (Available when COMPLETED)
 *   txHash?: string;      // Blockchain Transaction Hash (Available when COMPLETED)
 *   createdAt: string;
 *   completedAt?: string;
 *   errorMessage?: string; // Reason if FAILED (e.g. "Upload timeout after 30 minutes")
 *   tags?: string[];
 * }
 */

File Status Lifecycle

PENDING (initialized, awaiting upload/detection)
     │
     ▼
PROCESSING (syncing to IPFS / registering on-chain)
     │                        │
     │                   [Upload Timeout]
     │                        │
     ▼                        ▼
COMPLETED (on-chain)     FAILED (check errorMessage)

| Status | Meaning | | ------------ | ---------------------------------------------------- | | PENDING | Upload session created OR file waiting for IPFS sync | | PROCESSING | Actively syncing to IPFS / registering on blockchain | | COMPLETED | Fully on-chain. dacsId and txHash are available | | FAILED | Timed out or error. Check errorMessage for reason |

4. File Download

Fetch file content using either the internal fileId or the decentralized dacsId.

Option A: By File ID

// Parameters: fileId (string)
const buffer = await client.files.download({ fileId: "550e8400-..." });

Option B: By DACS ID (CID)

// Parameters: dacsId (string) - the CID starting with "Qm"
const buffer = await client.files.download({ dacsId: "Qm..." });

Saving to File (Node.js)

// Convert the resulting Buffer back to a physical file
import fs from "fs";
fs.writeFileSync("downloaded_file.png", buffer as Buffer);

5. Storage Quota

Monitor your project's storage usage.

const quota = await client.user.quota();

/**
 * quota: {
 *   used: number;      // Total bytes used
 *   limit: number;     // Max bytes allowed
 *   remaining: number; // Quota left
 *   unit: string;      // Measurement unit (e.g. "BYTES")
 *   fileCount: number; // Total number of uploaded files
 * }
 */

6. List Files

Retrieve paginated history of your uploaded files. You can filter by status to see different categories.

// Default: returns COMPLETED files
const response = await client.files.list({ page: 1, limit: 10 });

// Filter by PENDING (files still uploading to storage)
const pending = await client.files.list({ status: "PENDING" });

// Filter by FAILED (timed out or sync errors)
const failed = await client.files.list({ status: "FAILED" });

// Search by filename
const results = await client.files.list({ search: "image.png" });

/**
 * response: {
 *   data: FileStatusResponse[]; // Array of file objects (see Section 3 for fields)
 *   total: number;              // Total matching files
 *   page: number;
 *   limit: number;
 * }
 */

Note on FAILED status: A file is marked FAILED when:

  • The upload to S3 was not detected within 30 minutes (upload timeout)
  • An error occurred during IPFS sync or blockchain registration In both cases, errorMessage will explain the reason.

7. System Health

Check if DACS systems and Infrastructure are connected.

const health = await client.health();

/**
 * health: {
 *   status: "ok" | "degraded",
 *   service: "dacs-api-gateway",
 *   dacs: { connected: boolean },   // Storage & IPFS Status
 *   xenea: { connected: boolean },  // Blockchain Status
 *   timestamp: string;
 * }
 */

8. Tagging Rules

Tags are useful for content discovery and internal organization. When using tags, ensure they follow these rules:

  • Format: Array of strings (e.g. ["Project", "2024"]).
  • Allowed Characters: Alphanumeric (a-z, A-Z, 0-9), dashes (-), underscores (_), dots (.), slashes (/), and spaces.
  • Normalization: Slashes are treated as hierarchical separators. Leading/trailing slashes are automatically removed.

Error Handling

All SDK methods throw DacsError on failure. Always wrap calls in try/catch.

import { DacsError } from "@xenea.io/dacs-sdk";

try {
  await client.files.upload(buffer, "image.png");
} catch (err) {
  if (err instanceof DacsError) {
    console.error(err.code); // e.g. "QUOTA_EXCEEDED"
    console.error(err.message);
  }
}

Common Error Codes

| Code | Description | | ------------------ | ----------------------------------------- | | UNAUTHORIZED | Invalid or missing API key | | VALIDATION_ERROR | Invalid input (e.g. restricted tag chars) | | QUOTA_EXCEEDED | Storage quota reached | | FILE_TOO_LARGE | File exceeds maximum size | | UPLOAD_FAILED | Internal upload error | | NOT_FOUND | File record does not exist | | TIMEOUT | Request timed out |


Network & Infrastructure

Contract Addresses

| Network | Contract | Address | | ----------------------------- | ------------ | -------------------------------------------- | | Xenea Testnet (Chain ID 1096) | DACSRegistry | 0x1EfF0CdbD0e58aBcE73e564010e4105a4e2F8DEa |

API Endpoints

| Environment | URL | | ----------- | ------------------------------- | | Testnet | https://dacs-testnet.xenea.io |


Configuration

| Property | Description | Default | | --------- | --------------------- | ---------- | | baseURL | The DACS API URL | (Required) | | apiKey | Your project API Key | (Required) | | timeout | Request timeout in ms | 30000 |