A method for transferring HTTP communication over Nostr direct-messages#1276
A method for transferring HTTP communication over Nostr direct-messages#1276oren-z0 wants to merge 1 commit intonostr-protocol:masterfrom
Conversation
970b7e0 to
6dc5be3
Compare
|
Very cool! But don't use NIP-04 or NIP-17 for this. Just create your own event kind. NIP04 and NIP-17 are for plain text, human-readable content. You can just use the same encryption (NIP44) in a different kind that is designed for this, like NIP-46 and NIP-47 do. |
HTTP is also plain text, human readable content (over TCP). I don't see a reason for a new event kind - it will just add unnecessary complexity and security concerns. A remote observer should not be able to tell if this is a direct-message with "human" content or an http request/response. If the direct-messages are secure enough, then they're good for any type of content. K.I.S.S. |
|
A new event kind allows processors to filter only the messages they need to parse. There is no need to download the 1000s of DMs just to process one of these calls. In the same way, there is no need to download these messages if you only want to show DMs to the user. Don't overload event kinds. Reusing the same kind for everything is not kiss. |
|
We do this with Lightning.Pub (kind 21000) using protos for http-nostr An ephemeral kind is necessary because otherwise you're going to fill up a relay with all http events As for the lnurl piece, there's still an ssl requirement for reverse compatibility so a new bi-directional RPC has replaced it since we no longer have the limitations of url's themselves |
I totally agree with the ephemeral part. I can also imagine a use-case for ephemeral direct-messages (sending encrypted direct-messages that there is no reason to keep for long-term). We can have kind Give me a js library that support it and I'll upgrade http2nostr and nostr2http to use them (Let's start with a js library that implements NIP-17?). Managing your node over Nostr instead of TOR or Tailscale is also really cool, but from a quick look at Lightning.Pub it feels like you're trying to reinvent the idea of HTTP JSON apis. It may be more efficient, but does it worth it? My initial idea was not even to implement "HTTP over Nostr direct-messages", but implement "TCP over Nostr direct-messages", but there are more edge-cases to support. |
NIP-04 has been deprecated. There is no benefit on creating something based on that encryption standard.
You are confusing some of the kinds. The encryption you are looking for is NIP-44. That can be used in any kind you see fit, including directly in the Kind Kind Again, NIP-46 and NIP-47 are the model you should be copying. Just replace their use of NIP-04 encryptions for NIP-44 encryptions.
The NDK and nostr-tools both support NIP-44 encryptions. |
Who cares if the content is a human-readable text or a string containing a JSON object? It's too much math for me 😨... Please implement in @rust-nostr/nostr-sdk or in a different js library some |
I do. I don't want to have to deal with custom JSONs polluting everything. We don't even accept Markdown in chat messages. I don't even understand why you are insisting on this. Just pick a different number to separate things out. It's not hard. This is why event kinds were designed for... So that we don't need to parse every type of payload out there. |
I don't know who told you this, but that is not what DMs were designed for. |
|
OK, I actually found out that @rust-nostr/nostr-sdk already implemented NIP17, so implementing something similar with different kinds shouldn't be too difficult. I just wanted the implementation to be quick, and was frustrated to find out that I need patches for many repos (both the main LNbits repo, the LNbits lnurlp extension, the LNbits lnurl parser, etc.). I'm worried that if we add another kind it could take months for actual wallets to implement this. Let's see if I understand how NIP17, etc. work. So suppose I'll use {
"id": "<usual hash>",
"pubkey": "<sender-pubkey>",
"created_at": "<now>",
"kind": 50,
"tags": [
["p", "<receiver-pubkey>", "<relay-1-url>", "<relay-2-url>"] // can we have more than one relay here?
...
],
"content": "{
\"id\": \"0da8a3dd-80e2-4fca-ba93-5c4261edcc9e\",
\"url\": \"/api/test\",
\"method\": \"GET\",
\"headers\": {
\"accept\": \"*/*\",
\"user-agent\": \"curl/8.6.0\"
},
\"bodyBase64\": \"\"
}"
}The response message could have {
"id": "<usual hash>",
"pubkey": "<sender-pubkey>",
"created_at": "<now>",
"kind": 51,
"tags": [
["p", "<receiver-pubkey>", "<relay-1-url>", "<relay-2-url>"] // can we have more than one here?
...
],
"content": "{
\"id\": \"0da8a3dd-80e2-4fca-ba93-5c4261edcc9e\",
\"status\": 200,
\"headers\": {
\"date\": \"Fri, 31 May 2024 00:00:00 GMT\",
\"content-type\": \"application/json; charset=utf-8\"
},
\"bodyBase64\": \"eyJoZWxsbyI6IndvcmxkIn0=\"
}"
}
I actually do think it's important. Suppose I'm scanning a static lnurl-pay QR code - I would really prefer that nobody could tell that I interacted with this server - by wrapping whatever needs to be wrapped. Suppose the client uses {
"id": "<usual hash>",
"pubkey": randomPublicKey,
"created_at": randomTimeUpTo2DaysInThePast(),
"kind": 1059, // gift wrap - is there an equivalent ephemeral gift-wrap?
"tags": [
["p", serverPublicKey, "<relay1-url>", "<relay2-url>"] // we can have more than one, right?
],
"content": nip44Encrypt(
{
"id": "<usual hash>",
"pubkey": clientOneTimePublicKey,
"created_at": randomTimeUpTo2DaysInThePast(),
"kind": 13, // seal
"tags": [], // no tags
"content": nip44Encrypt(unsignedKind50, clientOneTimePrivateKey, serverPublicKey),
"sig": "<signed by clientOneTimePrivateKey>"
},
randomPrivateKey, serverPublicKey
),
"sig": "<signed by randomPrivateKey>"
}The server response doesn't need to be wrapped, because it's going to send only one message to {
"id": "<usual hash>",
"pubkey": serverPublicKey,
"created_at": randomTimeUpTo2DaysInThePast(),
"kind": 28000, // a new kind for "ephemeral-server-response"?
"tags": [
["p", clientPublicKey, "<relay1-url>", "<relay2-url>"]
],
"content": nip44Encrypt(unsignedKind50, serverPrivateKey, clientOneTimePublicKey),
"sig": "<signed by serverPrivateKey>"
}WDYT? The only thing remote users/relays might see is requests sent to the server (by unknown users) and the server responds to one-time public-keys that are never seen again. If the load on the server is high enough, it would be even harder to match a request to a response (and they are also encrypted). P.S. Will you be at BTC Prague? Maybe we could discuss over there. |
|
Nice, I think you got it. You can use the On the p tags, you can only use one relay url. But you can use the |
|
Thanks @vitorpamplona 🙏 |
|
You can just gift wrap both ways. Yes, people can send a GET to see if it is a server, but the server might not reply to random GET commands if they are truly private. Their protocol can add a little invite token to register keys that can use the service. Also, a single key receiving multiple wraps might just be any other type of service, using a different protocol. So randomly sending GET might not be that effective of an attack. |
2bb41ff to
aee0a1b
Compare
|
@vitorpamplona I've added the changes for sealing and gift-wrapping (in a new commit - could be squashed in the future). New kinds:
|
fff2647 to
3cd22c0
Compare
|
@vitorpamplona I've added the See the implementation using nostr-tools: https://github.com/oren-z0/http2nostr https://github.com/oren-z0/nostr2http @fiatjaf - Who is in charge of giving numbers to NIPs? I suggest "NIP-80" after the default http port. |
|
Hi, is it still proposal state? |
|
@4xvgal Closed it. It's not a good idea to transfer large amounts of data over Nostr notes, despite the advantages of bypassing NAT etc. |
Calling lnurl like small, one time rpc/api are reasonably more than whole http. Is the reason close the pr is latency issue or care about relays's infrastructure? Cuz i made nostr tunneling middleware for hide app server behind nat |
|
CLINK is a nostr successor for lnurl, also has a bridge and support for debits etc |
|
@4xvgal It's more about the infrastructure. It doesn't make sense to split large traffic into many many small signed notes, and relays will rightfully treat it as spam. HTTP-based protocols like LNURLs that pass small amount of data, should build an equivalent nostr-based implementation. For large amounts of p2p traffic that needs to bypass home routers NAT (which needs a static public ip address & port-forwarding), there are TOR and other technologies (my favorite is https://holesail.io ). |
|
@shocknet-justin |
What if run holesail connection string exchange server behind nostr-tunneling? That makes holesail host server can be run on no domain, CA/TLS just pubkey. This could be self VPN network service with just npub |
Lots of ways, ground up approach like an rpx, bi directional with sub specs, and sdk.. in use in various projects |
|
@4xvgal I'm not familiar enough about how holesail works in the background, but it creates an hs:// URL followed by a public-key (I think), so it's not that different from an npub anyways. |
Example use case: https://v.nostr.build/VAREX7f6XB8sTPQr.mp4
(and here is the old video that was implemented with NIP-04 direct-messages not following this NIP exactly but showing the purpose: https://vimeo.com/950881613 ).
Implementation: http://github.com/oren-z0/http2nostr http://github.com/oren-z0/nostr2http
rpm-packages: http://npmjs.com/http2nostr http://npmjs.com/nostr2http