Skip to content

Repository files navigation

BitcoinLink

An open-source, non-custodial payment service that allows you to send bitcoin using a simple link.

Built on Nostr and powered by Nostr Wallet Connect (NWC).

How It Works

BitcoinLink uses Nostr protocol features to create secure, shareable payment links without any backend database:

┌─────────────────────────────────────────────────────────────────────────────┐
│                            Link Creation Flow                                │
├─────────────────────────────────────────────────────────────────────────────┤
│  1. Sender connects wallet (Alby/Mutiny) → gets NWC URL                     │
│  2. App creates gift-wrapped event (NIP-17) containing NWC URL + amount     │
│  3. Event published to Nostr relays                                         │
│  4. Shareable URL contains: event ID + receiver private key + relays        │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│                              Claim Flow                                      │
├─────────────────────────────────────────────────────────────────────────────┤
│  1. Recipient opens link → app decodes eventId + receiverPrivateKey         │
│  2. App fetches gift-wrapped event from Nostr relays                        │
│  3. App decrypts event to extract NWC URL                                   │
│  4. Recipient provides Lightning address/invoice                            │
│  5. Payment sent directly via NWC (sender's wallet → recipient)             │
│  6. Deletion event (NIP-09) published to mark link as claimed               │
└─────────────────────────────────────────────────────────────────────────────┘

Architecture

Pure Nostr. No Database. No Backend API.

Layer Technology
Storage Nostr relays (gift-wrapped events)
Encryption NIP-17 (Gift Wrap) with NIP-44 encryption
Payments NIP-47 (Nostr Wallet Connect)
Claim Tracking NIP-09 (Deletion Events)
Nostr Library snstr

What Gets Stored Where

Data Location
NWC URL + Amount Inside gift-wrapped Nostr event on relays
Receiver Private Key Only in the link URL (never stored)
Claim Status NIP-09 deletion event on relays

Features

For Senders

  • Generate NWC with Alby (browser extension)
  • Generate NWC with Mutiny (via NWA protocol)
  • Create multiple links from one NWC connection
  • Set custom amounts per link

For Recipients

  • Claim with any Lightning address (user@domain.com)
  • Claim with any Bolt11 invoice
  • Claim with any LNURL-pay endpoint
  • Claim with Alby (WebLN)
  • Claim with Strike, Mutiny, or CashApp

Link URL Format

Links encode all necessary data in base64url format:

https://bitcoinlink.app/claim/{base64url_encoded_data}

The encoded data contains:

{
  "eventId": "nostr_event_id_hex",
  "receiverPrivateKey": "hex_private_key",
  "relays": ["wss://relay1.com", "wss://relay2.com"],
  "amountSats": 1000
}

Development

Prerequisites

  • Node.js 18+
  • npm or yarn
  • snstr library (available on npm as ^0.2.0)

Setup

# Clone the repository
git clone https://github.com/AustinKelsay/bitcoinlink.git
cd bitcoinlink

# Install dependencies
npm install

# Start development server
npm run dev

Environment Variables

No environment variables required for basic development.

The app connects to public Nostr relays:

  • wss://relay.damus.io
  • wss://relay.nostr.band
  • wss://nos.lol
  • wss://nostr.mutinywallet.com

Build

npm run build
npm start

Testing

npm test

Security Model

Non-Custodial Architecture

  • BitcoinLink never holds user funds
  • Payments route directly: sender's wallet → recipient's wallet
  • NWC credentials are encrypted and only decryptable with the link URL

Privacy Features

  • Gift wrap (NIP-17) hides sender metadata
  • Ephemeral keypairs for each link
  • Timestamps are randomized
  • No user accounts or tracking

Claim Protection

  • Each link can only be claimed once
  • Deletion events prevent double-claiming
  • Private key is required to decrypt (only in URL)

Tech Stack

Category Technology
Framework Next.js 14, React 18, TypeScript
Styling Tailwind CSS, PrimeReact
Nostr snstr library
Bitcoin @getalby/sdk, light-bolt11-decoder

Project Structure

src/
├── lib/nostr/           # Nostr protocol implementation
│   ├── client.ts        # Relay connection management
│   ├── gift-wrap.ts     # NIP-17 gift wrap creation/decryption
│   ├── link-encoder.ts  # URL encoding/decoding
│   ├── nwc-client.ts    # NWC payment execution
│   ├── relays.ts        # Default relay configuration
│   └── types.ts         # TypeScript interfaces
├── pages/
│   ├── index.tsx        # Home - link generation
│   └── claim/[slug].tsx # Claim page
├── components/          # React components
├── hooks/               # Custom React hooks
└── utils/               # Utility functions

Contributing

Contributions welcome! Please read the existing code and documentation before submitting PRs.

License

MIT License

Links

About

Resources

Stars

4 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages