What is Nostr?
IngwiePhoenix / Ingwie Phoenix
npub1tce…jmky
2025-02-23 16:58:08
in reply to nevent1q…8g30

IngwiePhoenix on Nostr: Ready for some low-level nostr? Because I will not hold back. First, let's reference ...

Ready for some low-level nostr? Because I will not hold back.

First, let's reference the required information: https://github.com/nostr-protocol/nips/blob/master/57.md

NIP-57 consists of a few events; their flow is well explained right away. From that flow, we only need part of step 1 (their public key, npub), 3 (the fake event we will generate), ignore 4, 5, 6, and 7, we will absolutely fake 8, and quietly ignore 9 with a smirk.

I will be using fiatjaf's nak tool for this; it is the easiest way to make this and I will use my own npub for a demonstration, on your post, to show you how this works.

First, I need your npub. Easy, your profile, right there - and store it.
I also need the ID of your post. That one is quite easy to grab. Unfortunately, Primal's cache servers isn't entirely nostr compliant; trying to grab events from it returns weird replies... O.o Oh well, I'll just assume that one of "the big ones" have your event too.
However, I have to convert the keys first.

root@superdiskboi ~# setenv TARGET_NPUB "npub1plrayr9zxu7qw365xrrmckx9ygql9rfj583khlcksen7eapj0lkqvv499t"
root@superdiskboi ~ [1]# setenv MY_NPUB "npub1tcekjparmkju6k83r5tzmzjvjwy0nnajlrwyk35us9g7x7wx80ys9hjmky"
root@superdiskboi ~ [1]# setenv TARGET_NPUB_HEX (nak decode $TARGET_NPUB | jq -r ".pubkey")
root@superdiskboi ~ [1]# setenv MY_NPUB_HEX (nak decode $MY_NPUB | jq -r ".pubkey")
root@superdiskboi ~ [1]# echo $TARGET_NPUB_HEX
0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec
root@superdiskboi ~# echo $MY_NPUB_HEX
5e336907a3dda5cd58f11d162d8a4c9388f9cfb2f8dc4b469c8151e379c63bc9

Cool. I can use that for requests now - so, lets fetch your reply right up there:

# nak req -a $TARGET_NPUB_HEX -p $MY_NPUB_HEX --limit 5 wss://nos.lol
connecting to wss://nos.lol... ok.
{"kind":1,"id":"8a36028fb98d27a3529736432a122b1721f4ae144e8271be3b84dd9e0293fd5d","pubkey":"0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec","created_at":1740326940,"tags":[["e","ce2fa5cf30573050d4f79f601beae49a66d265f15673abf5cb40e5b81d63a06a","","root"],["e","7b6d5c795a1b129619cbfdc2197b5c0fd13606d60ec71f2cecad120f314c841f"],["e","29051fdea21103f94926792a420a0db3aff40f6df39fde46a868a52f22387285","","reply"],["p","e2ccf7cf20403f3f2a4a55b328f0de3be38558a7d5f33632fdaaefc726c1c8eb"],["p","0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec"],["p","5e336907a3dda5cd58f11d162d8a4c9388f9cfb2f8dc4b469c8151e379c63bc9"]],"content":"How does one create a fake zap event? ","sig":"a103258815d3279a77ebc704abbb8ddd1f3dd947757e6c002bffb0031552b102def36ca51f9558fd0ce5efc9c7ea8a77ac989af577ad0469fdae00c95dd4a1be"}

Sick. The ID is what I need to make a reference to this note. So, I saved that together with the JSON blob.

As per the NIP, I _should_ normally contact your LNURL and check if you are Nostr enabled and blah blah - but let's just pretend that yours does accept Nostr and I could fetch an invoice and send the payment and your server happily returns me with a result; to quote, "Once the invoice is paid, the recipient's lnurl server MUST generate a zap receipt as described in Appendix E, and publish it to the relays specified in the zap request."

Each Nostr-enabled LN-Server/-Service has it's own npub/nsec. Let's make one for the pretend real quick.

root@superdiskboi ~ [1]# setenv FAKEPAYER_NSEC_HEX (nak key generate)
root@superdiskboi ~ [1]# setenv FAKEPAYER_NPUB_HEX (nak key public $FAKEPAYER_NSEC_HEX)
root@superdiskboi ~ [1]# echo $FAKEPAYER_NPUB_HEX
0658eebe021d9d3a0ec2bf4dfe066dda7e0b6c498a9d7483cfd1e512977deb83

Good! Our fake LN-Server has an identity now. Lit.

Now, we need to generate the fake "zap receipt", an event of kind 9735, a p-tag with the receipient (your) npub, e tag for the event (for which I grabbed the ID above), a fake "Bolt11 Zap Receipt", and an encoded Zap Request - which in itself is just a nostr event of kind 9734 with basically the same settings (target post in e, target npub in p and an amount tag - I will set this to something humane).

Let's start bottom-up:
(I) paid (you) 1k sats on your reply (id):
# nak event --sec $MY_NSEC_HEX -k 9734 -e $YOUR_REPLY_ID -p $TARGET_NPUB_HEX -t amount=1000 -t "lnurl=damneddespot724@minibits.cash"
{"kind":9734,"id":"047b4897cfc34a59bcaa05df0341d19b5419165bc5a187fb25b76a41f4a78d5f","pubkey":"43554621089946f0d76870db76f08451048d924a899ae01ffe374a29bb8e3cf3","created_at":1740328851,"tags":[["amount","1000"],["lnurl","damneddespot724@minibits.cash"],["e","8a36028fb98d27a3529736432a122b1721f4ae144e8271be3b84dd9e0293fd5d"],["p","0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec"]],"content":"","sig":"6a21986a90633b119097f8e62493d502b2d6df69e01af9b1ad0ca3eccf88bf57e51d78981a6359f97154a0ec6a9999fc4a53a2981d22d4a54432cf67e934c848"}

