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

@scom/nostr

v0.1.1

Published

A comprehensive TypeScript library for working with the Nostr protocol, providing cryptographic utilities, event management, client APIs, and interfaces for building Nostr-based applications.

Readme

@scom/nostr

A comprehensive TypeScript library for working with the Nostr protocol, providing cryptographic utilities, event management, client APIs, and interfaces for building Nostr-based applications.

Overview

This package provides a complete toolkit for interacting with the Nostr protocol, including:

  • Unified Client API: NostrClient for seamless HTTP and WebSocket relay interactions
  • Cryptographic Functions: Key generation, signing, encryption, and verification
  • Event Management: Create, serialize, validate, and submit Nostr events
  • NIP-19 Support: Encode and decode bech32-formatted Nostr entities (npub, nsec, note, etc.)
  • Connection Plugins: Extensible architecture supporting HTTP and WebSocket protocols
  • High-level APIs: Social features, communities, channels, marketplace, and more
  • Type Definitions: Comprehensive TypeScript interfaces for Nostr data structures

Installation

npm install @scom/nostr

Quick Start

Using NostrClient (Recommended)

The NostrClient provides a unified interface for interacting with Nostr relays via HTTP or WebSocket protocols:

import { NostrClient } from '@scom/nostr';

// Create an HTTP client
const client = NostrClient.create('https://relay.decom.app/api/v1', privateKey);

// Or create a WebSocket client
const wsClient = NostrClient.create('wss://relay.damus.io', privateKey);

// Connect to the relay
await client.connect();

// Fetch events
const response = await client.fetchEvents({
  kinds: [1],
  limit: 10
});

// Send a note
await client.sendNote('Hello Nostr!');

// Update your profile
await client.updateProfile({
  name: 'Alice',
  about: 'Nostr enthusiast',
  picture: 'https://example.com/avatar.jpg'
});

// Disconnect when done
await client.disconnect();

Core Cryptography

Low-level cryptographic utilities:

import { Keys } from '@scom/nostr';

// Generate a new private key
const privateKey = Keys.generatePrivateKey();

// Get the public key from a private key
const publicKey = Keys.getPublicKey(privateKey);

// Get shared secret for encryption (NIP-04)
const sharedSecret = Keys.getSharedSecret(privateKey, recipientPubkey);

Event Creation and Validation

Create and manage Nostr events:

import { Event } from '@scom/nostr';

// Create a blank event template
const eventTemplate = Event.getBlankEvent(Event.Kind.Text);

// Finish and sign an event
const signedEvent = Event.finishEvent(
  {
    kind: 1,
    content: 'Hello Nostr!',
    tags: [],
    created_at: Math.floor(Date.now() / 1000)
  },
  privateKey
);

// Validate an event
const isValid = Event.validateEvent(signedEvent);

// Verify event signature
const isVerified = Event.verifySignature(signedEvent);

Features

NostrClient API

The NostrClient class provides a high-level API for common Nostr operations:

Client Creation

import { NostrClient } from '@scom/nostr';

// Create with protocol auto-detection
const client = NostrClient.create('https://relay.example.com', privateKey);

// Create with specific plugin
import { NostrHttpConnectionPlugin } from '@scom/nostr';
const httpPlugin = new NostrHttpConnectionPlugin('https://relay.example.com');
const client = new NostrClient(httpPlugin, privateKey);

Connection Management

// Connect to relay
await client.connect();

// Check connection status
const connected = client.isConnected();

// Disconnect
await client.disconnect();

Fetching Events

// Fetch events with filters
const response = await client.fetchEvents({
  kinds: [1],
  authors: [pubkey],
  limit: 20
});

// Fetch cached events (HTTP only)
const cachedResponse = await client.fetchCachedEvents('user_profile', {
  pubKeys: [pubkey]
});

// Fetch user profile
const profile = await client.fetchUserProfileDetail(pubkey);

// Fetch events by IDs
const events = await client.fetchEventsByIds([eventId1, eventId2]);

Publishing Events

// Send a text note
await client.sendNote('Hello Nostr!');

// Send a note with hashtags
await client.sendNote('Building on #nostr', [['t', 'nostr']]);

// Send a reply
await client.sendReply('Great post!', originalEventId, originalAuthorPubkey);

// Update profile
await client.updateProfile({
  name: 'Alice',
  display_name: 'Alice in Nostrland',
  about: 'Building on Nostr',
  picture: 'https://example.com/avatar.jpg',
  banner: 'https://example.com/banner.jpg',
  website: 'https://example.com',
  lud16: '[email protected]',
  nip05: '[email protected]'
});

// Merge with existing profile
await client.updateProfile(
  { name: 'Alice' },
  undefined,
  true  // mergeWithExisting
);

// Send a reaction
await client.sendReaction('+', eventId, eventAuthorPubkey);

// Repost an event
await client.repostEvent(originalEvent);

Encryption (NIP-04)

// Encrypt a message
const encrypted = await client.encryptMessage(
  'Secret message',
  recipientPubkey
);

// Decrypt a message
const decrypted = await client.decryptMessage(
  encryptedContent,
  senderPubkey
);

Private Key Management

// Get public key from stored private key
const pubkey = client.getPublicKey();

// Set/update private key (supports nsec and hex formats)
client.setPrivateKey('nsec1...');
client.setPrivateKey('hexadecimal...');

WebSocket Subscriptions

// Subscribe to events (WebSocket only)
const subscriptionId = await client.subscribe(
  [{ kinds: [1], authors: [pubkey] }],
  (event) => {
    console.log('New event:', event);
  },
  () => {
    console.log('End of stored events (EOSE)');
  }
);

// Unsubscribe
await client.unsubscribe(subscriptionId);

NIP-19 Encoding/Decoding

Work with bech32-formatted Nostr identifiers:

import { Nip19 } from '@scom/nostr';

// Encode entities
const npub = Nip19.npubEncode(publicKey);
const nsec = Nip19.nsecEncode(privateKey);
const note = Nip19.noteEncode(eventId);

// Encode with relay hints
const nprofile = Nip19.nprofileEncode({
  pubkey: publicKey,
  relays: ['wss://relay.damus.io', 'wss://nos.lol']
});

const nevent = Nip19.neventEncode({
  id: eventId,
  relays: ['wss://relay.damus.io'],
  author: authorPubkey
});

// Decode entities
const decoded = Nip19.decode(npub);
console.log(decoded.type); // 'npub'
console.log(decoded.data); // public key hex

Connection Plugins

Extend NostrClient with custom connection plugins:

import { 
  NostrClient,
  NostrHttpConnectionPlugin,
  NostrWebSocketConnectionPlugin 
} from '@scom/nostr';

// HTTP Plugin
const httpPlugin = new NostrHttpConnectionPlugin('https://relay.example.com');
const httpClient = new NostrClient(httpPlugin, privateKey);

// WebSocket Plugin
const wsPlugin = new NostrWebSocketConnectionPlugin('wss://relay.example.com');
const wsClient = new NostrClient(wsPlugin, privateKey);

// Or use the factory method with auto-detection
const client = NostrClient.create('https://relay.example.com', privateKey);

Event Kinds

The library supports standard Nostr event kinds (NIP-01 and extensions):

  • 0 - Metadata (user profile)
  • 1 - Text Note
  • 2 - Recommend Relay
  • 3 - Contacts
  • 4 - Encrypted Direct Message (NIP-04)
  • 5 - Event Deletion
  • 6 - Repost
  • 7 - Reaction
  • 40 - Channel Creation
  • 41 - Channel Metadata
  • 42 - Channel Message
  • 43 - Channel Hide Message
  • 44 - Channel Mute User
  • 1984 - Report
  • 9734 - Zap Request
  • 9735 - Zap Receipt
  • 10000 - Mute List
  • 10002 - Relay List Metadata
  • 30000 - Categorized People List
  • 30008 - Profile Badges
  • 30009 - Badge Definition
  • 30023 - Long-form Content (Article)
  • 30078 - Application-specific Data
  • And more...

Manager Classes

Advanced manager classes for specialized operations:

import {
  NostrEventManagerRead,
  NostrEventManagerWrite,
  SocialUtilsManager,
  SocialDataManager,
  NostrRestAPIManager,
  NostrWebSocketManager
} from '@scom/nostr';

// REST API Manager for HTTP relay communication
const restManager = new NostrRestAPIManager('https://relay.example.com');

// WebSocket Manager for real-time communication
const wsManager = new NostrWebSocketManager(['wss://relay.example.com']);

// Event read operations
const eventReader = new NostrEventManagerRead(relayUrls);

// Event write operations  
const eventWriter = new NostrEventManagerWrite(relayUrls, privateKey);

// Social utilities
const socialUtils = new SocialUtilsManager();

// Social data management
const socialData = new SocialDataManager();

TypeScript Interfaces

The package provides comprehensive TypeScript interfaces for type-safe Nostr development:

import { 
  INostrEvent, 
  INostrMetadataContent, 
  INostrFetchEventsResponse,
  INostrSubmitResponse 
} from '@scom/nostr';

// Nostr event structure
interface INostrEvent {
  id: string;
  pubkey: string;
  created_at: number;
  kind: number;
  tags: string[][];
  content: string;
  sig: string;
}

