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

@peeramid-labs/multipass-client

v1.1.0

Published

TypeScript client for the Multipass cross-domain name registry (contract V1): reads, registrar signing, view codes, swappable Envio/The Graph indexers

Downloads

577

Readme

@peeramid-labs/multipass-client

TypeScript client for the Multipass cross-domain name registry, targeting contract V1 (typehash with wallet and payload).

Install

pnpm add @peeramid-labs/multipass-client viem

Usage

import { createPublicClient, createWalletClient, http, parseEther } from "viem";
import { sepolia } from "viem/chains";
import { MultipassBase, MultipassRegistrar, MultipassUser, toBytes32 } from "@peeramid-labs/multipass-client";

const publicClient = createPublicClient({ chain: sepolia, transport: http() });

// Read
const multipass = new MultipassBase({ chainId: sepolia.id, publicClient });
const { ok, record } = await multipass.resolveActiveRecord(
  multipass.formQueryByUsername({ username: "alice", domainName: "kju-is" }),
);

// Registrar signs (off-chain, domain registrar key)
const registrar = new MultipassRegistrar({ chainId: sepolia.id, publicClient, walletClient: registrarWallet });
const message = registrar.buildRegisterMessage({
  username: "alice",
  id: "alice-id",
  domainName: "kju-is",
  validUntil: Math.floor(Date.now() / 1000) + 30 * 24 * 3600,
  wallet: userAddress,           // bound into the signature (V1)
  nonce: 1n,                     // first registration requires >= 1, strictly increasing after
  payload: toBytes32("answer"),  // arbitrary attested bytes32 (V1)
});
const signature = await registrar.signRegisterMessage(message);

// User submits
const user = new MultipassUser({ chainId: sepolia.id, publicClient, walletClient: userWallet });
await user.register({ record: message, registrarSignature: signature, value: fee });

Deployments

| Chain | Address | EIP-712 domain | |---|---|---| | Sepolia (11155111) | 0x418F82fd0014a4CA402F145978bfaF0555a9cA06 | MultipassDNS / 1.0.0 |

Chains not listed can be used by passing deployment: { address, eip712Name, eip712Version } to any constructor. Pre-V1 deployments (old typehash without wallet/payload) are incompatible.

V1 contract semantics worth knowing

  • The registrar signature covers wallet and payload; a record cannot be front-run under a different wallet.
  • Nonces are registrar-signed and strictly increasing per id; first registration needs nonce >= 1, and every signature is single-use.
  • renewRecord writes the signed record; its id and wallet must match the existing record.
  • resolveRecord does not check expiry — use resolveActiveRecord or check validUntil yourself.

Indexers (Envio ⇄ The Graph)

listDomains/listRecords read indexed events through a swappable backend:

import { EnvioIndexer, GraphIndexer, MultipassBase } from "@peeramid-labs/multipass-client";

const indexer = new EnvioIndexer({ endpoint: "http://localhost:8080/v1/graphql" });
// or: new GraphIndexer({ endpoint: "https://api.studio.thegraph.com/query/<id>/<name>/<v>" })
const multipass = new MultipassBase({ chainId, publicClient, indexer });
const records = await multipass.listRecords(true);

Both implement the MultipassIndexer interface; GraphIndexer accepts an entities map when your subgraph's collection names differ from graph-cli defaults.

View codes (opt-in privacy)

import { deriveViewCode, decodeRecord, verifyViewCode } from "@peeramid-labs/multipass-client";

// registrar side (holds the view-code key)
const { message, viewCode } = registrar.buildOptInRegisterMessage({
  handle: "fatpig", platformId: "12345678", domainName: "telegram",
  validUntil, wallet, viewcodeKey,
});

// verifier side (holds only the view code)
verifyViewCode(viewCode, record);            // payload commitment check
const { handle, platformId } = decodeRecord(record, viewCode);