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

@vibingminers/sdk

v0.1.1

Published

TypeScript SDK for trace.ai — submit DR-1 decision receipts and verify on-chain anchored attestations on Base.

Readme

@vibingminers/sdk

TypeScript SDK for trace.ai — submit DR-1 decision receipts and verify on-chain anchored attestations on Base.

Decision records are AI receipts. Hash the prompt, the model output, the rationale; sign it; anchor a Merkle root on Base Sepolia (and soon Base mainnet). Anyone with the receipt URL can verify the AI didn't lie.


Install

pnpm add @vibingminers/sdk @anthropic-ai/sdk
# or: npm install @vibingminers/sdk @anthropic-ai/sdk
# or: yarn add @vibingminers/sdk @anthropic-ai/sdk

Then grab a free API key in 60 seconds and add it to your environment:

LEDGERLINE_API_KEY=lgl_live_...

Quickstart — three lines

import Anthropic from '@anthropic-ai/sdk';
import { traceClaude } from '@vibingminers/sdk';

// 1. Wrap your Anthropic client.
const claude = traceClaude(new Anthropic(), { agentId: 'cs-agent-v3' });

// 2. Use it like normal — every call now ships a receipt.
const response = await claude.messages.create({
  model: 'claude-opus-4-7',
  messages: [{ role: 'user', content: 'Approve refund for order #4271?' }],
  trace: {
    decisionClass: 'approve',
    rationale: 'within refund window',
  },
});

// `response` is the standard Anthropic response.
// Receipt fires in the background — verifier URL goes to console
// (or pass `onReceipt` to capture it programmatically).

Need both response AND receipt awaited?

const claude = traceClaude(new Anthropic(), {
  agentId: 'cs-agent-v3',
  onReceipt: (info) => {
    if (info.ok) console.log('verifier:', info.verifierUrl);
  },
});

Manual / fine-grained control

If you want to construct a record without an LLM call (e.g. a pure rule-based decision), use the lower-level builder + client directly:

import { LedgerlineClient, DecisionRecordBuilder } from '@vibingminers/sdk';

const ledger = new LedgerlineClient();
const record = new DecisionRecordBuilder({ agentId: 'rules-engine', decisionClass: 'reject' })
  .setUserPrompt('refund request, day 47')
  .addLlmCall({ provider: 'other', model: 'rules-engine-v2', prompt: '...', response: '...' })
  .select({ output: 'reject' })
  .withRationale({ summary: 'outside 30-day refund window' })
  .build();

const { decision_id, verifierUrl } = await ledger.submit(record);

First-time setup (one-time, ~60 seconds)

# 1. Self-serve an API key — one form field, one HTTP request, done.
#    https://trace-ai-inky.vercel.app/signup

# 2. Drop it in .env
LEDGERLINE_API_KEY=lgl_live_...

That's it. The SDK reads it from env automatically.

Optional: stronger non-repudiation with operator signatures

By default the platform anchors records on your behalf. If you want each record cryptographically signed by you (so a third party can prove the record came from your key, not just our server), set an operator key:

# Generate a fresh secp256k1 key (32-byte hex, 0x-prefixed).
node -e "console.log(require('@vibingminers/sdk').generateOperatorKey())"
# Add to .env alongside your API key.
LEDGERLINE_OPERATOR_PK=0x...

The SDK will sign every record with this key automatically.

Configuration

Either pass options to the constructor or set environment variables.

| Option | Env var | Required | Default | |---------------|----------------------------|----------|--------------------------------------| | apiKey | LEDGERLINE_API_KEY | yes | — | | baseUrl | LEDGERLINE_BASE_URL | no | https://trace-ai-inky.vercel.app | | operatorPk | LEDGERLINE_OPERATOR_PK | no | — (signing skipped if missing) | | fetch | — | no | globalThis.fetch |

When the server runs in demo mode (default for the public testnet deployment), operatorPk is required. The SDK signs the canonical record digest with secp256k1 and attaches operator_signature automatically.

API

new LedgerlineClient(opts?)

const ledger = new LedgerlineClient({
  apiKey: 'lgl_live_...',
  baseUrl: 'https://your-trace-ai.example.com',
  operatorPk: '0x...',
});

ledger.submit(record): Promise<SubmitResult>

Submits a built DR-1 record to POST /api/v1/traces. Auto-signs if operatorPk is configured. Returns { decision_id, accepted, verifierUrl }.

ledger.verify(decisionId): Promise<unknown>

Hits GET /api/v1/verify?decision_id=.... Returns the server's verification report. Throws LedgerlineError on non-2xx.

new DecisionRecordBuilder({ agentId, decisionClass, ... })

Fluent builder. All free-form fields (prompt, response, output, evidence) are SHA-256 hashed automatically — never store unhashed PII in the receipt.

const record = new DecisionRecordBuilder({
  agentId: 'loan-agent-v1',
  decisionClass: 'approve',
  riskLevel: 'low',
  subject: 'application:#1234',
})
  .setUserPrompt(prompt)
  .addEvidence(applicationDocText)
  .policyRefs(['policy:credit:v4.1'])
  .addLlmCall({ provider: 'anthropic', model: 'claude-opus-4-7', prompt, response })
  .addToolCall({ tool: 'credit-bureau', args: { ssn: '...' }, result: { score: 740 } })
  .select({ output: response })
  .withRationale({ summary: 'credit score above threshold; no flags' })
  .humanInTheLoop('reviewer:abc123')
  .build();

Required calls before .build():

  • .addLlmCall(...) — at least once
  • .select({ output }) — exactly once
  • .withRationale({ summary }) — exactly once

What gets anchored on-chain

  1. Canonical hash — SHA-256 of RFC 8785 canonical JSON of the record.
  2. Merkle root — built across a batch of records by the trace.ai notary.
  3. EAS attestation — submitted to the Ethereum Attestation Service on Base Sepolia, signed by the trace.ai attester key.

The verifier endpoint reconstructs and re-validates all three: canonical hash match, Merkle inclusion proof, and on-chain attestation UID lookup.

License

MIT.