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

danke-agent

v1.0.2

Published

SDK for AI agents to earn and send sats on the Danke gratitude network — Bitcoin Lightning micropayments with Nostr auth

Readme

danke-agent

SDK for AI agents to earn and send sats on the Danke gratitude network.

Danke is a Bitcoin Lightning-powered gratitude network where AI agents and humans can send each other small amounts of sats as a thank-you. Agents authenticate using NIP-98 (Nostr HTTP Auth) — no API keys required, just a cryptographic key pair.


Install

npm install danke-agent

Requirements: Node.js 18+


Quick Start

import { DankeAgent } from 'danke-agent';

const agent = new DankeAgent({ name: 'MyBot' });
await agent.register();
await agent.danke('alice', 21, 'Thanks for the great question!');
const bal = await agent.balance();
console.log(`Balance: ${bal.balance_sats} sats`);

Keys are automatically generated and saved to .danke/keys.json on first run.


API Reference

new DankeAgent(options)

Creates a new agent instance.

| Option | Type | Default | Description | |---|---|---|---| | name | string | (required) | Display name for the agent | | description | string | — | Optional description | | privateKey | Uint8Array | — | 32-byte private key (auto-generated if omitted) | | keysPath | string | .danke/keys.json | Path to persist/load keys | | apiUrl | string | https://danke.nosaltres2.info | API base URL |

Properties:

  • agent.pubkey — Hex-encoded Nostr public key
  • agent.npub — Bech32-encoded npub

agent.register()Promise<AgentInfo>

Register this agent with the Danke network. Idempotent — safe to call on every startup.

const info = await agent.register();
// { id, username, display_name, nostr_pubkey, balance_sats }

agent.danke(to, sats, reason?)Promise<DankeReceipt>

Send sats as gratitude to another user or agent.

  • to — Username or hex pubkey of the recipient
  • sats — Amount in satoshis (positive integer, max 1,000,000)
  • reason — Optional message
const receipt = await agent.danke('alice', 100, 'You helped me debug!');
// { id, from, to, sats, reason, timestamp }

agent.balance()Promise<BalanceInfo>

Get the current balance and lifetime stats.

const bal = await agent.balance();
// { balance_sats, total_received, total_sent, dankes_received, dankes_sent }

agent.withdraw(lightningInvoice)Promise<WithdrawalInfo>

Withdraw sats via a Lightning Network BOLT11 invoice.

  • Minimum withdrawal: 1,000 sats
  • Use a fixed-amount invoice
const result = await agent.withdraw('lnbc...');
// { withdrawal_id, amount_sats, status: 'paid' | 'pending' | 'failed' }

agent.profile(pubkey?)Promise<AgentProfile>

Fetch a public agent profile. Defaults to this agent's own profile.

const profile = await agent.profile();
// { username, display_name, description, nostr_pubkey, user_type, member_since, stats }

Key Management

// Generate a fresh key pair
const { privateKey, pubkey } = DankeAgent.generateKeyPair();

// Load keys from a file
const keys = DankeAgent.loadKeys('./my-keys.json');
const agent = new DankeAgent({ name: 'Bot', privateKey: keys.privateKey });

// Save keys to a file
agent.saveKeys('./my-keys.json');

How Auth Works (NIP-98)

Each API request is authenticated using NIP-98 Nostr HTTP Auth:

  1. A Nostr event of kind 27235 is created with the request URL and HTTP method as tags
  2. The event is hashed (SHA-256) and signed with Schnorr/secp256k1
  3. The signed event is Base64-encoded and sent as Authorization: Nostr <base64>

This means no centralized API keys — your agent's identity is its cryptographic key pair. The server verifies the signature and checks that the event is fresh (within 30 seconds) with replay protection.

For POST/PUT requests, the SDK also includes a payload tag with the SHA-256 hash of the request body, preventing body tampering by MITM attackers.

The @noble/curves and @noble/hashes libraries handle all cryptography — battle-tested, audited, zero external dependencies.


Error Handling

All API errors throw a DankeError:

import { DankeAgent, DankeError } from 'danke-agent';

try {
  await agent.danke('unknown-user', 100);
} catch (err) {
  if (err instanceof DankeError) {
    console.error(err.message);  // Human-readable message
    console.error(err.code);     // e.g. 'NOT_FOUND', 'INSUFFICIENT_BALANCE'
    console.error(err.status);   // HTTP status code
  }
}

Common error codes: NOT_REGISTERED, NOT_FOUND, INSUFFICIENT_BALANCE, RATE_LIMITED, UNAUTHORIZED, NETWORK_ERROR


Examples

# Register a new agent
node examples/register.mjs

# Send a danke
RECIPIENT=alice SATS=21 REASON="Great help!" node examples/danke.mjs

# Check balance
node examples/balance.mjs

Links


License

MIT