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

@le-space/p2pass

v0.3.2

Published

P2Pass — peer-to-peer passkeys, UCANs, OrbitDB registry sync, and Storacha backup (Svelte)

Readme

P2Pass (@le-space/p2pass)

Tests

Standalone Svelte component for passkey-based DID identities replicating p2p between devices and Storacha decentralized backup. Published on npm as @le-space/p2pass (Le Space).

Drop in <StorachaFab /> and get:

  • WebAuthn passkey authentication (hardware Ed25519, P-256, or worker Ed25519 fallback)
  • UCAN delegation-based Storacha access
  • OrbitDB backup/restore with progress tracking
  • P2P device linking via libp2p with copy/paste peer info
  • Multi-device registry with automatic device detection
  • Floating action button with Storacha branding

Install

npm install @le-space/p2pass

Usage

<script>
  import { StorachaFab } from '@le-space/p2pass';
</script>

<StorachaFab {orbitdb} {libp2p} onAuthenticate={handleAuthenticate} />

The component handles everything internally:

  1. Click the floating Storacha button (bottom-right)
  2. Choose a signing mode (hardware Ed25519 with P-256 fallback, hardware P-256 only, or worker Ed25519), then Authenticate with Passkey → biometric prompt → DID created
  3. Two tabs appear: P2P Passkeys (device linking) and Storacha (backup/restore); P2P Passkeys is the default
  4. Paste a UCAN delegation → connected to Storacha → backup/restore enabled
  5. P2P Passkeys tab shows connection status, peer info, and linked devices

Worker Ed25519 Passkey Flow

Worker mode (preferWorkerMode={true}) uses WebAuthn purely for user verification and PRF seed extraction — the actual signing key is an Ed25519 keypair generated in a web worker, encrypted with the PRF-derived key.

First Visit (Registration)

User clicks "Authenticate with Passkey"
  │
  ├─ navigator.credentials.create()
  │    ├─ Biometric prompt (Face ID / Touch ID / PIN)
  │    ├─ Creates discoverable credential (resident key)
  │    └─ PRF extension: eval({ first: deterministicSalt })
  │
  ├─ Extract PRF seed from credential response
  │    └─ Deterministic 32-byte seed derived from biometric + salt
  │
  ├─ Initialize Ed25519 keystore with PRF seed
  │    └─ PRF seed used as AES-GCM encryption key for the keystore
  │
  ├─ Generate Ed25519 keypair in web worker
  │    ├─ Random Ed25519 keypair created
  │    ├─ DID derived: did:key:z6Mk...
  │    └─ Archive exported (private key material)
  │
  ├─ Encrypt archive with PRF-derived AES key
  │    └─ { ciphertext, iv } stored as hex strings
  │
  ├─ Derive IPNS keypair from PRF seed (for recovery)
  │    └─ Deterministic Ed25519 key for IPNS manifest publishing
  │
  └─ Store credentials
       ├─ Encrypted archive → localStorage (bootstrap cache)
       ├─ Keypair + archive → OrbitDB registry (when available)
       └─ WebAuthn credential metadata → localStorage (for re-auth)

Return Visit (Restoration)

User clicks "Authenticate with Passkey"
  │
  ├─ Find cached archive in localStorage
  │    └─ { did, ciphertext, iv, publicKeyHex }
  │
  ├─ Load stored WebAuthn credential metadata
  │
  ├─ navigator.credentials.get()
  │    ├─ Biometric prompt (same passkey as registration)
  │    └─ PRF extension: eval({ first: sameSalt })
  │
  ├─ Extract PRF seed → same seed as registration
  │
  ├─ Decrypt archive with PRF seed → same Ed25519 keypair
  │
  └─ Same DID restored: did:key:z6Mk...

Recovery (New Device / Cleared Storage)

User clicks "Recover Identity"
  │
  ├─ navigator.credentials.get() (discoverable credential)
  │    ├─ Biometric prompt — passkey synced via iCloud/Google/etc.
  │    └─ PRF extension → same PRF seed
  │
  ├─ Derive IPNS keypair from PRF seed
  │
  ├─ Resolve IPNS manifest via w3name
  │    └─ Manifest contains: { ownerDid, archiveCID, delegation, registryAddress }
  │
  ├─ Fetch encrypted archive from IPFS gateway (no auth needed)
  │    └─ GET https://{archiveCID}.ipfs.w3s.link/ → { ciphertext, iv }
  │
  ├─ Decrypt archive with PRF seed → Ed25519 keypair restored
  │
  ├─ Connect to Storacha using delegation from manifest
  │
  └─ Same DID restored on new device

