Skip to content

Latest commit

 

History

History
89 lines (71 loc) · 3.87 KB

03.md

File metadata and controls

89 lines (71 loc) · 3.87 KB

DIP-03

Private Zaps

Private lightning zaps are a way to send a zap while not revealing the zap author. Only the receiver of the zap can see who sent the zap, and may include an optional private message.

Private Zap Request Event

A private zap request is used to send a zap to a user but only revealing the sender's identity to the receiver. An anon tag is added to the zap request event with the encrypted private zap request event.

The private zap event is encrypted using NIP-04 between the zap request key and the recipient's pubkey. The zap request key is the ephemeral key used to sign the zap request event. The encrypted private zap request event is then added to the zap request event as the anon tag bech32 encoded with the hrp of pzap1 and the iv values of the encryption are added with an underscore followed by the iv being bech32 encoded wit the hrp of iv.

Example Private Zap Event:

{
  "id": "9bf0e1d812e10faa5fd3d2560637f8e99fcbfff478583d2c835754d791acfda5",
  "pubkey": "385c3a6ec0b9d57a4330dbd6284989be5bd00e41c535f9ca39b6ae7c521b81cd",
  "created_at": 1708467377,
  "kind": 9733,
  "tags": [
    [
      "p",
      "aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4"
    ]
  ],
  "content": "Private Zap message!",
  "sig": "48cc725483f41207e83c48f3d01a4e5d341bedcf556e158c19b9faac42bca30e92113049268522cd5052ab3c69850c5df7e2b4fb40c72ce770996edee5a57c8d"
}

Example Private Zap Request Event:

{
  "id": "4ef9df0a6c7dd8b761145acc7055ae077df716bd8c374496d1f598c5b63bcd7a",
  "pubkey": "79d4773fded68a3ea9a30f13e651ff83e150957dacb0c2f6038883d837e1b17b",
  "created_at": 1708466564,
  "kind": 9734,
  "tags": [
    [
      "p",
      "aa4fc8665f5696e33db7e1a572e3b0f5b3d615837b0f362dcb1c8068b098c7b4"
    ],
    [
      "relays",
      "wss://relay.damus.io"
    ],
    [
      "anon",
      "pzap1n0pkup9fxc9w3yd2tvfr03shffrapfz8rtzu9kkq6v222jw5rgtp9myyh378gdtwptpnls8f0rv0v2dyapgt7sssu4263puepgshsj9g4u9y5lvfv9fsujlgvywsuejvftlfzcanu5fmnf2a3grlelwe8v0z4mdkyhr9mddxpswtvp7mtlc4acdys7740t0x5ej36qs5amfzwz5dpwlaf4gsl69lzhqdgc3hgt62xw4y8384a6zvsnf96l3ardkd2vkk6cm77p6v7ul3gwgjr7tra7uzpkvf4hncxp5qd75h6cdadf6n2d7edhc3dyyy7qpdka2mgqhvckhzhd2gcaux34jyw6qfk3nxhaaqs6pqkuy6z34wu2p2fvqqvg55eyqlrndjlgekm7xu08lqc3g0nje59uqu0adqerv2puypez3eck9xzupg4vxyfclk37qfqxra8nt4tk9ydc2tzhpnl4wpf7jf2nrkchknfnfgmezfyqe074dexe5mkxgw67j7zn8s24tae8tml747qnq0edw5jxsx6xfc4qhshf3man0s5duw6wm63ue8fese8c7hanqzphjna3g0ee4jgpwceqzk9jgrvf9rnkt89tkvh75qm65nvtqpud30vecwlqzdlu9fhcaj7jv89gpy32y2k828vsj7x8hmlq55rleeq23e062apenymv96tkvltv266ww6kly2q2t7k6z_iv189a0s9afn7ehz4gpeanueh56cv6t79qk"
    ]
  ],
  "content": "",
  "sig": "95984f4403a4f414436270584a2ea1e3b83c988a0794ed8438f7d214714de3d982edf5eaf494362333ee07b2ce49c64c1d1206ec3914e9c7d7d4bf958d8bbfad"
}

Deterministic Ephemeral Keys

Ephemeral keys can be generated deterministically by generating a private key like so:

func generate_private_keypair(our_privkey: Privkey, id: NoteId, created_at: UInt32) -> FullKeypair? {
    let to_hash = our_privkey.hex() + id.hex() + String(created_at)
    guard let dat = to_hash.data(using: .utf8) else {
        return nil
    }
    let privkey_bytes = sha256(dat)
    let privkey = Privkey(privkey_bytes)
    guard let pubkey = privkey_to_pubkey(privkey: privkey) else { return nil }

    return FullKeypair(pubkey: pubkey, privkey: privkey)
}

The private key is generated using the sha256 of the following data concatenated together:

  • our_privkey: is the user sending the notes private key
  • id: the target note that you are zapping's note id
  • created_at: the target note's created_at as a string

This allows you to decode private zaps that you have sent yourself by attempting to generate a matching pubkey from public data on the target note

Note that this will not work on the web, since NIP-07 does not support hashing the private key into other data.