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

@dregg/sdk

v0.3.0

Published

TypeScript SDK for dregg — authorization-first turns, receipts, the organ nouns (trustline, channels, mailbox), attested-query light-client reads, profiles, events, and the cell-program constraint language

Downloads

167

Readme

@dregg/sdk

TypeScript SDK for dregg. Two user-facing nouns and one shape:

Identity → .turn() → typed verb builders → .sign() → .submit() → Receipt

An unauthorized act is inexpressible on the public surface: every action carries a real Ed25519 Authorization::Signature over the canonical federation-bound signing message, and every submission rides a SignedTurn envelope over the canonical Turn::hash. The raw vocabulary (including unauthorized construction) is sealed behind @dregg/sdk/raw.

This package mirrors the Rust SDK (sdk/) shape-for-shape and byte-for-byte: key derivation, postcard wire encoding, canonical hashes, and signing preimages are differentially tested against the repo's own dregg-wasm build, and the identity derivation is pinned by the same golden vector as the Rust SDK, CLI, and browser extension — if any implementation drifts, all of them fail together.

Walkthrough (local node)

There is no public server (the former devnet.dregg.fg-goose.online is offline); run a node locally first — see QUICKSTART.md (dregg-node init … && dregg-node run --enable-faucet --port 8421). On a remote/operator node the signed-turn ingress is operator-gated (devnetKey / $DREGG_API_TOKEN); on your own --enable-faucet dev node it is open.

import { AgentRuntime, Identity, NodeClient, ReceiptFilter, profiles } from "@dregg/sdk";

// 1. A named identity — the same $DREGG_HOME/profiles store as `dregg id`.
const identity = profiles.loadActive() ?? (profiles.create("me"), profiles.load("me"));

// 2. Bind to a node (your local dev node, or a remote node + its operator token).
const node = new NodeClient("http://localhost:8421", {
  devnetKey: process.env.DREGG_DEVNET_KEY, // only needed for an operator-gated remote node
});
const runtime = new AgentRuntime(identity, node);

// 3. Materialize + fund the agent cell (devnet faucet).
await runtime.faucet(2000);

// 4. Observe before acting.
const stream = node.events().subscribe(new ReceiptFilter().cell(identity.cellId()));

// 5. The one public turn shape.
const authorized = await runtime.turn().writeU64(0, 42n).fee(1000).sign();
console.log(authorized.explain()); // the anti-blind-signing reading, [sem]-tagged
const receipt = await authorized.submit();

// 6. The same noun arrives on the nervous system.
for await (const observed of stream) {
  if (observed.turnHash === receipt.turnHash) break;
}

// 7. The STARK attaches lazily (the node's async prove pool).
const proof = await node.turnProof(receipt.turnHash);
if (proof) receipt.attachProof(proof);

Runnable version: node examples/devnet-walkthrough.mjs (after npm run build).

The organ nouns

Above the two base nouns sit the organs (docs/ORGANS.md) — the higher primitives. Each is the ergonomic TS face of a node service: the node computes the per-cell factory descriptors and seal fan-outs (Poseidon2 commitments, X25519 key schedules) that the TS wire layer does not carry, and these clients drive them. Every organ module documents an Honest scope for the node-side/client-side line.

Trustline — the bilateral line of credit (§1)

A line issuer → holder of N is an attenuated capability whose exercise debits a shared counter; the executor-installed cell program enforces drawn ≤ ceiling for life. Operator-gated (the node operator is the issuer).

const tl = runtime.trustline();
const line = await tl.open(holderCellHex, 1000n); // four-turn funded birth
await tl.draw(line.trustline, 250n);              // debit the shared counter (one-shot digest)
await tl.repay(line.trustline, 100n);             // restore the line
const pos = await tl.status(line.trustline);      // { line, drawn, remaining, escrow, open }
await tl.settle(line.trustline);                  // redeem outstanding to the holder

Runnable: node examples/trustline.mjs.