// User profile metadata
interface INostrMetadataContent {
  name?: string;
  display_name?: string;
  username?: string;
  website?: string;
  picture?: string;
  about?: string;
  banner?: string;
  lud16?: string;        // Lightning address
  nip05?: string;        // Nostr verification
}

// Fetch response
interface INostrFetchEventsResponse {
  error?: string;
  events?: INostrEvent[];
  data?: any;
}

// Submit response
interface INostrSubmitResponse {
  success: boolean;
  message?: string;
  relay?: string;
  eventId?: string;
}

Advanced Features

Custom Connection Plugins

Implement your own connection plugin by implementing the INostrConnectionPlugin interface:

import { INostrConnectionPlugin, NostrConnectionProtocol } from '@scom/nostr';

class MyCustomPlugin implements INostrConnectionPlugin {
  protocol = NostrConnectionProtocol.CUSTOM;
  
  async connect(): Promise<void> { /* ... */ }
  async disconnect(): Promise<void> { /* ... */ }
  isConnected(): boolean { /* ... */ }
  async subscribe(/* ... */): Promise<string> { /* ... */ }
  async unsubscribe(id: string): Promise<void> { /* ... */ }
}

Communities and Channels

The library includes interfaces and utilities for:

  • Communities: Community creation, management, and moderation
  • Channels: Public and private channel operations
  • Marketplace: Product listings and transactions
  • Social Features: Following, contacts, reactions, reposts
  • Data Management: Event fetching, caching, and aggregation

Testing

The package includes a comprehensive test suite. See tests/README.md for details.

# Run all tests
npm test

# Run specific test file
npx @scom/test tests/client-api.test.ts

Building

To build the package from source:

# Build library and bundle
npm run build

# Build library only
npm run build:lib

# Build browser bundle only
npm run build:bundle

This will compile the TypeScript source files and generate:

  • CommonJS/ES modules in the lib directory
  • Browser bundle in the dist directory

API Reference

NostrClient

Main client class for Nostr relay interactions:

Static Methods:

  • NostrClient.create(url, privateKey?, options?): Create client with auto-detected protocol

Instance Methods:

  • connect(): Connect to relay
  • disconnect(): Disconnect from relay
  • isConnected(): Check connection status
  • fetchEvents(...requests): Fetch events with filters
  • fetchCachedEvents(eventType, msg): Fetch cached events (HTTP only)
  • submitEvent(event, authHeader?): Submit a signed event
  • subscribe(requests, onEvent, onEose): Subscribe to events (WebSocket)
  • unsubscribe(subscriptionId): Unsubscribe from events
  • sendNote(content, tags?, privateKey?): Send a text note
  • sendReply(content, originalEventId, originalAuthorPubkey, privateKey?): Send a reply
  • updateProfile(metadata, privateKey?, mergeWithExisting?): Update user profile
  • sendReaction(content, eventId, eventAuthorPubkey, privateKey?): Send a reaction
  • repostEvent(event, privateKey?): Repost an event
  • fetchUserProfileDetail(pubkey): Fetch user profile
  • fetchEventsByIds(ids): Fetch events by IDs
  • encryptMessage(content, recipientPubkey): Encrypt message (NIP-04)
  • decryptMessage(encryptedContent, senderPubkey): Decrypt message (NIP-04)
  • getPublicKey(): Get public key from stored private key
  • setPrivateKey(privateKey): Set/update private key

Keys Module

Cryptographic key operations:

  • Keys.generatePrivateKey(): Generate a new random private key
  • Keys.getPublicKey(privateKey): Derive public key from private key
  • Keys.getPublicKeyY(privateKey): Get the Y coordinate of the public key
  • Keys.getSharedSecret(privateKey, publicKey): Calculate shared secret (ECDH)
  • Keys.decompressPublicKey(publicKey): Decompress a compressed public key

Event Module

Event creation and validation:

  • Event.getBlankEvent(kind?): Create a blank event template
  • Event.finishEvent(template, privateKey): Sign and finalize an event
  • Event.serializeEvent(event): Serialize event for hashing
  • Event.getEventHash(event): Calculate event ID
  • Event.validateEvent(event): Validate event structure
  • Event.verifySignature(event): Verify event signature

Nip19 Module

Bech32 encoding/decoding (NIP-19):

  • Nip19.npubEncode(publicKey): Encode public key to npub
  • Nip19.nsecEncode(privateKey): Encode private key to nsec
  • Nip19.noteEncode(eventId): Encode event ID to note
  • Nip19.nprofileEncode(profile): Encode profile with relays
  • Nip19.neventEncode(event): Encode event with metadata
  • Nip19.naddrEncode(addr): Encode parameterized replaceable event
  • Nip19.decode(encoded): Decode any NIP-19 entity

Bech32 Module

Low-level bech32 encoding/decoding utilities as defined in NIP-19.

Documentation

Resources