mirror of
https://github.com/fiatjaf/nak.git
synced 2024-10-30 00:59:07 -04:00
fix fetch
with nip05 filter and make req
filter options generalize to fetch
.
related: https://github.com/fiatjaf/nak/issues/19
This commit is contained in:
parent
2042b14578
commit
ea7b88cfd7
16
fetch.go
16
fetch.go
|
@ -17,13 +17,13 @@ var fetch = &cli.Command{
|
||||||
nak fetch nevent1qqsxrwm0hd3s3fddh4jc2574z3xzufq6qwuyz2rvv3n087zvym3dpaqprpmhxue69uhhqatzd35kxtnjv4kxz7tfdenju6t0xpnej4
|
nak fetch nevent1qqsxrwm0hd3s3fddh4jc2574z3xzufq6qwuyz2rvv3n087zvym3dpaqprpmhxue69uhhqatzd35kxtnjv4kxz7tfdenju6t0xpnej4
|
||||||
echo npub1h8spmtw9m2huyv6v2j2qd5zv956z2zdugl6mgx02f2upffwpm3nqv0j4ps | nak fetch --relay wss://relay.nostr.band`,
|
echo npub1h8spmtw9m2huyv6v2j2qd5zv956z2zdugl6mgx02f2upffwpm3nqv0j4ps | nak fetch --relay wss://relay.nostr.band`,
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
Flags: []cli.Flag{
|
Flags: append(reqFilterFlags,
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "relay",
|
Name: "relay",
|
||||||
Aliases: []string{"r"},
|
Aliases: []string{"r"},
|
||||||
Usage: "also use these relays to fetch from",
|
Usage: "also use these relays to fetch from",
|
||||||
},
|
},
|
||||||
},
|
),
|
||||||
ArgsUsage: "[nip05_or_nip19_code]",
|
ArgsUsage: "[nip05_or_nip19_code]",
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
sys := sdk.NewSystem()
|
sys := sdk.NewSystem()
|
||||||
|
@ -48,6 +48,7 @@ var fetch = &cli.Command{
|
||||||
}
|
}
|
||||||
authorHint = pp.PublicKey
|
authorHint = pp.PublicKey
|
||||||
relays = append(relays, pp.Relays...)
|
relays = append(relays, pp.Relays...)
|
||||||
|
filter.Authors = append(filter.Authors, pp.PublicKey)
|
||||||
} else {
|
} else {
|
||||||
prefix, value, err := nip19.Decode(code)
|
prefix, value, err := nip19.Decode(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -70,20 +71,17 @@ var fetch = &cli.Command{
|
||||||
case "naddr":
|
case "naddr":
|
||||||
v := value.(nostr.EntityPointer)
|
v := value.(nostr.EntityPointer)
|
||||||
filter.Tags = nostr.TagMap{"d": []string{v.Identifier}}
|
filter.Tags = nostr.TagMap{"d": []string{v.Identifier}}
|
||||||
filter.Kinds = append(filter.Kinds, v.Kind)
|
|
||||||
filter.Authors = append(filter.Authors, v.PublicKey)
|
filter.Authors = append(filter.Authors, v.PublicKey)
|
||||||
authorHint = v.PublicKey
|
authorHint = v.PublicKey
|
||||||
relays = append(relays, v.Relays...)
|
relays = append(relays, v.Relays...)
|
||||||
case "nprofile":
|
case "nprofile":
|
||||||
v := value.(nostr.ProfilePointer)
|
v := value.(nostr.ProfilePointer)
|
||||||
filter.Authors = append(filter.Authors, v.PublicKey)
|
filter.Authors = append(filter.Authors, v.PublicKey)
|
||||||
filter.Kinds = append(filter.Kinds, 0)
|
|
||||||
authorHint = v.PublicKey
|
authorHint = v.PublicKey
|
||||||
relays = append(relays, v.Relays...)
|
relays = append(relays, v.Relays...)
|
||||||
case "npub":
|
case "npub":
|
||||||
v := value.(string)
|
v := value.(string)
|
||||||
filter.Authors = append(filter.Authors, v)
|
filter.Authors = append(filter.Authors, v)
|
||||||
filter.Kinds = append(filter.Kinds, 0)
|
|
||||||
authorHint = v
|
authorHint = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,6 +91,14 @@ var fetch = &cli.Command{
|
||||||
for _, url := range relays {
|
for _, url := range relays {
|
||||||
relays = append(relays, url)
|
relays = append(relays, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(filter.Kinds) == 0 {
|
||||||
|
filter.Kinds = append(filter.Kinds, 0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := applyFlagsToFilter(c, &filter); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(relays) == 0 {
|
if len(relays) == 0 {
|
||||||
|
|
295
req.go
295
req.go
|
@ -12,7 +12,10 @@ import (
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
)
|
)
|
||||||
|
|
||||||
const CATEGORY_FILTER_ATTRIBUTES = "FILTER ATTRIBUTES"
|
const (
|
||||||
|
CATEGORY_FILTER_ATTRIBUTES = "FILTER ATTRIBUTES"
|
||||||
|
// CATEGORY_SIGNER = "SIGNER OPTIONS" -- defined at event.go as the same (yes, I know)
|
||||||
|
)
|
||||||
|
|
||||||
var req = &cli.Command{
|
var req = &cli.Command{
|
||||||
Name: "req",
|
Name: "req",
|
||||||
|
@ -28,7 +31,157 @@ it can also take a filter from stdin, optionally modify it with flags and send i
|
||||||
example:
|
example:
|
||||||
echo '{"kinds": [1], "#t": ["test"]}' | nak req -l 5 -k 4549 --tag t=spam wss://nostr-pub.wellorder.net`,
|
echo '{"kinds": [1], "#t": ["test"]}' | nak req -l 5 -k 4549 --tag t=spam wss://nostr-pub.wellorder.net`,
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
Flags: []cli.Flag{
|
Flags: append(reqFilterFlags,
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "stream",
|
||||||
|
Usage: "keep the subscription open, printing all events as they are returned",
|
||||||
|
DefaultText: "false, will close on EOSE",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "paginate",
|
||||||
|
Usage: "make multiple REQs to the relay decreasing the value of 'until' until 'limit' or 'since' conditions are met",
|
||||||
|
DefaultText: "false",
|
||||||
|
},
|
||||||
|
&cli.DurationFlag{
|
||||||
|
Name: "paginate-interval",
|
||||||
|
Usage: "time between queries when using --paginate",
|
||||||
|
},
|
||||||
|
&cli.UintFlag{
|
||||||
|
Name: "paginate-global-limit",
|
||||||
|
Usage: "global limit at which --paginate should stop",
|
||||||
|
DefaultText: "uses the value given by --limit/-l or infinite",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "bare",
|
||||||
|
Usage: "when printing the filter, print just the filter, not enveloped in a [\"REQ\", ...] array",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "auth",
|
||||||
|
Usage: "always perform NIP-42 \"AUTH\" when facing an \"auth-required: \" rejection and try again",
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "force-pre-auth",
|
||||||
|
Aliases: []string{"fpa"},
|
||||||
|
Usage: "after connecting, for a NIP-42 \"AUTH\" message to be received, act on it and only then send the \"REQ\"",
|
||||||
|
Category: CATEGORY_SIGNER,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "sec",
|
||||||
|
Usage: "secret key to sign the AUTH challenge, as hex or nsec",
|
||||||
|
DefaultText: "the key '1'",
|
||||||
|
Value: "0000000000000000000000000000000000000000000000000000000000000001",
|
||||||
|
Category: CATEGORY_SIGNER,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "prompt-sec",
|
||||||
|
Usage: "prompt the user to paste a hex or nsec with which to sign the AUTH challenge",
|
||||||
|
Category: CATEGORY_SIGNER,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "connect",
|
||||||
|
Usage: "sign AUTH using NIP-46, expects a bunker://... URL",
|
||||||
|
Category: CATEGORY_SIGNER,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "connect-as",
|
||||||
|
Usage: "private key to when communicating with the bunker given on --connect",
|
||||||
|
DefaultText: "a random key",
|
||||||
|
Category: CATEGORY_SIGNER,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
ArgsUsage: "[relay...]",
|
||||||
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
|
var pool *nostr.SimplePool
|
||||||
|
|
||||||
|
relayUrls := c.Args().Slice()
|
||||||
|
if len(relayUrls) > 0 {
|
||||||
|
var relays []*nostr.Relay
|
||||||
|
pool, relays = connectToAllRelays(ctx, relayUrls, c.Bool("force-pre-auth"), nostr.WithAuthHandler(func(evt *nostr.Event) error {
|
||||||
|
if !c.Bool("auth") && !c.Bool("force-pre-auth") {
|
||||||
|
return fmt.Errorf("auth not authorized")
|
||||||
|
}
|
||||||
|
sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var pk string
|
||||||
|
if bunker != nil {
|
||||||
|
pk, err = bunker.GetPublicKey(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get public key from bunker: %w", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
pk, _ = nostr.GetPublicKey(sec)
|
||||||
|
}
|
||||||
|
log("performing auth as %s... ", pk)
|
||||||
|
|
||||||
|
if bunker != nil {
|
||||||
|
return bunker.SignEvent(ctx, evt)
|
||||||
|
} else {
|
||||||
|
return evt.Sign(sec)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
if len(relays) == 0 {
|
||||||
|
log("failed to connect to any of the given relays.\n")
|
||||||
|
os.Exit(3)
|
||||||
|
}
|
||||||
|
relayUrls = make([]string, len(relays))
|
||||||
|
for i, relay := range relays {
|
||||||
|
relayUrls[i] = relay.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
for _, relay := range relays {
|
||||||
|
relay.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
for stdinFilter := range getStdinLinesOrBlank() {
|
||||||
|
filter := nostr.Filter{}
|
||||||
|
if stdinFilter != "" {
|
||||||
|
if err := easyjson.Unmarshal([]byte(stdinFilter), &filter); err != nil {
|
||||||
|
ctx = lineProcessingError(ctx, "invalid filter '%s' received from stdin: %s", stdinFilter, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := applyFlagsToFilter(c, &filter); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(relayUrls) > 0 {
|
||||||
|
fn := pool.SubManyEose
|
||||||
|
if c.Bool("paginate") {
|
||||||
|
fn = paginateWithPoolAndParams(pool, c.Duration("paginate-interval"), c.Uint("paginate-global-limit"))
|
||||||
|
} else if c.Bool("stream") {
|
||||||
|
fn = pool.SubMany
|
||||||
|
}
|
||||||
|
|
||||||
|
for ie := range fn(ctx, relayUrls, nostr.Filters{filter}) {
|
||||||
|
stdout(ie.Event)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no relays given, will just print the filter
|
||||||
|
var result string
|
||||||
|
if c.Bool("bare") {
|
||||||
|
result = filter.String()
|
||||||
|
} else {
|
||||||
|
j, _ := json.Marshal(nostr.ReqEnvelope{SubscriptionID: "nak", Filters: nostr.Filters{filter}})
|
||||||
|
result = string(j)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exitIfLineProcessingError(ctx)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqFilterFlags = []cli.Flag{
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "author",
|
Name: "author",
|
||||||
Aliases: []string{"a"},
|
Aliases: []string{"a"},
|
||||||
|
@ -91,116 +244,9 @@ example:
|
||||||
Usage: "a NIP-50 search query, use it only with relays that explicitly support it",
|
Usage: "a NIP-50 search query, use it only with relays that explicitly support it",
|
||||||
Category: CATEGORY_FILTER_ATTRIBUTES,
|
Category: CATEGORY_FILTER_ATTRIBUTES,
|
||||||
},
|
},
|
||||||
&cli.BoolFlag{
|
}
|
||||||
Name: "stream",
|
|
||||||
Usage: "keep the subscription open, printing all events as they are returned",
|
|
||||||
DefaultText: "false, will close on EOSE",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "paginate",
|
|
||||||
Usage: "make multiple REQs to the relay decreasing the value of 'until' until 'limit' or 'since' conditions are met",
|
|
||||||
DefaultText: "false",
|
|
||||||
},
|
|
||||||
&cli.DurationFlag{
|
|
||||||
Name: "paginate-interval",
|
|
||||||
Usage: "time between queries when using --paginate",
|
|
||||||
},
|
|
||||||
&cli.UintFlag{
|
|
||||||
Name: "paginate-global-limit",
|
|
||||||
Usage: "global limit at which --paginate should stop",
|
|
||||||
DefaultText: "uses the value given by --limit/-l or infinite",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "bare",
|
|
||||||
Usage: "when printing the filter, print just the filter, not enveloped in a [\"REQ\", ...] array",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "auth",
|
|
||||||
Usage: "always perform NIP-42 \"AUTH\" when facing an \"auth-required: \" rejection and try again",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "force-pre-auth",
|
|
||||||
Aliases: []string{"fpa"},
|
|
||||||
Usage: "after connecting, for a NIP-42 \"AUTH\" message to be received, act on it and only then send the \"REQ\"",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "sec",
|
|
||||||
Usage: "secret key to sign the AUTH challenge, as hex or nsec",
|
|
||||||
DefaultText: "the key '1'",
|
|
||||||
Value: "0000000000000000000000000000000000000000000000000000000000000001",
|
|
||||||
},
|
|
||||||
&cli.BoolFlag{
|
|
||||||
Name: "prompt-sec",
|
|
||||||
Usage: "prompt the user to paste a hex or nsec with which to sign the AUTH challenge",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "connect",
|
|
||||||
Usage: "sign AUTH using NIP-46, expects a bunker://... URL",
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "connect-as",
|
|
||||||
Usage: "private key to when communicating with the bunker given on --connect",
|
|
||||||
DefaultText: "a random key",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ArgsUsage: "[relay...]",
|
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
|
||||||
var pool *nostr.SimplePool
|
|
||||||
|
|
||||||
relayUrls := c.Args().Slice()
|
|
||||||
if len(relayUrls) > 0 {
|
|
||||||
var relays []*nostr.Relay
|
|
||||||
pool, relays = connectToAllRelays(ctx, relayUrls, c.Bool("force-pre-auth"), nostr.WithAuthHandler(func(evt *nostr.Event) error {
|
|
||||||
if !c.Bool("auth") && !c.Bool("force-pre-auth") {
|
|
||||||
return fmt.Errorf("auth not authorized")
|
|
||||||
}
|
|
||||||
sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(ctx, c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pk string
|
|
||||||
if bunker != nil {
|
|
||||||
pk, err = bunker.GetPublicKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("failed to get public key from bunker: %w", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
pk, _ = nostr.GetPublicKey(sec)
|
|
||||||
}
|
|
||||||
log("performing auth as %s... ", pk)
|
|
||||||
|
|
||||||
if bunker != nil {
|
|
||||||
return bunker.SignEvent(ctx, evt)
|
|
||||||
} else {
|
|
||||||
return evt.Sign(sec)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
if len(relays) == 0 {
|
|
||||||
log("failed to connect to any of the given relays.\n")
|
|
||||||
os.Exit(3)
|
|
||||||
}
|
|
||||||
relayUrls = make([]string, len(relays))
|
|
||||||
for i, relay := range relays {
|
|
||||||
relayUrls[i] = relay.URL
|
|
||||||
}
|
|
||||||
|
|
||||||
defer func() {
|
|
||||||
for _, relay := range relays {
|
|
||||||
relay.Close()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
for stdinFilter := range getStdinLinesOrBlank() {
|
|
||||||
filter := nostr.Filter{}
|
|
||||||
if stdinFilter != "" {
|
|
||||||
if err := easyjson.Unmarshal([]byte(stdinFilter), &filter); err != nil {
|
|
||||||
ctx = lineProcessingError(ctx, "invalid filter '%s' received from stdin: %s", stdinFilter, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
func applyFlagsToFilter(c *cli.Command, filter *nostr.Filter) error {
|
||||||
if authors := c.StringSlice("author"); len(authors) > 0 {
|
if authors := c.StringSlice("author"); len(authors) > 0 {
|
||||||
filter.Authors = append(filter.Authors, authors...)
|
filter.Authors = append(filter.Authors, authors...)
|
||||||
}
|
}
|
||||||
|
@ -259,32 +305,5 @@ example:
|
||||||
filter.LimitZero = true
|
filter.LimitZero = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(relayUrls) > 0 {
|
|
||||||
fn := pool.SubManyEose
|
|
||||||
if c.Bool("paginate") {
|
|
||||||
fn = paginateWithPoolAndParams(pool, c.Duration("paginate-interval"), c.Uint("paginate-global-limit"))
|
|
||||||
} else if c.Bool("stream") {
|
|
||||||
fn = pool.SubMany
|
|
||||||
}
|
|
||||||
|
|
||||||
for ie := range fn(ctx, relayUrls, nostr.Filters{filter}) {
|
|
||||||
stdout(ie.Event)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no relays given, will just print the filter
|
|
||||||
var result string
|
|
||||||
if c.Bool("bare") {
|
|
||||||
result = filter.String()
|
|
||||||
} else {
|
|
||||||
j, _ := json.Marshal(nostr.ReqEnvelope{SubscriptionID: "nak", Filters: nostr.Filters{filter}})
|
|
||||||
result = string(j)
|
|
||||||
}
|
|
||||||
|
|
||||||
stdout(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
exitIfLineProcessingError(ctx)
|
|
||||||
return nil
|
return nil
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user