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

@vectorforge-ai/sdk

v0.1.2

Published

Official Node.js/TypeScript SDK for VectorForge Cloud APIs

Readme

VectorForge Node SDK

Official TypeScript/Node.js client for VectorForge Cloud APIs.

VectorForge is a trust and confidence layer for AI and automations, providing:

  • DIVTs (Digital Integrity Verification Tokens) - Cryptographic "birth certificates" for data
  • AI Answer Confidence Scoring - Privacy-preserving and comprehensive scoring
  • Worldstate Logging - Immutable event capture for AI operations
  • Hybrid Post-Quantum Cryptography - ECDSA P-521 + ML-DSA-65 signatures

Installation

From npm (Recommended)

npm install @vectorforge-ai/sdk

From Source (Development)

git clone https://github.com/vectorforge/api
cd api/sdk/node
npm install
npm run build

For image support:

npm install sharp

Quick Start

Configuration

import { createVectorForgeClient } from '@vectorforge-ai/sdk';

// Option 1: Use environment variables (recommended)
// export VF_API_BASE_URL="https://api.vectorforge.ai"
// export VF_API_KEY="vf_prod_YourApiKeyHere"
const client = createVectorForgeClient();

// Option 2: Pass config directly
const client = createVectorForgeClient({
  baseUrl: "https://api.vectorforge.ai",
  apiKey: "vf_prod_YourApiKeyHere",
});

High-Level API (Recommended)

The SDK provides high-level methods that handle canonicalization and hashing automatically. These are the recommended way to use VectorForge.

Register Text Content

import { createVectorForgeClient } from '@vectorforge-ai/sdk';

const client = createVectorForgeClient();

const result = await client.registerContent(
  'prompt:123',
  'What is the capital of France?',
  'prompt_receipt_v1',
  { user_id: 'user-456', session: 'sess-789' }
);

console.log(`DIVT ID: ${result.divt_id}`);
console.log(`ECDSA signature: ${result.ecdsa_sig_b64.substring(0, 32)}...`);
console.log(`ML-DSA signature: ${result.ml_dsa_sig_b64.substring(0, 32)}...`);
console.log(`Ledger status: ${result.ledger_status}`);

What it does:

  1. Normalizes text (Unicode NFC, line endings, trim whitespace)
  2. Computes SHA3-512 hash
  3. Creates DIVT with hybrid post-quantum signatures
  4. Returns divt_id for future verification

Register JSON Data

const result = await client.registerJson(
  'rag_snapshot:v42',
  {
    snapshot_type: 'rag-corpus',
    doc_hashes: ['hash1', 'hash2'],
    index_hash: 'index_hash_value',
    timestamp: '2025-11-21T10:00:00Z',
  },
  'rag_snapshot_v1',
  { project: 'hr-assistant', env: 'prod' }
);

console.log(`RAG snapshot registered: ${result.divt_id}`);

What it does:

  1. Canonical JSON serialization (sorted keys, minimal whitespace)
  2. Computes SHA3-512 hash
  3. Creates DIVT

Register Embedding Vector

const result = await client.registerEmbedding(
  'chunk:doc-123:p5',
  [0.123456, -0.987654, 0.456789, ...],  // Your embedding vector
  'rag_chunk_v1',
  { document_id: 'doc-123', paragraph: 5 },
  6  // Decimal precision
);

console.log(`Embedding registered: ${result.divt_id}`);

What it does:

  1. Validates embedding (rejects NaN/Infinity)
  2. Formats with fixed precision for deterministic hashing
  3. Computes SHA3-512 hash
  4. Creates DIVT

Register Image

Requires: npm install sharp

import { readFile } from 'fs/promises';

const imageBuffer = await readFile('receipt.png');

const result = await client.registerImage(
  'image:receipt-456',
  imageBuffer,
  'image_receipt_v1',
  { source: 'mobile_app', user_id: 'user-789' },
  1024  // Max dimension
);

console.log(`Image registered: ${result.divt_id}`);

What it does:

  1. Decodes image (supports PNG, JPEG, WebP)
  2. Normalizes to sRGB color space
  3. Resizes if needed (preserves aspect ratio)
  4. Re-encodes as deterministic PNG
  5. Computes SHA3-512 hash
  6. Creates DIVT

Complete Example: Prompt Receipt with Verification

import { createVectorForgeClient } from '@vectorforge-ai/sdk';

const client = createVectorForgeClient();

// Register AI prompt + response
const promptData = {
  prompt: 'What is the capital of France?',
  response: 'Paris',
  model: 'gpt-4',
  timestamp: '2025-11-21T10:00:00Z',
};

