NIP-BC: Onchain Zaps (kind 8333)#2332
Conversation
|
NACK - I think this is gonna lead to just more p2tr dust utxos and confused users who can't move coins when we exit this low fee environment. Shouldn't be encouraging clients to implement this imo |
|
ohhh now you don't like utxos?? |
The more that I've thought about this over the last few days, I agree with this take. Right now, this works based on the current price and current fee market. In the near future, this may not work if the fiat price increases and/or transaction fees increase. I like the proposal due to Zaps being hard to implement in a UX friendly manner that doesn't add centralization. However, I'm not certain if this is the best path forward. |
|
lol, I was just thinking of re-making Bitcoin Core's Blockchain structure in Kotlin so that we can have the full chain on the phone to validate OTS records without depending on a block explorer... Now I have another idea :) |
If you are not zapping $5, you don't understand this proposal. Zap $5. Stop being cheap. Would you drop 2 pennies into a guitar case? The whole mindset needs to shift. |
|
The idea that if you got 100,000 likes it could convert into money for you is an idea from the dream that Nostr could actually replace Twitter. We're past that point. Nobody can actually survive off 21 sat zaps. It's not even worth the fee of converting Lightning into "real bitcoin" |
|
Also, I suspect that people will be against this for ideological reasons when they have not even tried it. They think it can't work even though it's working right now. |
|
Good thing that on nostr no one can stop anything |
|
NACK in its current form. this would enable a mass utxo doxxing mechanism for everyone using these. let's do it properly with silent payments |
|
I actually don't think the spam issue is that big of a deal since fees are low and the market will adapt to lightning or onchain depending on the fee market, but the privacy does concern me as it links utxos to nostr identities and that can be used to track the entire tx history of a person. would be an amazing resource for chainalytics |
This doesn't make sense to me. Zaps are already public. What are you worried about? |
We don't know where the coins flow after the zap takes place, they don't consolidate with other utxos or show users exchange deposit address the way chain zaps will eventually flow |
|
This is incredibly short-sighted, but I think people should do it, because Lightning is stupid and miners have to be paid. Also if we manage to bloat the UTXO set enough that could be promotion for Nostr, some people might even do a soft-fork to filter onchain zaps from Bitcoin. |
|
Gotta love Claude: Propose adding two optional tags to kind:8333: Then a client with only the bitcoin headers chain (75 MB) can:
Per-event payload cost: ~1 KB We only need block headers! Nothing else from the chain is touched — no transactions, no UTXOs, no scripts, no witness data, no mempool. That is a ~75 MB download for the entire chain, 1–10 minutes wall-clock, ~2 s CPU, ~72 MB on disk directly from the Bitcoin network. Unless you expect more than 1M on-chain zap events on a session. At that time, the cost of downloading the 1-2GB of compact chain filters (Neutrino-style) is better than downloading 1M heavier onchain zap events. |
|
@vitorpamplona added block and proof tags to the NIP |
there is a huge difference. linking onchain zaps to utxos can leak someones entire bitcoin tx history. zaps reveal a single payment and nothing else (and its not even a proof, so its deniable) |
|
Okay, I understand. But the problem with silent payments is that you can lose money on relays, which is exactly what I was trying to avoid. My hope for this spec is that it can provide a path that is extremely frictionless and guarantees access to funds. We can only do that if your key is 1:1 Nostr to Taproot. All your payment data exists on the blockchain. The way I imagine silent payments would work is that you'd tweak the recipient's pubkey and then send them an encrypted message with the tweak. This is already very similar to how nutzaps work, a major problem of which is that if you can't find the event on relays you can't get the money. I prioritize deliverability and access to funds in this design over privacy. Silent payments could still be supported, but I don't think it should be the default path for the majority of users. It just needs to be clear to users that transactions are public, probably by surfacing onchain data in Nostr clients and in feeds, and letting them comment on it with NIP-73. |
|
not sure what you mean you can lose the money on relays. with silent payments you can just put a silent payment address in your profile. we would then just need a mechanism for a bitcoin node to send an onchain zap signed by your key that verifies that the payment is correct, but it doesn't need to doxx any utxos. we could have it send a private and public parts of the zap, where private shows more detailed information. the public part of the zap could have blinded amounts so its not as easy to trace onchain (or could even be optional) |
|
another thing we should consider is zero-conf onchain zaps, like "tx pending". so you would have immediate feedback in apps. bitcoin core nodes have a walletnotify system for handling 0 and 1-conf bitcoin txs, so it would be perfect for this. i already do private onchain zap notifications for all incoming txs using giftwrapped kind1s. standardizing this would be great. |
|
Okay, I didn't really understand how silent payments work. That's mind blowing. 🤯 I'm still grokking it, but isn't it a downside that the client/wallet has to do a lot of work to figure out what your balance is? Chatting with Claude, you have to scan every block, so you can't just rely on an API like mempool.space. You need to either be running a full node or rely on a trusted server. |
|
I just released Ditto Extension on the Chrome Webstore that has support for
It's really good. The screenshots are Halloween themed because it uses your Ditto theme if you have one. It has a built-in onchain Bitcoin wallet. The signPsbt method works with tweaks, so it would be forwards-compatible with silent payments as well as gift-wrapped tweaks. I feel good about it. |
Exactly this! |
They could always try and get a job |
|
I think this works for SP generation so that keys don't need to declare their address. I just don't know exactly what to put into the ZapEvent itself, since it would reveal all the protections that Silent Payments added. Basically, the sender can automatically compute the SP of a receiver's public key and lock the funds into one of the UTXOs. At the same time, nobody else can pull all UTXOs of a pubkey. The address generation, end to endInputs
Sender side (anyone with the npub) Optional override: if the recipient has published a kind 10336 event carrying a hardened Address encoding (BIP-352 standard) Recipient side Parity / lift_x note. The npub is x-only; SP math is on full points. Convention: always That's the whole address spec: one tagged-hash tweak, one point addition, one bech32m encoding. No new event kinds required for the default case; one optional replaceable event for the safe-delegation override. Privacy features
Privacy limitations
One-line summaryA nostr npub becomes an |
A single Bitcoin transaction paying N recipients now produces a single kind 8333 event listing every recipient under its own p tag. The amount tag carries the total sats paid to all listed recipients (excluding the sender's change). Single-recipient events remain the degenerate case. Per-recipient amounts are not encoded in the event; clients that need them recompute them from the on-chain transaction by matching each recipient's derived Taproot address against the tx outputs. The deduplication key simplifies from (txid, target) to txid.
|
I updated kind 8333 to optionally include multiple p-tags. This is for a "make it rain" feature where a single transaction has outputs for multiple Nostr users. |
|
NACK if it's p2tr *, ACK if it's ** the nsec deriving up to a p2pkh or p2wpkh address without vendor lock-in. ETA: |
|
@TheButterZone people have already gotten it working in Sparrow and it should work in recent versions of Electrum. It is p2tr but wallets support it. |
Addresses ambiguities raised by @vitorpamplona in nostr-protocol#2332: - proof requires block (MUST) - block-height: stringified non-negative integer <= 2^31-1, no leading zeros - block-hash-hex and txid in display order; merkle-proof hashes in internal byte order - leaf is txid = dsha256(strip_witness(rawTx)) - merkle-proof-hex is N 33-byte steps: 1 direction byte + 32-byte sibling - direction 0x00 = sibling right, 0x01 = sibling left, other values reject - N MAY be 0 (1-tx block): empty proof, verifier checks txid == merkleRoot - N MUST NOT exceed 32; length MUST be a multiple of 33 - odd-level duplication: producer emits direction=0x00, sibling=cur - include verification algorithm pseudocode - sender MAY publish twice (pre-confirm without tags, post-confirm with); verifiers dedupe by (txid, recipient-set, target) and prefer the variant with a valid SPV proof - failed proof falls back to remote verification, not a hard reject
|
@vitorpamplona Updated |
Optional Compatibility Layer for Legacy Bitcoin Addresses (Non-normative)Thanks for the work on this PR — the Taproot mapping is clean and well-scoped. While reviewing the use of x-only secp256k1 keys (BIP340-style), I ran into a practical interoperability edge case that may be worth documenting as an optional, non-normative compatibility note. ContextNostr public keys (npub) are 32-byte x-only secp256k1 values.
require a compressed secp256k1 public key, which includes a parity byte: Since x-only keys omit parity, a deterministic rule is required if legacy address display is desired from only an npub. Proposed Compatibility Rule (Deterministic)If implementers wish to derive legacy Bitcoin addresses from an x-only Nostr pubkey:
This yields a deterministic mapping: Optional Wallet Interoperability (Private Key Export)Nostr private keys are not defined in Bitcoin wallet formats. However, for interoperability with existing Bitcoin software: Nostr clients MAY optionally expose Bitcoin compatibility by deriving WIF from nsec for import into existing Bitcoin wallets. This is strictly an implementation convenience and is not part of the Nostr protocol or key format specification. Why this design choice (anticipated objections)Objection 1: “Why force even-y? Isn’t that arbitrary?”Yes — but parity is not recoverable from x-only keys, so any legacy mapping must choose a convention. We choose 0x02 because:
Importantly:
Objection 2: “Why not use both 02 and 03 and pick one?”Using both would produce:
This would defeat determinism, which is required for interoperable wallet behavior. Objection 3: “Why include legacy address derivation at all?”This is strictly optional and not part of Taproot behavior. It is included only because:
If not needed, implementations MAY ignore this entirely and use only Taproot (P2TR). Full Reference Implementation (Python)Relationship to Taproot (important scope clarification)This does not modify Taproot behavior.
SummaryThis proposal adds:
Response to “Out of scope / should be omitted”A likely objection is that legacy Bitcoin address derivation should not be included in a Taproot-focused or Nostr-focused specification. However, this note does not introduce new functionality or expand protocol semantics. It only formalizes an existing ambiguity in implementation space. Key pointGiven an x-only secp256k1 public key, any system that attempts to derive a legacy Bitcoin address must choose one of:
This choice already exists implicitly in any implementation that supports such conversion. Without standardization, different clients will produce different addresses for the same Why omission does not remove the problemIf this note is omitted:
Thus, omission does not avoid the behavior — it only prevents it from being deterministic. Why inclusion is safeThis proposal:
Design principleThis follows the same principle used in other standards:
[With help or help? from ChatGPT, including a bunch of code iterations & runs on https://playcode.io/python-playground - since I can barely code & read console output... I beg forgiveness/steelman/for a pointer anywhere else I should post this. Thanks in advance.] |
Let me paint you a picture: Let’s say I’m a criminal, and I "on-chain zap" everyone on nostr. Some of my targets will inevitably move their UTXOs to cold storage, potentially combining what I’ve sent (and what I’m now tracking) with their main stash. I have a script running that notifies me of this (only if it’s above a certain amount, of course). A couple of days later I get such an alert. Jackpot. Generational wealth. I rub my hands as I browse nostr for the latest posts of my unsuspecting victim. Between memes and casual shitposts I find a link to a concert as well as an image they took on a stroll. There’s a mountain range in the background. I paste the image into a geolocation engine. It matches the concert location almost perfectly. I scroll further down and find multiple selfies and a photo of their dog. I now know where they live, what they look like, what their dog looks like, and where they usually go to take their dog on a walk. In short: a small zap could lead an attacker to a very large bounty. This is not an issue with regular zaps. |
Yes, any sane proposal would have to use blinded or otherwise obfuscated amounts, destroying a large part of what makes zaps interesting. Zaps and numerology go hand-in-hand. |
|
I just added a warning to inform users who are trying to drain the wallet not to mix their nostr funds with their cold wallets and always fund or drain from exchanges. That fixes your concern. |
|
NACK for reasons articulated at length here. Lots of footguns, lots of negative long-term implications. The negative effects outweigh any supposed benefit by a mile. |
Warning the users doesn't magically "fix" things. Also:
|
That's why if you're intelligent enough to not need 24/7 guardianship/caregivers, you will dedicate one cold storage address for receiving all your coins you ever received at a public address that was associated with your identity (whether actual or same-pseudonym). That means all the Zap sats go there, all the p2pkh & p2wpkh tipping/donation address coins also go there, and then that cold storage address either already was separate from every other address by keeping it as a paper wallet or 1-private-key-only wallet file or at a minimum, frozen & labeled as cold storage within your main wallet. If you have a change output (I personally try to avoid spending a key until 100% of it goes to receiver with no change), it goes to a new change address that you label & then freeze (and burn/label as burned, the previous cold storage), because that's your new public cold storage. Heck, if you're feeling charitable at burn/address rotation time, you can save yourself the step of immediately creating a new public cold storage by spending the change to charity instead of yourself. It's self-evident that no implementation (which will always have at least one thing to warn about), will ever be enough for paternalists, who inexplicably act like it's possible for people who need 24/7 guardianship/caregivers to use bitcoin, let alone the internet, as safely as possible alone. Time to stop painting anyone else with that infantilization brush. |
|
Part of the argument seems to be "great UX" and "easy," so thank you for making my point for me. |
|
In addition to all of the above I want to repeat a point that was made in a stacker.news discussion:
Footnotes |
Nah, I don't tolerate mini-gish-galloping. You want to fully-spec out and defeat the Bitcoin Software Iron Triangle for both competent users and people who require 24/7 guardianship, Gigi? Please do. But don't cheat by making 'great UX' and 'easy' separate dimensions, they fall under Usability. What are the other two dimensions, and how do you prevent any trade-off between the three so that the needs of those requiring 24/7 care will never force competent users to suffer a trade-off in their own sovereignty, usability, or security? |
|
This seems a really questionable idea, with a lot of problems and few advantages in addition to the temporary fun factor; I fully agree with @dergigi, who carefully explained the issues in his last article. |
I don't want to do that. I want to point out various issues that seem to be either overlooked or downplayed, and hopefully educate some of the newer people who haven't thought deeply about these issues. In addition to the conceptual problems that I hopefully managed to explain somewhat coherently, there's plenty of cryptographic issues as mentioned above.
So am I. |
"I don't want to do that' is a tacit admission that the Iron Triangle cannot be defeated. You said you wanted to educate newcomers, Gigi, but redirecting people to your blog (which not all may agree is coherent) is just a detour to avoid a live engineering paradox. Let’s actually educate them right here: your stance forces users requiring 24/7 guardianship to rely on 3rd-party solutions. It confirms that Bitcoin's inherent security, usability, & sovereignty trade-offs cannot be designed away. Your essay simultaneously reads as a critique of on-chain zaps & Bitcoin's base layer itself. You claim zaps are bad because they link identity to money & expose finances forever. But those aren't design flaws of zaps, those are the literal engineering realities of Bitcoin's public ledger. Pushing users to L2 to escape this isn’t defeating the Iron Triangle. It’s a total surrender of sovereignty & security. To run a truly self-sovereign Lightning node, users face extreme technical complexity & crippling on-chain capital costs just to manage channels. For the average person, & especially for someone requiring 24/7 care, that is impossible. So what is your actual alternative? Forcing them onto custodial wallets & 3rd-party clearinghouses where they hold nothing but IOUs. Lightning doesn't solve the triangle. It forces a brutal trade-off: you either keep your keys online 24/7 in a highly vulnerable hot-wallet environment, or you hand your security over to a middleman. Stop pretending L2 is a magic wand when it explicitly strips away the very trustlessness that makes Bitcoin valuable in the first place. You can't build a single software wallet that accommodates someone requiring 24/7 guardianship without introducing 3rd-party trust or guardrails. If you force those same guardrails onto competent users, you destroy their absolute sovereignty. We must stop pretending we can design away these fundamental trade-offs with clever UX or layers. We must accept them. And we must practice direct, absolutely-concise counter-evangelism to the provably-mentally-competent caregivers of those most at risk, ensuring they know how to protect vulnerable individuals under their care from a system mathematically bound to offer zero safety nets - DON'T LET THEM USE TECHNOLOGY THAT SUPPORTS L1-L∞. Education can only help the mentally competent. The engineering laws of the triangle remain undefeated. |
I'm not here to pretend that trade-offs don't exist. I am painfully aware of the trade-offs that Lightning, LUD-16 identifiers, NIP-60/61, or npub.cash bring.1 I think they are worth making. I joined the discussion to point out certain risks and complications that I didn't see discussed, and I wanted to point them out so developers (and users) can make a proper judgement call when it comes to deciding what to implement (and what to use). I'm not against on-chain transactions, to the contrary. I'm against permanently and irreversibly tying identities to on-chain activity. I think it's a trade-off that isn't worth making. I think it will harm users in a multitude of ways and it has the potential to harm the network as a whole. But I think I made my point.2 Footnotes |
We did make those tradeoffs. But none of them work very well. It's not that we didn't try. Heck, we made our own NWC just to go around the lightning API shitshow. I know it's hard to hear when better privacy tech fails to gain traction, but the world isn't fair. I think the trade-offs listed for each technology were grossly underestimated by everyone, and the privacy limitations of each stack, when put in practice, draw the final straw: "not worth doing". Lately, not even Silent Payments has convinced me that it is worth working with for Zaps. I remain open to solutions, and I am happy to test crazy ideas anyone can make. But those ideas need to work in practice. Until then, we are stuck in 2014 tech. |
|
For the first time ever, Bitcon on Nostr actually works. |
|
I would like to separate money and identity and don't like the idea that a client, without my permission, can derive a bitcoin address from my nostr pubkey. Period. I think I know the answer, but my first question that comes in mind is "are there any technical solutions to prevent others creating UTXOs tied to that address"? |
There are not, because in Python, anyone can derive a bitcoin address from virtually any data, no client necessary (and in fact this was done in 2023, someone just discovered & Noted) & then create a UTXO tied to that address, period. The only way to "win", is to not play against all human/machine-kind - don't even generate a npub/use Nostr, in the first place. Like asking if you can put the genie back in the bottle, or undo the laws of cryptography. |
Of course. But does that mean that a bitcoin wallet should encourage users to use "bacon bacon bacon bacon..." as their seed phrase? Of course not. These types of seeds are dangerously insecure. You can also use any string of characters as a password, but that doesn't mean that we should build software that auto-suggests Reusing cryptographic keys across purposes goes against all the best practices we know, not only for conceptual reasons, but also because it weakens the cryptography of the keys and opens up a multitude of attack surfaces and other issues. To quote Bruce Schneier et al. once more: "this should be avoided whenever possible" The question at hand is not "is this possible?" The question at hand is: should this be a NIP? I think the only sensible answer to that question is a resounding NO. |
|
Allow me to make one more comment: if this becomes a NIP or some other form of de-facto standard (because big clients like Amethyst decide to implement it, or even more dangerously: make it some kind of default) one of the side-effects might be that nostr devs are "forced" to deal with the intricacies of bitcoin wallet development. Developing a secure bitcoin wallet is hard. Very hard. I've watched the discourse about on-chain zaps quite closely, and I was shocked to see that many nostr devs have no idea what a UTXO is, don't know what "coin control" is1, and so on. This is worrisome. Cryptography is hard. There's a million ways to make mistakes that lead to catastrophic loss. To quote Phil Zimmermann: "Most people don’t realize how fiendishly difficult it is to devise an encryption algorithm that can withstand a prolonged and determined attack by a resourceful opponent." Putting a bounty on every npub is a surefire way to bring prolonged and determined attackers.2 I remain steadfast in my initial assessment of this proposal: NACK Footnotes
|
|
I strongly agree with all the NACKs here for all the reasons that have already been outlined. |
You really just can't resist raising the specter of those needing 24/7 guardianship/care managing to use L1-L∞ compatible technology with ease, can you? No mentally competent person would follow that encouragement, allow anyone under their care to be encouraged all the way to harm, nor would anyone, who is mentally competent, think a productive use of their time would be to actually try to encourage other mentally competent people to do that. Beyond parody.
So does having P2TR UTXOs that never had to do with "onchain zaps", which you have to keep on the move or spread so thin that likely no CRQC operator (likely totalitarian state actors) would even bother cracking your keys. Oh no, I've just lost plausible deniability because I didn't practice perfect hygiene while moving them! Taproot going mainnet as-is was a mistake.
You think https://github.com/nostr-protocol/nips/blob/master/04.md is the only NIP that can ever have warnings against itself included & THIS NIP being merged won't lead to disinfectant by hypernova-level sunlight? Warnings divided across platforms, few even having a link to this PR in their respective threads, without one authoritiative target to focus the beams on, OTOH... Apparently it took years from 01 to 44 for https://github.com/search?q=repo%3Anostr-protocol%2Fnips%20quantum&type=code to be explicitly acknowledged. And, didn't NIST already reach Round 3 of its PQC standardization process (to replace vulnerable algorithms like Schnorr and ECDSA) by July 2020, just before NIP-01 was published? It's ~3 years past time for this NIP with warnings from all angles about doing what started? being done with npubs in 2023 (if not earlier & just not discovered yet). P.S. https://x.com/TaoistBitcoiner/status/1676276971821572109
https://x.com/mdhardcastle/status/1893736080437916065
And yet even we who understand, persist. |
I think you are on the wrong protocol. The ONLY point that Nostr made from an innovation perspective was to acknowledge the risks and work around the flaws of reusing a single pubkey for everything on the web. You want something Nostr itself cannot provide. When it tries to provide, the UX suffers so much that our products either have to become trusted/centralized or they simply cease to be usable. The reason Bitcoin works is that the chain is public. Every stack that has tried to make Bitcoin private has failed to build a UX that users can truly depend on for life. People get pissed when things fail, but that is fine because the chain is always there as a fallback. These stacks have always been an "experiment" and may never evolve from there. The chain will always work On Nostr, we have been trying to make these shitty protocols work without any fallback. When things fail, our users get pissed because there isn't any stable fallback. This PR was the first attempt to create something that NEVER fails. I stress. NEVER is truly NEVER. 30 years from now, the funds will be there. We cannot say that for any other wallet solution out there. And users are tired of how flimsy these solutions are. |
NACK |
# Conflicts: # README.md
I was with you up 'til here... this most likely would be true, if only hardened public key hashed addresses derived from nsec+passphrase were the standard everyone opted to use (#2360), not unhardened, CRQC-vulnerable Taproot. Who will be most likely to be the first to achieve/control CRQC? Totalitarians/nation-states who will seize the peoples' means of economic liberty, as always - whether people within their borders or without. The marketing & implementation of Taproot/Schnorr signatures into mainnet bitcoin couldn't have been written by totalitarians any better. It's well past time to destroy their trap & make all BTC hardened again. |



This NIP introduces onchain zaps, as implemented by Ditto.
Big discussion here: https://ditto.pub/nevent1qgsqgc0uhmxycvm5gwvn944c7yfxnnxm0nyh8tt62zhrvtd3xkj8fhgqyz3ccj3j3lhzu756pyznc0qhe4umqhsu628c88cfef5j8k5jqwtks6w7gqw