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

coco-cashu-plugin-npc

v2.2.4

Published

NPubCash plugin for coco-cashu-core - bridges NPubCash server with coco-cashu wallet

Downloads

533

Readme

coco-cashu-plugin-npc

NPC plugin for coco-cashu-core. It bridges an NPubCash (NPC) server into the coco lifecycle by polling for newly paid quotes, converting them to MintQuotes, and feeding them to the core mintQuoteService.

  • Polls NPC for paid quotes since a persisted timestamp
  • Groups by mintUrl and forwards via mintQuoteService.addExistingMintQuotes
  • Configurable polling interval, lifecycle cleanup on shutdown

Installation

Install the plugin and its peer dependencies in your app:

# npm
npm install coco-cashu-plugin-npc coco-cashu-core@^1.0.0-rc6

This package uses npubcash-sdk under the hood for NPC API access and JWT auth.

Quick start (interval-based)

import { NPCPlugin, MemorySinceStore } from "coco-cashu-plugin-npc";
import type { Logger } from "coco-cashu-core";

// Optional: pass your own SinceStore; defaults to in-memory if omitted
const sinceStore = new MemorySinceStore(0);

// Provide a signer supported by npubcash-sdk's JWTAuthProvider
// See npubcash-sdk docs for signer options
const signer: any = /* your signer */ {};

const baseUrl = "https://npc.example.com";
const logger: Logger | undefined = undefined; // optional

const plugin = new NPCPlugin(
  baseUrl,
  signer,
  sinceStore, // optional; omit to use memory
  logger,
  25_000 // optional poll interval ms (default 25s)
);

// Register with coco-cashu-core (pseudo-code)
// core.use(plugin);

The core will call onInit, at which point the plugin starts polling. When the core shuts down, the plugin cleans up its timer via registerCleanup.

How it works

On each poll cycle the plugin:

  • Loads the last processed timestamp via SinceStore.get()
  • Calls the NPC server for paid quotes since that timestamp
  • Groups by mintUrl and forwards to mintQuoteService.addExistingMintQuotes(mintUrl, quotes)
  • Persists the latest paidAt back via SinceStore.set()

API

class NPCPlugin {
  constructor(
    baseUrl: string,
    signer: any,
    sinceStore?: SinceStore,
    logger?: Logger,
    pollIntervalMs = 25_000
  );

  // Called by the core to start polling and register cleanup
  onInit(ctx: PluginContext<["mintQuoteService"]>): void | Promise<void>;
  // Called when the host is fully ready; starts the interval
  onReady(): void | Promise<void>;

  // Metadata required by coco-cashu-core
  readonly name: "npubcashPlugin";
  readonly required: ["mintQuoteService"];
}
  • baseUrl: NPC server base URL, e.g. https://npc.example.com
  • signer: Signer instance compatible with npubcash-sdk JWTAuthProvider
  • sinceStore: Optional store for last processed NPC paidAt (defaults to in-memory)
  • logger: Optional logger (child loggers are derived if supported)
  • pollIntervalMs: Polling interval in milliseconds (default 25_000)

Required service from the host core:

  • mintQuoteService: must provide addExistingMintQuotes(mintUrl, quotes)

Notes

  • A reentrancy guard prevents overlapping polls; slow requests won’t stack.
  • Be sure to persist since durably (e.g., DB) for correct resume behavior.
  • Errors during polling are logged through the provided logger if available.

Development

This is a TypeScript library. The public surface is exported from src/index.ts:

export * from "./plugins/NPCPlugin";
export * from "./plugins/NPCOnDemandPlugin";
export * from "./sync/sinceStore";

Run type checks or builds using your project’s toolchain (e.g., tsc, tsdown).

On-demand variant (no interval)

If you prefer to control when syncing happens (e.g., on a cron job, webhook, or manual trigger), use NPCOnDemandPlugin. It exposes a syncOnce() method instead of running on an interval.

import { NPCOnDemandPlugin, MemorySinceStore } from "coco-cashu-plugin-npc";
import type { Logger } from "coco-cashu-core";

const baseUrl = "https://npc.example.com";
const signer: any = /* your signer */ {};
const logger: Logger | undefined = undefined; // optional
const sinceStore = new MemorySinceStore(0); // optional; omit to use memory

const plugin = new NPCOnDemandPlugin(baseUrl, signer, sinceStore, logger);

// Register with coco-cashu-core (pseudo-code)
// core.use(plugin);

// Trigger on demand as needed
await plugin.syncOnce();

API additions:

class NPCOnDemandPlugin {
  constructor(
    baseUrl: string,
    signer: any,
    sinceStore?: SinceStore,
    logger?: Logger
  );

  onInit(ctx: PluginContext<["mintQuoteService"]>): void | Promise<void>;
  onReady(): void | Promise<void>;

  // Triggers a single sync cycle
  syncOnce(): Promise<void>;

  readonly name: "npubcashPluginOnDemand";
  readonly required: ["mintQuoteService"];
}