const registerResult = await client.registerJson(
  'prompt_receipt:flow-abc-123',
  promptData,
  'prompt_receipt_v1',
  { workflow: 'customer_support' }
);

const divtId = registerResult.divt_id;
console.log(`✓ Prompt receipt registered: ${divtId}`);

// Later: Verify the prompt receipt
const verifyResult = await client.verifyJson(divtId, promptData);

if (verifyResult.verified) {
  console.log('✓ DIVT is valid');
  console.log(`  - Hash valid: ${verifyResult.hash_valid}`);
  console.log(`  - ECDSA signature valid: ${verifyResult.ecdsa_signature_valid}`);
  console.log(`  - ML-DSA signature valid: ${verifyResult.ml_dsa_signature_valid}`);
  console.log(`  - Object ID: ${verifyResult.object_id}`);
  console.log(`  - Created: ${verifyResult.created_at}`);
  console.log(`  - Ledger status: ${verifyResult.ledger_status}`);
} else {
  console.log('✗ DIVT verification failed');
  console.log(`  - Hash valid: ${verifyResult.hash_valid}`);
  console.log(`  - Revoked: ${verifyResult.revoked}`);
}

Low-Level API (Advanced)

For advanced use cases where you want to compute hashes yourself, use the low-level register() method:

import { canon } from '@vectorforge-ai/sdk';

// Compute hash manually
const text = 'Hello, World!';
const hashB64 = canon.hashContentV1(text);

// Register with pre-computed hash
const result = await client.register({
  object_id: 'doc-123',
  hash_mode: 'content',
  hash_version: 'content_v1',
  hash_b64: hashB64,
  data_type: 'prompt_receipt_v1',
});

Canonicalization Utilities

import { canon } from '@vectorforge-ai/sdk';

// Text canonicalization
const hashB64 = canon.hashContentV1('Hello, World!');

// JSON canonicalization
const hashB64 = canon.hashJsonV1({ key: 'value', nested: { a: 1 } });

// Embedding canonicalization
const hashB64 = canon.hashEmbeddingV1([0.1, 0.2, 0.3], 6);

// Image canonicalization (requires sharp)
const imageBuffer = await readFile('image.png');
const hashB64 = await canon.hashImageV1(imageBuffer, 1024);

// Or get canonical bytes without hashing
const canonicalBuffer = canon.canonicalizeContentV1('Hello');
const hashB64 = canon.sha3512Digest(canonicalBuffer);

Verification

Verify a Single DIVT

// Using hash_b64 (advanced)
const result = await client.verify({
  divt_id: '019abc12-3456-7890-abcd-ef0123456789',
  hash_b64: 'your-precomputed-hash-base64',
});

if (result.verified) {
  console.log('✓ DIVT is valid');
  console.log(`  - Hash valid: ${result.hash_valid}`);
  console.log(`  - ECDSA valid: ${result.ecdsa_signature_valid}`);
  console.log(`  - ML-DSA valid: ${result.ml_dsa_signature_valid}`);
  console.log(`  - Revoked: ${result.revoked}`);
} else {
  console.log('✗ DIVT verification failed');
}

Verify with High-Level Helpers

// Verify text content
const result = await client.verifyContent(divtId, 'Hello, World!');

// Verify JSON data
const result = await client.verifyJson(divtId, { key: 'value' });

Bundle API

Get comprehensive verification bundles for DIVTs including worldstate context and scoring results.

Get Bundle by DIVT ID

const bundle = await client.getBundle({
  divt_id: '019abc12-3456-7890-abcd-ef0123456789',
});

console.log('DIVT Verification:');
console.log(`  - Verified: ${bundle.divt.verified}`);
console.log(`  - Hash valid: ${bundle.divt.hash_valid}`);
console.log(`  - Ledger status: ${bundle.divt.ledger_status}`);

console.log(`Worldstate events: ${bundle.worldstate.length}`);
console.log(`Scoring events: ${bundle.scoring.length}`);
console.log(`Generated at: ${bundle.generated_at}`);

Get Bundle by Object ID

const bundle = await client.getBundle({
  object_id: 'prompt_receipt:flow-abc-123',
  include_history: true,
});

Scoring API

Privacy Score (No Raw Content Sent)

const result = await client.scorePrivacy({
  query_id: 'query-123',
  answer_id: 'answer-456',
  evidence: [
    {
      object_id: 'chunk:doc-1:p1',
      divt_id: '019abc...',
      tenant_id: 'my-tenant',
      similarity: 0.95,
      chunk_confidence: 0.9,
    },
  ],
});