That's the "zap request" we sent off to the non-existent server.

Next, we need a fake bolt11 "containing the description hash bolt11 invoice". Nope, don't think so. In fact, I'll throw some completely arbitrary information in there - because no relay in Nostr-land actually verifies those anyway - not even the clients. :D

# setenv BOLT11_DESCRIPTOR "idontthinkthiswillreallymateranywaysoallowmetowritesomethingstupidinherelol"

Next, "The zap receipt MUST contain a description tag which is the JSON-encoded zap request". Bruh. literally stringifying a stringified JSON? aight...

# echo '{"kind":9734,"id":"047b4897cfc34a59bcaa05df0341d19b5419165bc5a187fb25b76a41f4a78d5f","pubkey":"43554621089946f0d76870db76f08451048d924a899ae01ffe374a29bb8e3cf3","created_at":1740328851,"tags":[["amount","1000"],["lnurl","damneddespot724@minibi
ts.cash"],["e","8a36028fb98d27a3529736432a122b1721f4ae144e8271be3b84dd9e0293fd5d"],["p","0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec"]],"content":"","sig":"6a21986a90633b119097f8e62493d502b2d6df69e01af9b1ad0ca3eccf88bf57e51d78981a6359f97154a0ec6a999
9fc4a53a2981d22d4a54432cf67e934c848"}' | podman run -i php -r 'echo json_encode(file_get_contents("php://stdin"));'
"{\"kind\":9734,\"id\":\"047b4897cfc34a59bcaa05df0341d19b5419165bc5a187fb25b76a41f4a78d5f\",\"pubkey\":\"43554621089946f0d76870db76f08451048d924a899ae01ffe374a29bb8e3cf3\",\"created_at\":1740328851,\"tags\":[[\"amount\",\"1000\"],[\"lnurl\",\"damneddespot724@minibits.cash\"],[\"e\",\"8a36028fb98d27a3529736432a122b1721f4ae144e8271be3b84dd9e0293fd5d\"],[\"p\",\"0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec\"]],\"content\":\"\",\"sig\":\"6a21986a90633b119097f8e62493d502b2d6df69e01af9b1ad0ca3eccf88bf57e51d78981a6359f97154a0ec6a9999fc4a53a2981d22d4a54432cf67e934c848\"}\n"

Yep, old reliable. Didn't have node on my system, and I had just pulled PHP down so... here we are. Strip the \n at the end, and we have ourself a stringified json string. woop. x.x

Alright - now let's fill out all the blanks and construct the actual zap event, 9735:

# nak event --sec $FAKEPAYER_NSEC_HEX -k 9735 -e $YOUR_REPLY_ID -p $TARGET_NPUB_HEX -d "bolt11=$BOLT11_DESCRIPTOR" -d "description=$FAKE_PAY_REQUEST"
{"kind":9735,"id":"328670ccb23504127f476449f968c0a6fc5dddf6e3bb1107a4e1f7c65cce935a","pubkey":"0658eebe021d9d3a0ec2bf4dfe066dda7e0b6c498a9d7483cfd1e512977deb83","created_at":1740329750,"tags":[["e","8a36028fb98d27a3529736432a122b1721f4ae144e8271be3b84dd9e0293fd5d"],["p","0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec"],["d","bolt11=idontthinkthiswillreallymateranywaysoallowmetowritesomethingstupidinherelol"],["d","description={\"kind\":9734,\"id\":\"047b4897cfc34a59bcaa05df0341d19b5419165bc5a187fb25b76a41f4a78d5f\",\"pubkey\":\"43554621089946f0d76870db76f08451048d924a899ae01ffe374a29bb8e3cf3\",\"created_at\":1740328851,\"tags\":[[\"amount\",\"1000\"],[\"lnurl\",\"damneddespot724@minibits.cash\"],[\"e\",\"8a36028fb98d27a3529736432a122b1721f4ae144e8271be3b84dd9e0293fd5d\"],[\"p\",\"0fc7d20ca2373c07475430c7bc58c52201f28d32a1e36bff168667ecf4327fec\"]],\"content\":\"\",\"sig\":\"6a21986a90633b119097f8e62493d502b2d6df69e01af9b1ad0ca3eccf88bf57e51d78981a6359f97154a0ec6a9999fc4a53a2981d22d4a54432cf67e934c848\"}"]],"content":"","sig":"1a508d6444a3f1dd36d946a05e0af4a6626e7ed593b584f2133c7d42f15ef0296c87ef901d5c7767636ffa836ef5cf0a00ce30c3cd781e004de6dee36be5efdd"}

And there we have it: A zap event with a bogus zap request that never received a real bolt11 invoice but fullfills the entire schema - and, how to get there.

You can put that into a simple, single shell file and rumor has it people have done this before to fake interaction on Nostr. Some people really are that lonely, but considering how easy it is to fake them, I guess you can see how why it works. x)

By the way, this IS a valid set of events. Those ARE verifiable. Do not put them on a relay, please? Not that it would do anything, but - out of respect, yknow. o.o
Author Public Key
npub1tcekjparmkju6k83r5tzmzjvjwy0nnajlrwyk35us9g7x7wx80ys9hjmky