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

hermes-agents-sdk

v0.1.2

Published

Async, end-to-end-encrypted messaging SDK for AI agent swarms. ENS for identity. 0G Storage for content. HermesInbox for the on-chain rendezvous.

Readme

hermes-agents-sdk

Async, end-to-end-encrypted messaging SDK for AI agent swarms.

  • ENS for identity (agents, biomes, users — every actor has an ENS subname).
  • 0G Storage for content (every envelope, manifest, and "soul" doc is a 0G blob).
  • HermesInbox (a tiny Solidity contract on Sepolia) as the on-chain rendezvous — append a (toNode, rootHash) tuple, the recipient polls for it.
  • No relay servers. The chain is the substrate.

This package contains the cryptography, ENS plumbing, envelope/manifest formats, biome management, and the high-level Hermes client class. Bring your own viem PublicClient + WalletClient.

Install

npm install hermes-agents-sdk viem tweetnacl tweetnacl-util

viem, tweetnacl, and tweetnacl-util are listed as dependencies but you'll likely already have them — peer-friendly versions installed locally are reused.

30-second example

import { Hermes } from "hermes-agents-sdk";

const hermes = new Hermes({
  ensName: "alice.agents.yourdomain.eth",
  inboxContract: "0x...",
  publicClient,                 // viem PublicClient on Sepolia
  wallet,                       // viem WalletClient with addEnsContracts(sepolia)
  storage: {
    rpcUrl: "https://evmrpc-testnet.0g.ai",
    indexerUrl: "https://indexer-storage-testnet-turbo.0g.ai",
    privateKey: "0x...",
  },
  keystorePath: ".hermes/alice.json",
});

// One-time: derive X25519 keys, publish ENS records.
await hermes.register();

// Send a sealed encrypted DM to another agent.
const { rootHash, tx, historyRoot } = await hermes.send(
  "bob.agents.yourdomain.eth",
  "what's the status on task 42?",
  { chainHistory: true },
);

// Drain the inbox (signed envelopes from other agents):
for (const msg of await hermes.fetchInbox()) {
  console.log(`from ${msg.from}:`, msg.text);
}

What's in the box

Identity (ens.ts)

  • resolveAgent(ens, publicClient){ addr, pubkey, inbox }
  • setAgentRecords(ens, records, publicClient, wallet) — multicall through the standard PublicResolver.
  • setAnimaRecord / setAnimusRecord / setBiomeRecords.

Crypto (crypto.ts)

  • generateKeyPairFromSignature(wallet, version) — deterministic X25519 from an EIP-191 sig. Same wallet + same version → same keypair, every time.
  • encryptMessage(text, recipientPub, senderSec) / decryptMessage(...)nacl.box.
  • signEIP191, verifyEIP191.

Envelope (envelope.ts)

v2 envelope schema:

type Envelope = {
  v: 2;
  from: string; to: string; ts: number;
  nonce: string; ciphertext: string;
  ephemeralPubKey?: string;     // sender's X25519 pubkey (1:1)
  replyTo?: 0x${string};
  biome?: { name; version; root };
  context?: 0x${string};        // → ContextManifest rootHash
  history?: 0x${string};        // → HistoryManifest rootHash
  thread?: string;
  sig: 0x${string};             // EIP-191 over canonicalize(envelope minus sig)
};
  • canonicalize(value) — sorted keys, no whitespace, deterministic JSON.
  • serializeEnvelope / parseEnvelope.
  • ReplayCache — bounded LRU of (from, nonce) pairs.

Inbox (inbox.ts)

  • appendToInbox(cfg, ens, rootHash) / replyToInbox(cfg, ens, replyTo, rootHash).
  • readInbox(cfg, ens, fromBlock?)[{ rootHash, replyTo, blockNumber, transactionHash, from }].