console.log(`Overall confidence: ${result.overall_confidence}`);
console.log(`Semantic confidence: ${result.semantic_confidence}`);
console.log(`Integrity score: ${result.integrity_score}`);
console.log(`Verified count: ${result.verified_count}/${result.vector_count}`);

Full Score (With Groq Judge)

const result = await client.scoreFull({
  query: 'What is the capital of France?',
  answer: 'The capital of France is Paris.',
  evidence: [
    {
      object_id: 'chunk:doc-1:p1',
      divt_id: '019abc...',
      tenant_id: 'my-tenant',
      text: 'Paris is the capital city of France.',
      similarity: 0.95,
    },
  ],
  options: {
    log_worldstate: 'minimal',
  },
});

console.log(`Overall confidence: ${result.overall_confidence}`);
console.log(`Support score: ${result.support_score}`);
console.log(`Faithfulness score: ${result.faithfulness_score}`);

Worldstate Read

Get Single Worldstate Record

// Get worldstate record metadata
const item = await client.getWorldstateItem({
  wsl_id: '019abc12-3456-7890-abcd-ef0123456789',
});

console.log(`Kind: ${item.kind}`);
console.log(`Timestamp: ${item.timestamp}`);
console.log(`Ledger status: ${item.ledger_status}`);
console.log(`Summary: ${item.data_summary}`);

// Get worldstate record with full data from S3
const itemWithData = await client.getWorldstateItem({
  wsl_id: '019abc12-3456-7890-abcd-ef0123456789',
  include_data: true,
});

console.log('Full data:', itemWithData.data);

List Worldstate Records

// List all records
const result = await client.listWorldstate();
console.log(`Found ${result.count} records`);

// List with filters
const promptReceipts = await client.listWorldstate({
  kind: 'prompt_receipt',
  created_from: '2025-11-01T00:00:00Z',
  created_to: '2025-11-30T23:59:59Z',
  limit: 50,
});

// Paginate through all results
let cursor = promptReceipts.cursor;
while (cursor) {
  const page = await client.listWorldstate({ cursor });
  for (const item of page.items) {
    console.log(`${item.wsl_id}: ${item.data_summary}`);
  }
  cursor = page.cursor;
}

Available Filters:

  • kind: Filter by event type (prompt_receipt, scoring_event, rag_snapshot, etc.)
  • created_from: Start of time range (ISO 8601)
  • created_to: End of time range (ISO 8601)
  • limit: Page size (max 100, default 50)
  • cursor: Pagination cursor from previous response

Stream Events (SSE)

const oneHourAgo = new Date(Date.now() - 3600000).toISOString();

await client.streamEvents(
  {
    since: oneHourAgo,
    types: ['divt_registered', 'scoring_event'],
    limit: 50,
  },
  (event) => {
    console.log(`[${event.type}] ${event.id} at ${event.timestamp}`);
  }
);

Error Handling

import { VectorForgeAPIError } from '@vectorforge-ai/sdk';

try {
  const result = await client.registerContent(
    'doc-123',
    'Hello, World!',
    'prompt_receipt_v1'
  );
} catch (error) {
  if (error instanceof VectorForgeAPIError) {
    console.error(`API Error: ${error.message}`);
    console.error(`Status: ${error.statusCode}`);
    console.error(`Code: ${error.error}`);
    if (error.details) {
      console.error(`Details: ${error.details}`);
    }
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Common Error Codes:

  • invalid_api_key (401) - API key invalid or expired
  • quota_exceeded (429) - Monthly request limit reached
  • rate_limit_exceeded (429) - Too many requests
  • plan_limitation (403) - Feature not available on your plan
  • network_error (0) - Network connectivity issue

Type Support

Full TypeScript support with type definitions:

import type {
  RegisterInput,
  RegisterResult,
  VerifyInput,
  VerifyResult,
  BundleInput,
  BundleResult,
  PrivacyScoreInput,
  FullScoreInput,
  ScoreResult,
  StreamEventsInput,
  StreamEvent,
} from '@vectorforge-ai/sdk';

Integration Tests

To run integration tests against the live API:

export VF_API_BASE_URL="https://api.vectorforge.ai"
export VF_API_KEY="your-api-key"
npm test

Requirements

  • Node.js: >= 18.0.0 (uses native fetch)
  • Dependencies:
    • js-sha3 (SHA3-512 hashing)
  • Optional:
    • sharp >= 0.33.0 (for image registration)

Related Documentation


Support


License

MIT © VectorForge