Channels — the group-key epoch lift (§4)

A group is a cell; the membership root, key epoch, and key commitment live on-cell. remove(m) darkens both m's forward-read ability and their group-held capabilities in one atomic epoch step (the keystone — surfaced as the epochs_unified invariant). Message bodies never touch the chain: encrypt under the current epoch key client-side, post only ciphertext.

const ch = runtime.channels();
const g = await ch.create(7, [{ cell: aliceHex, sealPk: aliceSealHex }]);
await ch.join(g.channel, { cell: bobHex, sealPk: bobSealHex }); // → fresh sealed fan-out
await ch.post(g.channel, g.epoch, nonceHex, ciphertextHex);     // body, ciphertext only
await ch.remove(g.channel, bobHex);                             // bob darkened in ONE turn
for await (const m of ch.messages(g.channel)) { /* SSE delivery */ }

Runnable: node examples/channel.mjs.

Mailbox — a hosted inbox over the relay (§2)

A store-and-forward inbox on the network-facing relay (its own port, default :3100). Subscribe / drain are Ed25519-signed by the inbox owner (this client signs them — differentially checked against the Rust signing path); sending is open. The relay sees only ciphertext.

const mb = new MailboxClient("http://relay.example:3100", identity);
await mb.subscribe();                     // create your hosted inbox
// elsewhere: someone seals a body and POSTs it to your pubkey
const { messages } = await mb.drain(50);  // each carries a dequeue (custody) proof

Honest scope: sealing/opening (X25519 → ChaCha20-Poly1305) and re-running the dequeue Merkle verifier are NOT done in pure TS — bring sealed ciphertext and verify custody proofs via @dregg/sdk/wasm or the Rust SDK.

Attested query — the light-client read surface (Noun 2's TS face)

The read-only twin: no identity, no signing. Fetch the federation-attested state roots, finalized checkpoints, and a committed turn's full-turn STARK.

// The federation-attested roots/checkpoints + standalone STARK are produced by
// blocklace finalization across a committee, so they are empty/404 on a SOLO node;
// boot the local federation (`demo/multi-node-devnet`, QUICKSTART §9) to see them.
const aq = new AttestedQuery("http://127.0.0.1:7811");
const roots = await aq.attestedRoots();        // federation-signed roots (+ signature count)
const cp = await aq.checkpoint();              // latest finalized checkpoint (+ qc votes)
const proof = await aq.turnProof(turnHashHex); // full-turn STARK BYTES

Honest scope: verifying a STARK or a threshold signature is a Rust/wasm operation — pure TS surfaces the artifacts to verify elsewhere, it does not return a checked verdict on its own.

Runnable: node examples/attested-query.mjs.

DreggDL — the checkable deployment spec (DeployChecker)

Write a dregg capability layout once, declaratively (TOML / JSON), and check it for the four static guarantees — conservation, non-amplification, well-formedness, ring-balance — over the WHOLE declared authority layout BEFORE submitting, exactly like the Rust dregg-deploy check CLI:

import init from "dregg-wasm";
import { DeployChecker } from "@dregg/sdk";

const deploy = new DeployChecker(await init());
const v = deploy.check(toml);          // { pass, assurance, factories, cells, turn_count }
if (!v.pass) {
  for (const f of v.assurance.findings) {
    console.error(`${f.guarantee}: ${f.message} @ ${f.locus.display}`);
  }
}
const lowered = deploy.lower(toml);    // the ordered CallForest the checker consumes

DeployChecker is a thin binding over the REAL dregg-deploy crate (parse → Lowered::from_deploymentdregg_userspace_verify::analyze), reached through the dregg-wasm deploy_check / deploy_lower exports. The lowering and the checks are NOT reimplemented in TypeScript — a deployment audited from TS is audited by the exact same code as dregg-deploy check. An over-granting deployment FAILs with the located amplification.

Surface

| Export | Purpose | |--------|---------| | Identity | Ed25519 identity; blake3 derive_key("dregg/0", seed64) derivation | | profiles | Shared $DREGG_HOME/profiles named-identity store (dregg id …) | | NodeClient / AgentRuntime | A node's HTTP surface / an identity bound to it | | TurnBuilder / AuthorizedTurn | Typed verbs → .sign().submit(); empty turns refused | | Receipt / TurnProof | Proof-of-execution noun; STARK lazily attached, mis-bound attachments refused | | NodeEvents / ReceiptFilter | subscribe(filter)AsyncIterable<Receipt> (SSE, Last-Event-ID resume, reconnecting) | | explainTurn / renderTurn / explainAction / explainEffect | The clerk's faithful reading: total, [sem <digest>]-tagged (equal text ⇒ equal semantics) | | program | Cell-program atoms (senderIs / senderInSlot / balanceGte / balanceLte / preimageGate, anyOf / not / implies) + content-addressed factory descriptors | | TrustlineClient | Organ §1 — open / draw / repay / settle / close / status (runtime.trustline()) | | ChannelsClient | Organ §4 — create / join / remove / rekey / post / status / messages (runtime.channels()) | | MailboxClient | Organ §2 — subscribe / send / drain / unsubscribe over the relay (owner-signed) | | AttestedQuery | Light-client reads — attestedRoots / checkpoint / turnProof (no identity) | | DeployChecker | DreggDL — check(text, ring?) / lower(text) via the REAL dregg-deploy (parse → lower → userspace-verify), through dregg-wasm |

Turn verbs

transfer(to, amount) · transferFrom(from, to, amount) · write(index, value) · writeU64(index, n) · grant(to, cap) · incrementNonce() · effect(e) / effects(list) · modifiers on(target) · method(name) · fee(n).

Unlike the Rust in-process runtime there is no .asCell(..): the remote signed ingress pins turn.agent to the signer's default cell.

Sealed: @dregg/sdk/raw

The wire vocabulary (postcard encoders, canonical hashes, signing preimages, unsignedAction). Quarantined exactly like the Rust SDK's sdk/src/raw.rs: if you import it in application code you are almost certainly building something the executor will reject.

Legacy: @dregg/sdk/wasm

The pre-refinement wasm-bound playground client (DreggClient, DreggRuntime, proof/Merkle/Datalog toys) — unchanged, for existing consumers.

Building from a fresh clone

The package's core (Identity / turns / receipts / events / organs / program) is pure TypeScript — no runtime wasm dependency. But the legacy @dregg/sdk/wasm and @dregg/sdk/browser entry points, and the differential-test oracle, import the repo's own dregg-wasm build (file:../wasm/pkg, a dev/peer dependency). So a fresh clone must build that package first, or the .d.ts emit step of npm run build fails with Cannot find module 'dregg-wasm':

# from the repo root — build the wasm package the SDK differentials against
(cd wasm && wasm-pack build --target web --out-dir pkg)
# then, in this package
cd sdk-ts && npm ci && npm run build

In Docker, mount the repo root (not just sdk-ts/) so the ../wasm/pkg path dependency resolves:

docker run --rm -v "$PWD":/repo -w /repo/sdk-ts node:22 \
  bash -c "npm ci && npm run build && npm test"

Tests

npm test   # build + node --test  (needs ../wasm/pkg — see above)
  • Differential: TS-built signed turns are byte-identical (postcard encoding AND canonical Turn::hash v3) to the Rust implementation via the repo's dregg-wasm build; BLAKE3 is differentially tested across chunk boundaries.
  • Golden vector: seed 00..3f → pubkey 335840a9…8b9a, the same pin as sdk/src/profiles.rs, cli/src/commands/id.rs, and extension/test/derivation.test.mjs.
  • Profile store, SSE resume/reconnect, explain totality + sem-tag discrimination, program content-addressing.

License

AGPL-3.0-or-later