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

libaskexperts

v0.1.5

Published

A TypeScript library to create experts based on NIP-174

Downloads

24

Readme

libaskexperts - Create Your Own Experts

A TypeScript library to create experts based on NIP-174 (AskExperts) protocol.

AskExperts is intended to be used by MCP tools as clients to find experts and ask them questions in exchange for a Lightning Network payment.

Overview

This library provides an Expert class that encapsulates all the logic of the NIP-174 protocol, handling Nostr events and Lightning payments. It allows you to create your own expert by implementing two callback functions:

  • onAsk: Called when a new ask is received, returns a bid if the expert wants to participate
  • onQuestion: Called when a question is received, returns an answer to the question

Installation

npm install libaskexperts

Usage

import { Expert } from 'libaskexperts';
import { generateSecretKey, getPublicKey } from 'nostr-tools';
import { nwc } from '@getalby/sdk';

// Create a wallet for generating invoices
const nwcClient = new nwc.NWCClient({ nostrWalletConnectUrl: "your-nwc-string" });

// Generate expert keypair
const expertPrivateKey = generateSecretKey();
const expertPublicKey = getPublicKey(expertPrivateKey);

// Create an expert instance
const expert = new Expert({
  nwcString,
  expertPrivkey: expertPrivateKey,
  askRelays: ["wss://relay.nostr.band", "wss://relay.damus.io"],
  questionRelays: ["wss://relay.nostr.band", "wss://relay.damus.io"],
  hashtags: ["ai", "programming"], // Listen for asks with these hashtags
  min_bid_sats: 50, // Ignore asks with max_bid_sats less than 50
  onAsk: async (ask) => {
    // Evaluate the ask and decide whether to bid
    return {
      content: "I can help with your programming question!",
      bid_sats: 100, // Charge 100 sats for an answer
    };
  },
  onQuestion: async (ask, bid, question, history) => {
    // Generate an answer to the question
    // history contains previous question-answer pairs for followups
    return {
      content: "Here's the answer to your question...",
      followup_sats: 50, // Allow followup questions for 50 sats
    };
  },
  bidTimeout: 600, // 10 minutes
});

// Start the expert
expert.start();

// To stop the expert and clean up resources
expert[Symbol.dispose]();

API

Expert Class

class Expert {
  constructor(params: ExpertParams);
  start(): void;
  [Symbol.dispose](): void;
}

ExpertParams Interface

interface ExpertParams {
  nwcString: string;
  expertPrivkey: Uint8Array;
  askRelays: string[];
  questionRelays: string[];
  hashtags: string[];
  onAsk: (ask: Ask) => Promise<Bid | undefined>;
  onQuestion: (ask: Ask, bid: Bid, question: Question, history?: QuestionAnswerPair[]) => Promise<Answer>;
  bidTimeout?: number;
  min_bid_sats?: number; // Minimum bid amount in satoshis that the expert will accept
}

Ask Interface

interface Ask {
  id: string;
  pubkey: string;
  content: string;
  created_at: number;
  tags: string[][];
  hashtags: string[]; // Hashtags parsed from 't' tags
  max_bid_sats?: number; // Maximum bid amount in satoshis
}

Bid Interface

interface Bid {
  content: string;
  bid_sats: number;
  tags?: string[][];
}

Question Interface

interface Question {
  id: string;
  content: string;
  preimage: string;
  tags?: string[][];
}

Answer Interface

interface Answer {
  content: string;
  followup_sats?: number; // Amount to charge for followup questions
  tags?: string[][];
}

QuestionAnswerPair Interface

interface QuestionAnswerPair {
  question: Question;
  answer: Answer;
}

Followup Questions

The library supports followup questions, allowing clients to ask additional questions after receiving an answer. To enable followup questions:

  1. In your onQuestion callback, return an Answer with the followup_sats property set to the amount you want to charge for a followup.
  2. The library will automatically generate an invoice and include it in the answer.
  3. When a client pays the invoice and asks a followup question, your onQuestion callback will be called again with the original ask, bid, the new question, and a history of previous question-answer pairs.

License

MIT