Key Insight

The WebAuthn credential never signs anything — it's only used for:

  1. User verification (biometric gate)
  2. PRF seed extraction (deterministic secret derived from biometric + salt)

The PRF seed is the root of all derived keys:

  • Ed25519 DID keypair — encrypted with PRF-derived AES key
  • IPNS recovery key — deterministically derived from PRF seed
  • Keystore encryption — PRF seed used as AES-GCM key

This means the same passkey on any device (via passkey sync) produces the same PRF seed, which unlocks the same DID identity.

Signing Modes

| Mode | Security | Key Storage | Biometric | | ---------------- | -------- | ----------------------------------- | ------------- | | Hardware Ed25519 | Highest | TPM/Secure Enclave | Per signature | | Hardware P-256 | High | TPM/Secure Enclave | Per signature | | Worker Ed25519 | Medium | Web worker + encrypted localStorage | On init only |

Worker Ed25519 matches typical OrbitDB multi-device flows (signing key in a worker). Hardware modes keep private keys in the authenticator; hardware Ed25519 lists Ed25519 first and may obtain P-256 if the device does not support hardware Ed25519. Pick the mode in the panel before authenticating, or set signingPreference="worker" / preferWorkerMode on the component.

Props

When using StorachaFab or StorachaIntegration directly:

| Prop | Type | Default | Description | | ------------------- | -------- | --------------- | ---------------------------------------------------------------------------------------- | | orbitdb | object | null | OrbitDB instance (for backup/restore) | | database | object | null | Database instance to backup | | isInitialized | boolean | false | Whether OrbitDB is ready | | entryCount | number | 0 | Database entry count | | databaseName | string | 'restored-db' | Name for restored database | | onRestore | function | () => {} | Called when restore completes | | onBackup | function | () => {} | Called when backup completes | | onAuthenticate | function | () => {} | Called after passkey auth (receives signingMode) | | libp2p | object | null | libp2p instance for P2P connectivity | | signingPreference | string | null | 'hardware-ed25519', 'hardware-p256', or 'worker' — overrides the in-panel selector | | preferWorkerMode | boolean | false | Deprecated; same as signingPreference="worker" |

Components

StorachaFab

Floating action button (bottom-right) with the Storacha rooster logo. Opens the integration panel as an overlay. Self-contained — no Tailwind or external CSS required.

StorachaIntegration

The panel component itself. Can be embedded inline instead of as a floating panel.

Programmatic API

import {
  IdentityService,
  createStorachaClient,
  parseDelegation,
  setupP2PStack,
  createLibp2pInstance,
  cleanupP2PStack,
} from '@le-space/p2pass';

// Create identity (worker mode for P2P)
const identity = new IdentityService();
const { mode, did, algorithm } = await identity.initialize(undefined, { preferWorkerMode: true });

// Get UCAN principal
const principal = await identity.getPrincipal();

// Connect to Storacha
const delegation = await parseDelegation(delegationBase64);
const client = await createStorachaClient(principal, delegation);

// Start P2P stack
const libp2p = await createLibp2pInstance();
// After auth, upgrade to full stack with OrbitDB:
const stack = await setupP2PStack(credential);

Development

npm run dev:example    # Run example app
npm test               # Run unit tests
npm run package        # Build library

End-to-end tests

Playwright drives the example app in Chromium with virtual WebAuthn. Tests live in e2e/ (for example link-devices.spec.js for multi-device pairing).

Run:

npm run test:e2e       # headless; starts relay + Vite automatically
npm run test:e2e:ui    # Playwright UI mode (debugging)

playwright.config.js starts scripts/e2e-with-relay.mjs, which:

  1. Launches orbitdb-relay-pinner (local libp2p relay).
  2. Fetches WebSocket bootstrap multiaddrs from the relay’s HTTP API and passes them to Vite as VITE_BOOTSTRAP_PEERS so browsers can connect.
  3. Runs svelte-package and the example Vite dev server on port 5173.

First-time setup may require browser binaries:

npx playwright install chromium

Reuse a running dev server (you must still provide a relay and matching VITE_BOOTSTRAP_PEERS yourself if you skip the script):

PW_REUSE_SERVER=1 npm run test:e2e

Failed runs write HTML reports, screenshots, traces, and video under test-results/ (see Playwright output for paths).

Signing mode in e2e: set E2E_SIGNING_MODE to worker, hardware-ed25519, or hardware-p256 (default in helpers is worker). CI runs the link-devices spec three times (matrix), one per mode.

E2E_SIGNING_MODE=hardware-ed25519 npm run test:e2e

Dependencies

License

MIT