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

@yseeku/trust-receipts

v1.0.0

Published

SSL/TLS for AI — cryptographically sign and verify every interaction

Readme

@yseeku/trust-receipts

npm version tests license

SSL/TLS for AI — cryptographically sign and verify every interaction.

The Problem

AI systems generate outputs that need to be auditable. Who said what? When? Was the response tampered with? Current logging is trust-based and easily manipulated.

The Solution

Trust Receipts work like SSL certificates for AI interactions:

  • Authentication: Ed25519 signatures prove who generated the receipt
  • Integrity: SHA-256 hashes of prompt and response detect tampering
  • Non-repudiation: Hash chains create immutable audit trails

Install

npm install @yseeku/trust-receipts

Quick Start

import { TrustReceipts } from '@yseeku/trust-receipts';
import OpenAI from 'openai';

const receipts = new TrustReceipts({
  privateKey: process.env.SONATE_PRIVATE_KEY,
});

const openai = new OpenAI();
const messages = [{ role: 'user', content: 'Explain quantum computing.' }];

const { response, receipt } = await receipts.wrap(
  () => openai.chat.completions.create({ model: 'gpt-4', messages }),
  { sessionId: 'user-123', input: messages }
);

console.log(response.choices[0].message.content);
console.log('Receipt:', receipt.receiptHash);

What Gets Hashed?

Before signing, the SDK canonicalizes and hashes this payload using RFC 8785 JSON Canonicalization:

{
  "version": "1.0",
  "timestamp": "2026-02-18T01:29:00.000Z",
  "sessionId": "user-123",
  "agentId": "gpt-4",
  "promptHash": "sha256:a1b2c3...",
  "responseHash": "sha256:d4e5f6...",
  "scores": { "clarity": 0.92, "accuracy": 0.88 },
  "prevReceiptHash": "sha256:789abc...",
  "metadata": {}
}

The promptHash and responseHash are SHA-256 hashes of the canonicalized prompt/response content. The entire payload is then hashed to produce receiptHash, which is signed with Ed25519.

Receipt Structure

interface SignedReceipt {
  version: string;           // Schema version ("1.0")
  timestamp: string;         // ISO 8601 UTC timestamp
  sessionId: string;         // Your session identifier
  agentId: string | null;    // AI model/agent identifier
  promptHash: string;        // SHA-256 of canonicalized input
  responseHash: string;      // SHA-256 of AI response content
  scores: Record<string, number>;  // User-defined attestation scores (0-1)
  prevReceiptHash: string | null;  // Hash chain to previous receipt
  receiptHash: string;       // SHA-256 of this receipt's payload
  signature: string;         // Ed25519 signature (hex)
  metadata: object;          // Custom metadata
}

Key Generation

// Generate a new key pair
const { privateKey, publicKey } = await TrustReceipts.generateKeyPair();

console.log('Private Key:', privateKey); // Store securely!
console.log('Public Key:', publicKey);   // Share for verification

Hash Chaining

Link receipts for an immutable audit trail:

const { receipt: r1 } = await receipts.wrap(call1, { sessionId: 's1', input: q1 });
const { receipt: r2 } = await receipts.wrap(call2, {
  sessionId: 's1',
  input: q2,
  previousReceipt: r1  // Chain to previous
});

// r2.prevReceiptHash === r1.receiptHash

Verification

// Verify single receipt
const valid = await receipts.verifyReceipt(receipt, publicKey);

// Verify entire chain
const result = await receipts.verifyChain([r1, r2, r3], publicKey);
console.log(result.valid);   // true if all signatures and chains valid
console.log(result.errors);  // Array of any errors found

Bitcoin Anchoring (OpenTimestamps)

For stronger timestamp guarantees, anchor receipt hashes to Bitcoin:

import { TrustReceipts, anchor, upgradeAnchor } from '@yseeku/trust-receipts';

const { receipt } = await receipts.wrap(aiCall, { sessionId: 's1', input });

// Submit to OpenTimestamps calendar servers
const proof = await anchor(receipt.receiptHash);
console.log('Anchored to calendars:', proof.calendars);
console.log('Status:', proof.status); // 'pending' initially

// Store the proof with your receipt
await saveToDatabase({ receipt, anchorProof: proof });

// Later (after ~1-2 hours), upgrade to get Bitcoin confirmation
const upgraded = await upgradeAnchor(proof);
if (upgraded.status === 'confirmed') {
  console.log('Confirmed in Bitcoin block:', upgraded.bitcoinBlock);
}

How it works:

  1. Your receiptHash is submitted to OpenTimestamps calendar servers
  2. Calendars aggregate hashes into a Merkle tree
  3. The Merkle root is committed to Bitcoin (~hourly)
  4. Your proof can be independently verified against the blockchain

Chain anchoring: Since receipts are hash-chained, anchoring the final receipt transitively anchors the entire conversation:

import { anchorChain } from '@yseeku/trust-receipts';

// Anchor entire conversation with one proof
const chainProof = await anchorChain([r1.receiptHash, r2.receiptHash, r3.receiptHash]);

Scores & Attestation

Scores are user-defined attestation values — the SDK does not compute them. You define your own rubric and the SDK cryptographically signs whatever scores you provide.

Each score is a float between 0 and 1 keyed by a name you choose:

const { receipt } = await receipts.wrap(aiCall, {
  sessionId: 'session-1',
  input: messages,
  scores: {
    clarity: 0.95,      // Your clarity rubric
    accuracy: 0.88,     // Your accuracy rubric
    safety: 0.99,       // Your safety rubric
    compliance: 0.92,   // Your compliance rubric
  },
});

