-
Notifications
You must be signed in to change notification settings - Fork 634
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NIP-19: add nreq
#882
NIP-19: add nreq
#882
Conversation
seems like a good idea to me |
Ok, so one thing @Semisol pointed out is that you can't reference a list of authors (i.e. follow list or whatever) in this. In coracle I have a |
So you want unix pipes? |
yes |
Can we make an entity that's turing complete? |
Edit: sorry, I'll stop spamming everyone now |
I like the idea of nreq, but this one seems a bit limited? It could be powerful if it is just any filter+relays+title so you could share almost any kind of feed. |
As you know this isnt how i implemented it, i feel like putting TLV entries for search/limit/until into NIP-19 just doesn't make any sense because they dont apply to the other prefixes. I simply put the JSON req filter array into type 0, then i just pass this value directly to query system, its very simple and flexible. A link to fiatjafs 10 latest posts: |
This looks good, I think the addition of a title or description field would improve it because the request can be anything. Right now you said "A link to fiatjafs 10 latest posts" but it could have been just part of the nreq and a client would just render a link titled "fiatjafs 10 latest posts" and after clicking it it would open the feed. |
I like |
I think that description within the entity may be superfluous since the filter is self-explanatory, if you want a description it could be formed by parsing the filter and verbosing. |
I am not sure if this is feasible. Sure we can share filters (I like @v0l's idea of a single text field) but it's really hard for the Client to figure out how to display the results. What if it is a filter for chat messages? You would have to somehow parse the filter, see that this is returning only chat messages, and direct the user to that View type. Obviously, most filters will return a set of different event kinds. What happens if the filter is just anything by users X, Y and Z at the same time? It's not a profile view. Reactions are mixed with DMs, which are mixed with ephemeral NWC events, etc.. What do you do when you open this in your client? We don't have a super generic way to build a view for that. |
Coracle's feeds can mostly handle this (other than DMs which is a degenerate case). If a client dev doesn't want to build generic feeds, they can also open the link in a client which does support it (maybe njump could have an nreq page). |
Sure, feed-based clients can just dump the whole thing in front of the user without any additional context. I don't know how to display a Zap Request or an Event Deletion but if it is in the filter it should be displayed somehow. This, of course, assumes this link is to be displayed. It could be used just to build a local storage of events. Either way, the client parsing the request doesn't know if this is a display thing or a storage thing. Or maybe something to send to relays just to confuse their user tracking tools. I don't know... It feels too broad. |
Is this a solution in search for a problem? Maybe we should actually really come up with a |
Maybe
lol The use case I had imagined for this was custom feed lists, where each entry was a filter. But that could be done independent of |
The What I am thinking is that this would specify various steps in a query process and yield events in the process. Here's a stupid example that would use some constant values assumed to be defined and then perform a three step querying process to yield a custom feed of recent posts from people of whom I have bookmarked content but I don't follow. val me;
val myOutboxRelays;
val myInboxRelays;
val myFollowList;
for tag in querySync({kinds: [10003], authors: [me]}, myOutboxRelays).tags:
if (tag.0 == "e" or tag.0 == "a") and tag.2:
val bookmark = querySync({ids: [tag.1]}, [tag.2])
if bookmark.pubkey not in myFollowList:
val events = querySync({kinds: [1], authors: [bookmark.pubkey]}, [tag.2])
yield events This is not a fleshed out idea in any sense, by the way, and may also be a solution in search for a problem just like Can you give a concrete example of how you would do custom feeds, @staab? |
Read-only query languages can be quite effective. For instance, I have a use case for contextual Amber alerts based on Nostr data. It would be a simple new Event kind with the message and a boolean filter. The client runs the filter in the local DB and if it passes, it displays the message. Then you could do alerts on things like: Filter: User has pneumonia and is in New York |
I think nreq is a great idea, I have a similar concept in Damus for
representing filters but its very limited, you can link to basic filters
like this hastag one: damus:t:hashtag
The `nscript` could be a WASM script like @jb55 was doing -- although I
don't know how his thing works at all.
What I am thinking is that this would specify various steps in a query
process and yield events in the process. Here's a stupid example that
would use some constant values assumed to be defined and then perform a
three step querying process to yield a custom feed of _recent posts
from people of whom I have bookmarked content but I don't follow_.
```scala
val me;
val myOutboxRelays;
val myInboxRelays;
val myFollowList;
for tag in querySync({kinds: [10003], authors: [me]}, myOutboxRelays).tags:
if (tag.0 == "e" or tag.0 == "a") and tag.2:
val bookmark = querySync({ids: [tag.1]}, [tag.2])
if bookmark.pubkey not in myFollowList:
val events = querySync({kinds: [1], authors: [bookmark.pubkey]}, [tag.2])
yield events
```
This is very similar to what I'm doing in nostrscript, yes. scripts can
query relays and yield results. Here was the test script I had working:
```ts
import * as nostr from './nostr'
export function go(): i32 {
let subid = "sidebar_trending"
let relay = 'wss://cache3.primal.net/cache15'
var done: i32 = 0
var events: i32 = 0
nostr.pool_add_relay(relay)
nostr.pool_send_to(`["REQ","${subid}",{"cache":["explore_global_trending_24h"]}]`, relay)
while (!done) {
var ev = nostr.event_await(subid)
let type = nostr.event_get_type(ev)
switch (type) {
case nostr.EventType.OK:
nostr.log("ok")
break
case nostr.EventType.NOTE:
events++
let note = nostr.event_get_note(ev)
let kind = nostr.note_get_kind(note)
nostr.log(`type:${type} #${events} note, kind:${kind}`)
break
case nostr.EventType.EOSE:
nostr.log("eose, got " + events.toString() + " events")
done = true
break
default:
nostr.log("got event type " + type.toString())
}
}
return events
}
go()
```
nscript:
```
nscript1qpshxmgpqqqqqqgkq3sqglml0alsqcqqq9lkqqml0alszlmqqqqqywsrq4hx7um5wgykummnw3e97cmdvsqqyqm9demq2ctzdae8gqqqq4hx7um5wgfxummnw3e97ur0dak97um9dej97ar0qqqqxpqrqyqsxpgrqyqqzpsxq9lszsgqpvrs7qszvahsqpqxd4jk6mmj0ypqqzqpq5xqzrc2jvzs8cgrqy9h7svqpvssyqjqg8wq52qzqpqsya3zqeqsz6ezq4qsqjqdqqsq23gygpq7qz3gqgqzyqj9q3qyrqqtyypqkrqppvp5qgqryqryspzqyqp5zqn5g8sq563gqgqzyqsygqsqqgqzgy2xk2qzzpqszan2yyqqkgqrgyqk5ggrpsqskzeqqpqlcz3gqgqyzqtkygrzqptvdfqszapzqaq7ellllup5kpzqgxsqks0qpdqavqzprcgqzqqtyqr5zyr2ygp5rl8llllsxjcygpq6qz6puq95zg2pr5gqzqqtyvqzzqpqqpqsg63zqgsqxsgndfqhqu2pq34jyzr2ygpn7qpzp9q3qazppa4yzur3yg9ykpzqyqyjqqeqpf45rlllqd4yrqyq03c5zyrkyg9zqzfqpf9pksqqgyqyspzqyq9yqqzpqpyqgsqqpv9skgqrysqzqqpqpqmqyqpqqfqsg6ezqpqsqdszqssqqsgqxcpqsgqqgyprvqsvyqqzqpekqggzqqjpzp4zzqsrgqsqggq9fqzyqgqygyp8gs0qpf4zsqsqygqqgspqqgsqzsgpw34zqqpqqpq3g6egqggyzqtkygqyzqt5ls9qqqpqqqsqz63pqy9jqpsygqsqygqpgyqhg6jpsq9jqpjpq960czsqqqsqzgqxdgsszzeqq3qsz63pqsxqzzctyqz5zqn5g8sq563gqgqzyqqygqsqygqpgyqhg63qqqsqqsg5dv5qyyzp0eclczsqqq9skgqzpw3qzqgr0aqsys0qppqaczpgqgqyzqtkzqqp5s0ypfq6qzpkqgqpqqezqgsqysg5dv5qyyzpq9myrcqgg8wqs2qzqpqszassqgp5qgqpg5zyqqjqqfqyzq6p5qyyr8qg9qpqqsgpwcgqqgszq3l5zppqqfqsqyqqq4qsqz6pqf4suqcqqvqsxzeqqpqsz63pqqsqyprlgyzjqqjpqqgqqp2pqq9jyqsygpqsvgqzgyqpqqq6pvxqyz6pqysszrqppv9jqqqtpgqyrrqvysqpqpq6pv9mwqc0qpqcczqtqy7qqsvcpq9jwqsqqqqzqqqqqpesq6gqvsqx2qrzqpssqusqtuq8gqrjqpjsqmsqvsqxjqrwqpnsqswvpq9szhqqg8vqsz69qgqqqqp7qqqqqacqwvq8xqp6qqhsqtcqvvqxzqrrqp5qqegqxvqzuqrsqpeqq6gqd5qxzqrvqqhqqmsqv5q8gqp0qp3sqcgqvvqxsqr9qqcsqdgqgxkqjzcp9sqyrwqfpvtsyqqqqqgqqqqqtvqzyqzjqpzsq5gqygqzcqpzqpqaczgtq9kqqs0gpy947qsqqqq9sqqqqq3qqtqq0vqzyqrrqpssqccqdqqx2qpzqqaqqkcqygqx2qrcqpcqqmqqduq8yqr9qp0sqecqdsqx7qrzqpssqmqqtuq8gqrjqpjsqmsqvsqxjqrwqpnsqhcqxgqrgqrgqq3qqhgq05q96qzpes9qk8suqqqqqqcqqqqqqqqqqqzqqqqqpsqqqqxqqsqqqqqqqqq0qpqqg8kq5zcprsqyr7q2pvqsyqzp3s9skqfuqpqeszct9upqqqqq9qqqqqzpqpkqqmqqduqxxqrpqp6qq6gqduqxuqpqqp6qqmcqduqzqqrvqpssqusqvuqx2qzpes9skqfuqpqaszcty5pqqqqqrcqqqqr7qpkqq6gqvgqz7qrjqp6qqtcqwvq8gqr4qp3qqtsqwsq8xux2zrs
```
We're still working on the ABI though, since these scripts can do other
things as well such as filter feeds.
|
Thinking through this more has been on my to-do list for a while. But off the top of my head, a custom feed would be an OR of multiple dynamic filters, where:
Here's what Coracle currently does: |
It's looking like In the simplest case the What is your approach for taking input into the |
Personally i don't have any use case for |
I'll close this for now since we all agree |
I feel like |
https://github.com/nostr-protocol/nips/blob/nreq/19.md
For discussion.
@v0l @pablof7z @staab