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

@happyvertical/smrt-profiles

v0.36.0

Published

Profile management system with relationships, metadata, and reciprocal associations for SMRT framework

Readme

@happyvertical/smrt-profiles

Central identity system with multi-auth (Nostr/OIDC/API keys/magic links), relationships, controlled metadata, and audit logging.

Installation

pnpm add @happyvertical/smrt-profiles

Usage

import {
  Profile,
  ProfileCollection,
  OidcIdentity,
  OidcIdentityCollection,
  ApiKey,
  ApiKeyCollection,
  NostrIdentity,
  generateNostrKeypair,
  createProfileFromOidc,
} from '@happyvertical/smrt-profiles';

// Create a profile
const profile = new Profile({
  name: 'Alice Johnson',
  email: '[email protected]',
});
await profile.save();

// OIDC identity (Keycloak/Google/GitHub)
const oidcProfile = await createProfileFromOidc({
  issuer: 'https://accounts.google.com',
  subject: 'abc123',
  email: '[email protected]',
  name: 'Alice Johnson',
});

// Nostr identity (encrypted keypair, requires SERVER_MASTER_SECRET)
const keypair = generateNostrKeypair();
const nostr = new NostrIdentity({
  profileId: profile.id,
  pubkey: keypair.pubkey,
});
await nostr.save();

// API key (plaintext returned once only)
const { key, apiKey } = await ApiKey.generate({
  profileId: profile.id,
  scope: 'read:profiles',
  expiresAt: new Date('2025-12-31'),
});
// key = plaintext (store now), apiKey.keyPrefix = visible identifier

// Relationships (auto-creates reciprocal inverse)
const bob = new Profile({ name: 'Bob Smith', email: '[email protected]' });
await bob.save();
await profile.addRelationship(bob, 'friend');
const friends = await profile.getRelationships({ direction: 'from' });

Owned assets

import { AssetCollection } from '@happyvertical/smrt-assets';

const profiles = await ProfileCollection.create();
const assets = await AssetCollection.create();

const headshot = await assets.create({
  name: 'alice-headshot.jpg',
  sourceUri: 'file:///tmp/alice-headshot.jpg',
  mimeType: 'image/jpeg',
});

await profile.addAsset(headshot, 'avatar');
await profiles.addAsset(profile.id!, headshot, 'gallery', 1);

const avatarAssets = await profile.getAssets('avatar');
const galleryAssets = await profiles.getAssets(profile.id!, 'gallery');

API

Models

| Export | Description | |--------|------------| | Profile | Core identity (STI base for Bot/Organization/Person) | | Bot | STI subclass for automated agents | | Organization | STI subclass for companies/groups | | Person | STI subclass for individuals | | ProfileType | Profile classification lookup table | | ProfileMetadata | Per-profile metadata values | | ProfileMetafield | Controlled vocabulary with validation schema | | ProfileRelationship | Directional link between two profiles | | ProfileRelationshipType | Relationship classification with reciprocal flag | | ProfileRelationshipTerm | Time-bounded relationship periods | | ProfileAsset | Dedicated owned-asset join stored in profile_assets with relationship and sortOrder |

Auth Models

| Export | Description | |--------|------------| | OidcIdentity | OIDC provider identity (issuer + subject) | | NostrIdentity | Nostr keypair with AES-256-GCM encryption | | ApiKey | SHA-256 hashed API key with scope and expiry | | MagicLinkToken | One-time passwordless auth token | | AuditLog | Action/resource audit trail with source tracking |

Collections

| Export | Description | |--------|------------| | ProfileCollection | CRUD and query for profiles | | ProfileAssetCollection | Direct access to profile_assets rows plus asset helper wrappers | | ProfileTypeCollection | Profile type management | | ProfileMetadataCollection | Metadata value operations | | ProfileMetafieldCollection | Metafield vocabulary management | | ProfileRelationshipCollection | Relationship queries | | ProfileRelationshipTypeCollection | Relationship type management | | ProfileRelationshipTermCollection | Term period management | | ApiKeyCollection | API key lookup and management | | AuditLogCollection | Audit log queries | | MagicLinkTokenCollection | Magic link token operations | | NostrIdentityCollection | Nostr identity lookup (includes NIP-05) | | OidcIdentityCollection | OIDC identity lookup |

Profile and ProfileCollection both expose getAssets(), addAsset(), and removeAsset() helpers backed by profile_assets. Typical relationships are avatar, gallery, and attachment.

Auth Functions

| Export | Description | |--------|------------| | resolveIdentity | Resolve profile from any auth method | | createProfileFromOidc | Create profile + OIDC identity in one call | | createProfileFromNostr | Create profile + Nostr identity in one call | | createAuthEvent | Create a Nostr auth event | | verifyAuthEvent | Verify a Nostr auth event signature | | createMagicLinkService | Factory for magic link auth service | | createNip05Handler | Factory for NIP-05 address handler |

Nostr Crypto

| Export | Description | |--------|------------| | generateNostrKeypair | Generate new Nostr keypair | | encryptPrivkey / decryptPrivkey | AES-256-GCM key encryption | | deriveEncryptionKey | Derive encryption key from master secret | | getPublicKey | Derive pubkey from privkey | | signEvent / computeEventId | Nostr event signing | | verifyNostrSignature | Verify Nostr signature | | pubkeyToNpub / npubToPubkey | Bech32 pubkey conversion | | privkeyToNsec / nsecToPrivkey | Bech32 privkey conversion | | isValidPubkey / isValidPrivkey | Key validation | | parseNip05Identifier / isValidNip05Identifier | NIP-05 parsing |

Key Types

ProfileOptions, ProfileTypeOptions, ProfileMetadataOptions, ProfileMetafieldOptions, ProfileRelationshipOptions, ProfileRelationshipTypeOptions, ProfileRelationshipTermOptions, OidcIdentityOptions, NostrIdentityOptions, ApiKeyOptions, GenerateKeyResult, MagicLinkTokenOptions, GenerateTokenResult, AuditLogOptions, AuditSource, AuthContext, ResolveIdentityResult, InitiateResult, VerifyResult, MagicLinkConfig, MagicLinkService, Nip05HandlerConfig, Nip05HandlerResult, Nip05Request, Nip05Response, NostrEvent, NostrKeypair, EncryptedKey, ValidationSchema, ValidatorFunction, ReciprocalHandler

Dependencies

  • @happyvertical/smrt-core -- ORM base classes
  • @happyvertical/ai -- AI client (SDK)
  • @happyvertical/sql -- Database operations (SDK)
  • @happyvertical/files -- Filesystem utilities (SDK)
  • @happyvertical/logger -- Structured logging (SDK)
  • @happyvertical/utils -- Shared utilities (SDK)
  • @noble/curves -- Nostr cryptography
  • bech32 -- Bech32 encoding for Nostr keys
  • Peer: @happyvertical/smrt-tenancy