Common score patterns:

  • Quality: { clarity, coherence, relevance } — language quality metrics
  • Safety: { safety, toxicity, bias } — content safety metrics
  • Compliance: { pii_check, policy_adherence, audit_score } — regulatory metrics

For computed scores, provide a calculateScores function:

const receipts = new TrustReceipts({
  privateKey: process.env.SONATE_PRIVATE_KEY,
  calculateScores: (prompt, response) => ({
    wordCount: Math.min(String(response).length / 1000, 1),
    hasCodeBlock: String(response).includes('```') ? 1 : 0,
  }),
});

Streaming Support

For streaming responses, create receipts manually after accumulating the response:

let fullResponse = '';
const stream = anthropic.messages.stream({ ... });

for await (const event of stream) {
  fullResponse += event.text;
}

const receipt = await receipts.createReceipt({
  sessionId: 'stream-session',
  prompt: messages,
  response: fullResponse,
  previousReceipt: lastReceipt,
  scores: { completeness: 0.95 },
});

Privacy

By default, only SHA-256 hashes of prompt and response are included in receipts. The original content is never stored unless you explicitly opt in.

Hash-only (default): Proves integrity without exposing sensitive data. Third parties can verify that content hasn't been tampered with by comparing hashes, but cannot reconstruct the original content.

Full content (opt-in): Set includeContent: true for use cases like internal audit logs where you need the complete interaction record:

// Default: hashes only (privacy-preserving)
const { receipt } = await receipts.wrap(aiCall, {
  sessionId: 's1',
  input: messages,
});
// receipt.promptHash = "a1b2c3..."
// receipt.promptContent = undefined

// Opt-in: include full content
const { receipt: fullReceipt } = await receipts.wrap(aiCall, {
  sessionId: 's1',
  input: messages,
  includeContent: true,
});
// fullReceipt.promptHash = "a1b2c3..."
// fullReceipt.promptContent = [{ role: "user", content: "..." }]
// fullReceipt.responseContent = "The AI response text..."

Anthropic Example

import Anthropic from '@anthropic-ai/sdk';
import { TrustReceipts } from '@yseeku/trust-receipts';

const anthropic = new Anthropic();
const receipts = new TrustReceipts({
  privateKey: process.env.SONATE_PRIVATE_KEY,
  defaultAgentId: 'claude-3-sonnet',
});

const messages = [{ role: 'user', content: 'Explain trust receipts.' }];

const { response, receipt } = await receipts.wrap(
  () => anthropic.messages.create({
    model: 'claude-3-sonnet-20240229',
    max_tokens: 1024,
    messages,
  }),
  { sessionId: 'claude-session', input: messages }
);

Cryptographic Details

| Component | Specification | |-----------|--------------| | Signing | Ed25519 (RFC 8032) | | Hashing | SHA-256 | | Canonicalization | JSON Canonicalization Scheme (RFC 8785) | | Key Size | 32 bytes (256 bits) | | Signature Size | 64 bytes (512 bits) | | Timestamp | ISO 8601 UTC | | Anchoring | OpenTimestamps (Bitcoin) |

Public Key Discovery

For production deployments, publish your public key at a well-known location:

https://yourdomain.com/.well-known/sonate-keys.json

Example format:

{
  "keys": [{
    "id": "default",
    "publicKey": "abc123def456...",
    "algorithm": "Ed25519",
    "created": "2026-02-18T00:00:00Z"
  }]
}

This allows third parties to verify your receipts without out-of-band key exchange.

Timestamp Guarantees

Receipts include three layers of temporal proof:

| Layer | Guarantee | Trust Model | |-------|-----------|-------------| | timestamp | ISO 8601 UTC timestamp | Self-reported (system clock) | | Hash chain | Ordering proof — receipt N+1 references receipt N | Cryptographic (SHA-256) | | anchor() | Bitcoin-backed proof of existence | Decentralized (OpenTimestamps) |

Self-reported timestamps are sufficient for most audit trails. Hash chaining ensures ordering cannot be forged even if individual timestamps are approximate.

For stronger non-repudiation, use anchor() to submit receipt hashes to OpenTimestamps calendar servers, which commit them to Bitcoin (~hourly). This provides blockchain-backed proof that a receipt existed at a specific time:

import { anchor } from '@yseeku/trust-receipts';

const proof = await anchor(receipt.receiptHash);
// proof.status = 'pending' → 'confirmed' after Bitcoin block

Known Limitations & Roadmap

Large Payloads

Current: Full prompt/response content is hashed. SHA-256 is fast (~5ms for 1MB), but very large payloads may add latency.

Mitigation: Use extractResponse option to hash only relevant fields, or store content externally with receiptHash as reference.

const { receipt } = await receipts.wrap(fn, {
  sessionId: 's1',
  input: messages,
  extractResponse: (r) => r.choices[0].message.content, // Hash only the text
});

Key Management

Current: Keys are provided by the caller. No built-in key rotation or HSM support.

Roadmap: Key rotation helpers, HSM/KMS integration guides.

Use Cases

  • Compliance: Audit trails for regulated industries (healthcare, finance)
  • Debugging: Trace issues through conversation history
  • Analytics: Track quality metrics over time
  • Security: Detect prompt injection or response tampering
  • Accountability: Prove what was said and when

Related Packages

  • @yseeku/verify-sdk — For verifying SONATE platform receipts (server-side verification of receipts generated by the SONATE backend)
  • @yseeku/trust-receipts (this package) — For generating receipts in your own applications

License

MIT