Skip to main content

Nostrbook Extension

This tutorial covers how to add the Nostrbook MCP Server as a Goose extension to provide access to a comprehensive registry of Nostr documentation that helps users understand the decentralized social protocol, its implementation possibilities, and technical specifications.

TLDR

Command

npx -y xjsr @nostrbook/mcp

Configuration

info

Note that you'll need Node.js installed on your system to run this command, as it uses npx.

  1. Launch the installer
  2. Press Yes to confirm the installation
  3. Click Save Configuration
  4. Scroll to the top and click Exit from the upper left corner

Example Usage

Goose Prompt

Goose, what is the NIP-61 and how can I implement it?.

Goose Output

Note that IDs have been changed to generic ones

CLI
Tool Calls

─── read_nip | nostrbook ──────────────────────────

nip: 61

NIP-61: Implementing Nutzaps

NIP-61 defines "Nutzaps," which are P2PK Cashu tokens where the payment itself acts as the receipt. This protocol allows for Bitcoin micropayments through the Nostr ecosystem using Cashu tokens.

Core Concept

Nutzaps enable users to send small Bitcoin payments to each other through Nostr events, with the tokens being locked to the recipient's specified public key.

Implementation Guide

Prerequisites

  1. Familiarize yourself with Cashu and P2PK token locking
  2. Understand NIP-60 for wallet functionality
  3. Ensure your implementation supports NUT-11 (P2PK) and NUT-12 (DLEQ proofs)

Step 1: Set Up Recipient Information (For Receiving Nutzaps)

Create and publish a kind:10019 event to inform others how to send you money:

{
"kind": 10019,
"tags": [
["relay", "wss://your-relay1.com"],
["relay", "wss://your-relay2.com"],
["mint", "https://your-trusted-mint.com", "sat"],
["pubkey", "<your-p2pk-pubkey>"]
]
}
  • The pubkey should be a dedicated public key (NOT your Nostr identity key)
  • Store the corresponding private key safely in your NIP-60 wallet event
  • List only mints you trust and monitor

Step 2: Building the Sender Functionality

To implement nutzapping:

  1. Query recipient information:

    // Fetch recipient's kind:10019 event
    const recipientInfo = await relay.get({
    kinds: [10019],
    authors: [recipientPubkey]
    });
  2. Extract mint and P2PK information:

    const recipientMints = recipientInfo.tags
    .filter(tag => tag[0] === 'mint')
    .map(tag => tag[1]);

    const recipientLockKey = recipientInfo.tags
    .find(tag => tag[0] === 'pubkey')?.[1];
  3. Mint or swap tokens at one of the recipient's trusted mints, P2PK-locking them to their specified key

  4. Publish the nutzap event:

    {
    "kind": 9321,
    "content": "Thanks for your post!",
    "tags": [
    ["proof", "{\"amount\":1,\"C\":\"02...3f\",\"id\":\"000...\",\"secret\":\"[\\\"P2PK\\\",...]\"}"],
    ["u", "https://recipient-specified-mint.com"],
    ["e", "<event-being-zapped>", "<relay-hint>"],
    ["p", "<recipient-pubkey>"]
    ]
    }

Step 3: Building the Recipient Functionality

To implement nutzap receiving:

  1. Query for incoming nutzaps:

    // Subscribe to nutzap events
    relay.subscribe([
    {
    kinds: [9321],
    "#p": [myPubkey],
    "#u": myTrustedMints,
    since: lastCheckTimestamp
    }
    ]);
  2. Validate incoming nutzaps:

    • Verify the token is from a mint you've specified
    • Verify the token is locked to your P2PK key
    • Verify the DLEQ proof
  3. Redeem the token:

    • Swap the P2PK token into your wallet
    • Create a kind:7376 event to record redemption:
    {
    "kind": 7376,
    "content": "<encrypted-content>",
    "tags": [
    ["e", "<nutzap-event-id>", "", "redeemed"],
    ["p", "<sender-pubkey>"]
    ]
    }

Important Implementation Details

  1. P2PK Key Prefixing: Always prefix the P2PK-lock public key with "02" for compatibility
  2. Token Verification: Implement local verification of DLEQ proofs
  3. Mint URL Normalization: Normalize mint URLs to avoid issues with slight URL variations
  4. User Guidance: Guide users to use only NUT-11 and NUT-12 compatible mints
  5. Publishing Locations: Publish nutzap events to the recipient's specified relays

Testing

When testing your implementation:

  1. Create test nutzaps with small amounts
  2. Verify token redemption works correctly
  3. Check that redemption records are properly created
  4. Test with multiple mints for compatibility

Security Considerations

  • Never use the user's main Nostr key for P2PK operations
  • Ensure proper encryption of sensitive wallet data
  • Validate all proofs before attempting to redeem tokens
  • Only interact with explicitly trusted mints

By following these steps, you can implement a complete nutzap solution that allows users to send and receive Bitcoin micropayments through the Nostr protocol using Cashu tokens.