nips/69.md
shocknet-justin 858e73ea81 first pass
2024-08-26 22:54:45 -04:00

4.8 KiB

NIP-69

Nostr Offer STRings

wip optional

This NIP proposes a format for static payment codes in Nostr as a successor to LNURL-Pay, enabling users to initiate Lightning Network payments by scanning or clicking a string.

Motivation

Reliance on LNURL has led to centralization via custodial solutions due to the legacy baggage of IP4-NAT/Domain/SSL requirements. Nostr's use-cases are already centered around Lightning, whether as a wallet connector, zap receipts, or its overlapping network effects, rendering Nostr as a de facto "3rd layer" for Lightning and a natural successor to LNURL.

When layered over kind 21000, NWC, or other potential Lightning RPCs, this specification enables a seamless user experience similar to legacy LNURL-Pay, without the domain and SSL requirements. Additionally, the signed nature of Nostr communications eliminates the trust requirements inherent in LNURL when a node must outsource the serving of web requests.

Specification

Static Payment Code Format

The static payment code is a bech32 (per NIP-19) encoded string prefixed with noffer. The encoded string will include the following TLV (Type-Length-Value) items:

  • 0: The 32 bytes of the receiving services public key, encoded in hex.
  • 1: The relay URL where the receiving service subscribes to payment requests
  • 2: The offer string

Process Flow

  1. Payer Scans or Clicks the Static Payment Code

  2. Payers wallet decodes the payment code

  3. Payers wallet sends a Nostr event to the specified relay, addressed to the receiver's public key, containing the identifier string.

    • Event Type: Ephemeral Kind 21001 | NIP-44 Encrypted
    • Optional: Include additional payer data
  4. Receiver Responds with Lightning Invoice

    • Upon receiving the payment request event, the receiver generates a Lightning invoice and responds with a Nostr event containing the invoice details.
    • Event Type: Ephemeral Kind 21001 | NIP-44 Encrypted
    • Optional: Include additional purchase data
  5. Payer Pays the Invoice

    • The payer completes the payment by settling the Lightning invoice.
  6. Optional: Receiver Emits Payment Receipt

    • This step is out of scope for this NIP, but potential receipt considerations include: a. Nostr Event as Receipt: Emitting a public Nostr event as a "zap" receipt for verifiable record-keeping. b. Lightning Pre-Image: Sharing the Lightning pre-image as proof of payment. c. External / WebHook: The receiver may finalize the flow out-of-band.

Nostr Event

This NIP specifies the use of event kind 21001 with the following structure:

  • content: NIP-44 encrypted payment details
  • tags:
    • p: Receiver's public key (encoded in hex)
    • relay: URL of the relay for receiving payment requests
    • offer: Unique identifier for the payment purpose

Example event:

{
  "id": "<event_id>",
  "pubkey": "<sender_pubkey>",
  "created_at": 1234567890,
  "kind": 21001,
  "tags": [
    ["p", "<receiver_pubkey>"],
    ["e", "<event_id>"] // used only in response by the receiver to identify the original payment request
  ],
  "content": "<NIP-44 encrypted offer id and optional payer data>",
  "sig": "<signature>"
}

The content field should contain a stringified JSON object with the following structure:

{
    "offer_id": "<offer_id>",
    "payer_data": "<payer_data>"
}

Client Behavior

Clients implementing this NIP must:

  1. Decode and validate the structure of the noffer bech32-encoded static payment code.
  2. Use NIP-44 encryption for all communication between payer and receiver.
  3. Generate and send kind 21001 events as specified in this NIP.
  4. Parse the content field of received events by decrypting and JSON-parsing the stringified content.
  5. Handle potential errors gracefully, providing clear feedback to users.
  6. Respect the relay tag specified in the static payment code for sending payment request events.

Clients implementing this NIP may:

  1. Support both this protocol and LNURL for backward compatibility during the transition period.
  2. Implement additional features such as multi-recipient payments or integration with other Lightning-related NIPs.

Clients implementing this NIP MUST NOT:

  1. Send unencrypted sensitive information in event content or tags.
  2. Ignore or modify any fields from the encoded static payment code.

Notes

Transition from LNURL

LNURL services wishing to migrate to Nostr Offer STRings should consider adding a noffer tag to their responses.

Future Considerations

Future versions of this NIP may consider additional features such as:

  1. Multi-recipient payments
  2. Integration with other Lightning-related NIPs
  3. Extended metadata for more complex payment scenarios

Reference Implementation

Lightning.Pub / ShockWallet offers branch