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

@ar.io/anchor

v0.1.2

Published

Anchor-at-write-time for the ar.io verification stack. Hash your data locally, sign a Verifiable Event Envelope (ario.events/v1), and anchor it to ar.io — permanent, tamper-evident provenance with Merkle-batched checkpoints and per-event inclusion proofs.

Downloads

427

Readme

@ar.io/anchor

Anchor-at-write-time for the ar.io verification stack: hash your data locally, sign a Verifiable Event Envelope under the ario.events/v1 profile, and anchor it to ar.io — no relay, no SDK bloat, raw bytes never leave your system.

Write through Turbo — ar.io's upload service. Read it back through any ar.io gateway — turbo-gateway.com, or any of the others at gateways.ar.io; you're never locked to one provider. Underneath, it's stored permanently on Arweave.

npm install @ar.io/anchor
import { createAnchorer } from "@ar.io/anchor";

// Dev mode: zero config. Auto identity + wallet; small uploads are free on Turbo.
// Proofs are permanently marked environment:"dev" inside the signed bytes.
const ario = createAnchorer();

const receipt = await ario.anchor({
  type: "event",
  data: fileBytes,            // or a string, or an AsyncIterable (streams),
  // contentHash: "...",      // or a pre-computed sha256 — exactly one
  ref: "s3://bucket/key",     // optional locator
  metadata: { approver: "alice" },
  chain: "orders",            // optional per-key hash chain
});

receipt.txId;          // ar.io transaction id (resolved once Turbo accepts the upload)
receipt.envelope;      // the signed, Minimal-disclosure envelope
receipt.recordBytes;   // RETAIN THESE — the committed event record
receipt.gatewayUrl;    // resolve on any ar.io gateway (gateways.ar.io)

Batching

High-frequency events (LLM steps, pipeline records): one ar.io write per window, while every event keeps its own offline-verifiable inclusion proof.

const batch = ario.batch({
  maxEvents: 100,     // flush when full…
  maxAge: 60_000,     // …or 60s after the first buffered event…
  flushOnIdle: 5_000, // …or 5s after the last add. First trigger wins.
});

const receipt = await batch.add({ data: JSON.stringify(step) }).receipt();
// → { checkpointTxId, root, leafHash, leafIndex, auditPath, envelope, recordBytes, ... }

await ario.close(); // explicit flush — call it on shutdown; nothing is flushed for you

add() is synchronous (bytes/string/pre-computed hash — no streams here). A batch of one is valid. With the default in-memory buffer a crash loses buffered proofs, never data — every event is re-anchorable from your system.

Verifying

Fetch the envelope by txId from any ar.io gateway — https://<gateway>/raw/<txId> (e.g. turbo-gateway.com; browse the network at gateways.ar.io). With that envelope and your retained recordBytes, anyone verifies offline with the read-only @ar.io/proof:

import { ed25519Verify, jcs, sha256Hex, utf8 } from "@ar.io/proof";

const { signature, ...preSignature } = receipt.envelope;
await ed25519Verify(signature, utf8(jcs(preSignature)), receipt.envelope.public_key); // true
(await sha256Hex(receipt.recordBytes)) === receipt.envelope.payload_hash;             // true

Batched events verify their inclusion the same way — see the runnable examples.

Production

Production structurally refuses auto-generated secrets — it throws unless you pass all three:

import { createAnchorer, LocalEd25519Signer, SolanaWalletSigner } from "@ar.io/anchor";

const ario = createAnchorer({
  environment: "production",
  // Identity key (signs envelopes). Any { publicKey(), sign() } works —
  // file seed shown; Vault/KMS adapters implement the same interface.
  signer: LocalEd25519Signer.fromSeedHex(process.env.ANCHOR_IDENTITY_SEED!),
  // Funding wallet (pays Turbo) — a different key, Solana ed25519 default.
  wallet: new SolanaWalletSigner(LocalEd25519Signer.fromSeedHex(process.env.ANCHOR_WALLET_SEED!)),
  subject: { type: "producer", producer_id: "acme-app" },
});

The two keys are deliberately separate: identity (who signed) vs money (who pays). Fund the wallet with Turbo Credits at https://turbo.ardrive.io.

Errors

All errors carry a machine-checkable code:

| Class (code) | When | Do | |---|---|---| | FundingExhaustedError (FUNDING_EXHAUSTED) | Turbo 402 — wallet out of funds | Fund the wallet; the message includes instructions. Not retryable as-is. | | UploadFailedError (UPLOAD_FAILED) | 5xx/429/network, retries exhausted | Transient — safe to retry the same anchor() call. | | UploadRejectedError (UPLOAD_REJECTED) | Terminal 4xx from Turbo | Inspect the detail; retrying the same bytes won't help. | | TxIdMismatchError (TXID_MISMATCH) | Upstream returned a TX ID that doesn't match the signature-derived one | Should never happen with an honest upstream — treat the upload as suspect. | | ProductionConfigError (PRODUCTION_CONFIG) | Production mode without explicit signer/wallet/subject | Supply the missing credentials; dev secrets cannot reach production. |

A failed batch window rejects only that window's receipt() promises — the chain head is untouched and the next window proceeds; re-add the events to re-anchor them.

Guarantees

  • Local hashing only. data is hashed in-process (streams supported); only the signed envelope (a few hundred bytes) is uploaded.
  • Minimal disclosure. The on-chain envelope carries no event type, no subject, no chain pointer — those live in the hash-committed record you retain.
  • Dev proofs are cryptographically dev. environment sits inside the signed scope; a dev proof can never be presented as production evidence.
  • Verification is a separate, read-only package@ar.io/proof. This package contains the write path only.

Conformance

Byte-for-byte against the family corpus (ar-io-proof test-vectors-v1.1); ANS-104 output byte-pinned vs arbundles and re-verified by an independent Python parser in CI. See the profile spec.