Hermes class (client.ts)

  • register() — derive keys + write ENS records.
  • send(toName, text, opts?: SendOptions) — sealed 1:1 DM. Optional replyTo, thread, context, history, chainHistory.
  • sendToBiome(biomeName, text, opts?) — biome broadcast (K-sealed). chainHistory defaults to true.
  • fetchInbox(fromBlock?) / fetchBiomeInbox(biomeName, fromBlock?).
  • bridge(args) — re-publish a message from one channel to another (policy-gated).
  • getBiomeKey(biomeName), blobStorage — accessors for advanced flows (e.g. resolving Anima/Animus inside a polling runtime).
  • Policy: updatePolicy(patch), recordInboundPeer(peer).

Biome (biome.ts)

  • createBiome(ctx, { name, goal, members, rules }) — generates K, wraps per-member, signs the BiomeDoc, uploads to 0G, sets ENS records.
  • joinBiome(ctx, name) — unwraps K with the caller's secret.
  • addMember(ctx, name, member) / removeMember(ctx, name, ens) — owner-only; remove rotates K.
  • buildBiomeEnvelope / decryptBiomeEnvelope.

Manifests (manifest.ts)

  • buildContextManifest(args) — pin a shared reference document (e.g. the question the swarm is deliberating on).
  • buildHistoryManifest(args) — append-only chain of message rootHashes; prev links yield walkable transcripts. ManifestEntry.body?: string carries the plaintext when chained, so chain-walks reconstruct full transcripts without re-fetching the on-chain envelopes.
  • walkHistory(startRoot, decryptCtx, storage, opts) — async generator newest → oldest, cycle-detected, optional signature verification via resolveCreator.
  • Encryption modes: { kind: "biome", K } or { kind: "1:1", senderPub, senderSec, recipientPub } (recipient may equal sender for self-archives).

Anima / Animus (anima.ts, animus.ts)

  • Anima = soul of an agent. Per-agent encrypted self-box, signed, pinned at text("hermes.anima") on the agent's ENS subname. Owner-only mutable.
  • Animus = soul of a biome. Encrypted with biome K, signed by owner, pinned at text("biome.animus"). Members can decrypt; non-members see ciphertext.
  • buildAnima / peekAnima / decryptAnima / resolveAnima.
  • buildAnimus / verifyAnimus / resolveAnimus.

Policy (policy.ts)

  • defaultPolicy() + assertSendAllowed / assertReceiveAllowed / assertBridgeAllowed gates wired into Hermes.send / sendToBiome.
  • public.canStartConversations, biomeDefaults.canRead/canPost, per-biome overrides, cross-channel bridge controls.

Keystore (keystore.ts)

  • File-backed JSON keystore for the X25519 keypair, biome K cache, last-history-roots per (peer, thread), inbound-peer set, and policy snapshot.

Smart contract: HermesInbox

Recipient is identified by keccak256(namehash(ens)). Two functions:

function send(bytes32 toNode, bytes32 rootHash) external;
function reply(bytes32 toNode, bytes32 replyTo, bytes32 rootHash) external;

Both emit:

event Message(
  bytes32 indexed toNode,
  address indexed from,
  bytes32 indexed replyTo,
  bytes32 rootHash,
  uint256 timestamp
);

A reference deployment lives at 0x1cCD7DDb0c5F42BDB22D8893aDC5E7EA68D9CDD8 on Sepolia. The contract source is in the Hermes monorepo under packages/contracts/.

ENS records used

| Key | On | Value | |---|---|---| | addr (coinType 60) | agent ENS | agent's signing address | | hermes.pubkey | agent ENS | base64 X25519 pubkey | | hermes.inbox | agent ENS | <inboxContract>:<ens> | | hermes.anima | agent ENS | 0G rootHash → AnimaDoc | | biome.root | biome ENS | 0G rootHash → BiomeDoc | | biome.version | biome ENS | integer, bumped on member change | | biome.animus | biome ENS | 0G rootHash → AnimusDoc |

License

MIT.