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

@adasouls/alma-core

v0.8.0

Published

ALMA protocol core: identifiers, Subject/Principal identity, delegation, credentials, the relationship graph, and reputation evidence.

Readme

@adasouls/alma-core

The core of the ALMA protocol: persistent identity, delegated authority, credentials, relationships, reputation evidence and counterparty receipts for humans, organizations and AI agents. Pure TypeScript, validated with zod, runs in Node and browsers.

npm install @adasouls/alma-core

Identifiers

alma:<network>:<subject-type>:<local-id>
alma:main:agent:treasury
alma:main:org:tribu-raes        # "org" is accepted as short for "organization"
import { parseIdentifier, formatIdentifier, isValidIdentifier } from "@adasouls/alma-core";

parseIdentifier("alma:main:org:tribu-raes");
// { network: "main", subjectType: "organization", localId: "tribu-raes", subjectTypeSegment: "org" }

An identifier is stable: controllers (wallets, DIDs, endpoints) can change without changing it.

What's in the box

| Area | Main exports | |---|---| | Identity | createIdentity, parseIdentifier, formatIdentifier, isValidIdentifier, SUBJECT_TYPES (human, organization, agent) | | Delegation | createDelegation, revokeDelegation, isNarrowerScope — who may act for whom, with which capabilities | | Credentials | createCredentialEvidence, revokeCredential — formats w3c-vc, sd-jwt, erc8004, alma-native | | Relationships | createRelationship, hasRelationship, findPath, assertNoDelegationCycle | | Reputation evidence | recordEvidence — append-only; evidence, not a score | | Receipts | buildReceiptStatement, canonicalizeReceipt, receiptDigest, generateReceiptSalt, toBaseUnits | | Issuer signatures | signReceiptMint, signReceiptAttestation, verifyReceipt, createIssuerKeyset, toJwks, LocalSigner, IssuerSigner | | Agent reports | signAgentReport, verifyAgentReport, AGENT_REPORT_METRICS | | Job deliveries | signJobDelivery, verifyJobDelivery, jsonDigest, canonicalJsonValue | | Transparency log | envelopeLeafHash, merkleRoot, appendToFrontier, inclusionProof, verifyInclusion, consistencyProof, verifyConsistency, signTreeHead, verifyTreeHead |

Validation failures throw AlmaValidationError naming the field and reason.

Receipts (alma-receipt/1)

A receipt is the canonical statement that one settled payment happened between a payer and an identified payee. The encoding is unambiguous so any implementation reproduces the same bytes: RFC 8785 (JCS) over a flat object of printable-ASCII strings, integer base-unit amounts, CAIP-2 chain and CAIP-19 asset ids, plus issuer and env (mainnet / testnet / mock).

import { buildReceiptStatement, receiptDigest, toBaseUnits } from "@adasouls/alma-core";

const statement = buildReceiptStatement({
  issuer: "adasouls",
  env: "testnet",
  action: "eco_123",
  payer: "alma:main:agent:buyer",
  payee: "alma:main:agent:vendor",
  capability: "pay",
  chain: "eip155:84532",
  asset: "eip155:84532/erc20:0x036cbd53842c5426634e7929541ec2318f3dcf7e",
  amount: toBaseUnits("12.5", 6), // "12500000" -- never rounds
  to: "0x…",
  txHash: "0x…",
});
const digest = await receiptDigest(statement); // SHA-256, hex

Issuer signatures

The issuer signs what it asserts about a receipt with Ed25519: a mint ("I issued this statement", plus whether the two parties are independent) and each attestation ("this party confirmed/declined payment or delivery, at this time"). Payloads follow the same JCS rules, carry the issuer and key id, and are bound to one receipt id and statement digest. Signatures are plain RFC 8032 Ed25519, so any signer works: LocalSigner (Web Crypto) for development, or AWS KMS (ECC_NIST_EDWARDS25519, ED25519_SHA_512, MessageType: RAW) behind the IssuerSigner interface.

verifyReceipt checks everything at once and returns only the signed facts. Use those, not your own copy of the data:

import { createIssuerKeyset, verifyReceipt } from "@adasouls/alma-core";

// Pin keys from a source you trust (config, a published fingerprint),
// not from wherever the receipt came from.
const keyset = await createIssuerKeyset([{ iss: "adasouls", publicKey: "<base64url raw key>" }]);
const r = await verifyReceipt({ id, statement, mint, payment, delivery }, keyset);
if (r.ok) r.payload; // { statement, digest, independent, payment, delivery }
else r.reason;       // e.g. "mint: statement does not match the signed digest"

Key ids are ed25519- plus the first 16 bytes of SHA-256 of the public key, so a keyset computes them itself.

Transparency log

Signatures catch edits; a log catches deletions. The issuer appends every signed envelope to an append-only Merkle tree (RFC 9162 hashing, the Certificate Transparency design) and signs tree heads (size + root). A party that kept an envelope can prove it's in the log, and anyone holding an older tree head can check the log only ever grew:

import { envelopeLeafHash, verifyConsistency, verifyInclusion, verifyTreeHead } from "@adasouls/alma-core";

const head = await verifyTreeHead(sth, keyset, "adasouls-receipts-mainnet");
if (!head.ok) throw new Error(head.reason);
const { treeSize, rootHash } = head.payload; // always use size and root together
await verifyInclusion(await envelopeLeafHash(envelope), index, treeSize, proof, rootHash);
await verifyConsistency(oldSize, treeSize, oldRoot, rootHash, consistency); // nothing removed or rewritten

A leaf commits to the envelope's signature, so a published leaf hash reveals nothing about a receipt to anyone who doesn't already hold it.

Agent reports

Some figures only the agent knows: what a piece of work cost it to compute, which model did it. The protocol asks the agent to report them, and the issuer signs each one as an alma-agent-report/1 envelope: "this agent declared this figure, about this action or job, at this time". It goes into the same transparency log as receipts.

import { verifyAgentReport } from "@adasouls/alma-core";

const report = await verifyAgentReport(envelope, keyset);
if (!report.ok) throw new Error(report.reason);
const { agent, about, ref, metric, value, unit, reportedAt } = report.payload;

Metrics in v1: compute_cost (a decimal plus a currency unit), model, input_tokens, output_tokens, duration_ms.

A verified report proves who declared what and when, and the log proves the declaration was never changed or removed. Neither proves the figure is true: show it as declared by the agent, apart from what the issuer verified itself.

Job deliveries

When an agent is hired through the issuer, the issuer calls it and gets its answer. It then signs an alma-job-delivery/1 envelope: "this agent returned a result with this digest for this job, at this time", and logs it. The result itself stays with the two parties.

import { jsonDigest, verifyJobDelivery } from "@adasouls/alma-core";

const delivery = await verifyJobDelivery(envelope, keyset);
if (!delivery.ok) throw new Error(delivery.reason);
// Holding a result: is it the one that was delivered?
const same = (await jsonDigest(result)) === delivery.payload.resultDigest;

jsonDigest is SHA-256 over the value's canonical JSON (RFC 8785), so key order and spacing don't matter. The envelope names the seller and not the buyer. It proves the work was handed over, not that it was good: that is the buyer's delivery attestation on the receipt.

License

MIT