mirror of
https://github.com/fiatjaf/nak.git
synced 2026-10-05 15:18:23 +00:00
encode: support reading pointer data as json from stdin also in specific subcommands.
This commit is contained in:
@@ -4,12 +4,64 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
stdjson "encoding/json"
|
stdjson "encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"iter"
|
||||||
|
|
||||||
"fiatjaf.com/nostr"
|
"fiatjaf.com/nostr"
|
||||||
"fiatjaf.com/nostr/nip19"
|
"fiatjaf.com/nostr/nip19"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func parseProfilePointerInput(target string) (nostr.ProfilePointer, bool) {
|
||||||
|
var profilePtr nostr.ProfilePointer
|
||||||
|
if err := stdjson.Unmarshal([]byte(target), &profilePtr); err != nil || profilePtr.PublicKey == nostr.ZeroPK {
|
||||||
|
return nostr.ProfilePointer{}, false
|
||||||
|
}
|
||||||
|
return profilePtr, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseEventPointerInput(target string) (nostr.EventPointer, bool) {
|
||||||
|
var eventPtr nostr.EventPointer
|
||||||
|
if err := stdjson.Unmarshal([]byte(target), &eventPtr); err != nil || eventPtr.ID == nostr.ZeroID {
|
||||||
|
return nostr.EventPointer{}, false
|
||||||
|
}
|
||||||
|
return eventPtr, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseEntityPointerInput(target string) (nostr.EntityPointer, bool) {
|
||||||
|
var entityPtr nostr.EntityPointer
|
||||||
|
if err := stdjson.Unmarshal([]byte(target), &entityPtr); err != nil || entityPtr.PublicKey == nostr.ZeroPK || entityPtr.Kind == 0 {
|
||||||
|
return nostr.EntityPointer{}, false
|
||||||
|
}
|
||||||
|
return entityPtr, true
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEncodeSubcommandInput(args cli.Args, allowBlank bool) iter.Seq[string] {
|
||||||
|
if args.Len() > 0 {
|
||||||
|
return func(yield func(string) bool) {
|
||||||
|
for _, arg := range args.Slice() {
|
||||||
|
if !yield(arg) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return func(yield func(string) bool) {
|
||||||
|
for jsonStr := range getJsonsOrBlank() {
|
||||||
|
if jsonStr == "{}" {
|
||||||
|
if allowBlank {
|
||||||
|
yield("")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !yield(jsonStr) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var encode = &cli.Command{
|
var encode = &cli.Command{
|
||||||
Name: "encode",
|
Name: "encode",
|
||||||
Usage: "encodes notes and other stuff to nip19 entities",
|
Usage: "encodes notes and other stuff to nip19 entities",
|
||||||
@@ -51,20 +103,17 @@ var encode = &cli.Command{
|
|||||||
hasStdin = true
|
hasStdin = true
|
||||||
}
|
}
|
||||||
|
|
||||||
var eventPtr nostr.EventPointer
|
if eventPtr, ok := parseEventPointerInput(jsonStr); ok {
|
||||||
if err := stdjson.Unmarshal([]byte(jsonStr), &eventPtr); err == nil && eventPtr.ID != nostr.ZeroID {
|
|
||||||
stdout(nip19.EncodeNevent(eventPtr.ID, nostr.AppendUnique(relays, eventPtr.Relays...), eventPtr.Author))
|
stdout(nip19.EncodeNevent(eventPtr.ID, nostr.AppendUnique(relays, eventPtr.Relays...), eventPtr.Author))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var entityPtr nostr.EntityPointer
|
if entityPtr, ok := parseEntityPointerInput(jsonStr); ok {
|
||||||
if err := stdjson.Unmarshal([]byte(jsonStr), &entityPtr); err == nil && entityPtr.PublicKey != nostr.ZeroPK && entityPtr.Kind != 0 {
|
|
||||||
stdout(nip19.EncodeNaddr(entityPtr.PublicKey, entityPtr.Kind, entityPtr.Identifier, nostr.AppendUnique(relays, entityPtr.Relays...)))
|
stdout(nip19.EncodeNaddr(entityPtr.PublicKey, entityPtr.Kind, entityPtr.Identifier, nostr.AppendUnique(relays, entityPtr.Relays...)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
var profilePtr nostr.ProfilePointer
|
if profilePtr, ok := parseProfilePointerInput(jsonStr); ok {
|
||||||
if err := stdjson.Unmarshal([]byte(jsonStr), &profilePtr); err == nil && profilePtr.PublicKey != nostr.ZeroPK {
|
|
||||||
stdout(nip19.EncodeNprofile(profilePtr.PublicKey, nostr.AppendUnique(relays, profilePtr.Relays...)))
|
stdout(nip19.EncodeNprofile(profilePtr.PublicKey, nostr.AppendUnique(relays, profilePtr.Relays...)))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -135,14 +184,21 @@ var encode = &cli.Command{
|
|||||||
},
|
},
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
for target := range getStdinLinesOrArguments(c.Args()) {
|
for target := range getEncodeSubcommandInput(c.Args(), false) {
|
||||||
pk, err := nostr.PubKeyFromHexCheap(target)
|
|
||||||
if err != nil {
|
|
||||||
ctx = lineProcessingError(ctx, "invalid public key '%s': %s", target, err)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
relays := c.StringSlice("relay")
|
relays := c.StringSlice("relay")
|
||||||
|
pk := nostr.ZeroPK
|
||||||
|
|
||||||
|
if profilePtr, ok := parseProfilePointerInput(target); ok {
|
||||||
|
pk = profilePtr.PublicKey
|
||||||
|
relays = nostr.AppendUnique(relays, profilePtr.Relays...)
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
pk, err = nostr.PubKeyFromHexCheap(target)
|
||||||
|
if err != nil {
|
||||||
|
ctx = lineProcessingError(ctx, "invalid public key '%s': %s", target, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if getBoolInt(c, "outbox") > 0 {
|
if getBoolInt(c, "outbox") > 0 {
|
||||||
for _, r := range sys.FetchOutboxRelays(ctx, pk, int(getBoolInt(c, "outbox"))) {
|
for _, r := range sys.FetchOutboxRelays(ctx, pk, int(getBoolInt(c, "outbox"))) {
|
||||||
@@ -183,16 +239,26 @@ var encode = &cli.Command{
|
|||||||
},
|
},
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
for target := range getStdinLinesOrArguments(c.Args()) {
|
for target := range getEncodeSubcommandInput(c.Args(), false) {
|
||||||
id, err := parseEventID(target)
|
id := nostr.ZeroID
|
||||||
if err != nil {
|
|
||||||
ctx = lineProcessingError(ctx, "invalid event id: %s", target)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
author := getPubKey(c, "author")
|
author := getPubKey(c, "author")
|
||||||
relays := c.StringSlice("relay")
|
relays := c.StringSlice("relay")
|
||||||
|
|
||||||
|
if eventPtr, ok := parseEventPointerInput(target); ok {
|
||||||
|
id = eventPtr.ID
|
||||||
|
relays = nostr.AppendUnique(relays, eventPtr.Relays...)
|
||||||
|
if author == nostr.ZeroPK {
|
||||||
|
author = eventPtr.Author
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var err error
|
||||||
|
id, err = parseEventID(target)
|
||||||
|
if err != nil {
|
||||||
|
ctx = lineProcessingError(ctx, "invalid event id: %s", target)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if getBoolInt(c, "outbox") > 0 && author != nostr.ZeroPK {
|
if getBoolInt(c, "outbox") > 0 && author != nostr.ZeroPK {
|
||||||
for _, r := range sys.FetchOutboxRelays(ctx, author, int(getBoolInt(c, "outbox"))) {
|
for _, r := range sys.FetchOutboxRelays(ctx, author, int(getBoolInt(c, "outbox"))) {
|
||||||
relays = nostr.AppendUnique(relays, r)
|
relays = nostr.AppendUnique(relays, r)
|
||||||
@@ -220,16 +286,14 @@ var encode = &cli.Command{
|
|||||||
Usage: "the \"d\" tag identifier of this replaceable event -- can also be read from stdin",
|
Usage: "the \"d\" tag identifier of this replaceable event -- can also be read from stdin",
|
||||||
},
|
},
|
||||||
&PubKeyFlag{
|
&PubKeyFlag{
|
||||||
Name: "pubkey",
|
Name: "pubkey",
|
||||||
Usage: "pubkey of the naddr author",
|
Usage: "pubkey of the naddr author",
|
||||||
Aliases: []string{"author", "a", "p"},
|
Aliases: []string{"author", "a", "p"},
|
||||||
Required: true,
|
|
||||||
},
|
},
|
||||||
&cli.IntFlag{
|
&cli.IntFlag{
|
||||||
Name: "kind",
|
Name: "kind",
|
||||||
Aliases: []string{"k"},
|
Aliases: []string{"k"},
|
||||||
Usage: "kind of referred replaceable event",
|
Usage: "kind of referred replaceable event",
|
||||||
Required: true,
|
|
||||||
},
|
},
|
||||||
&cli.StringSliceFlag{
|
&cli.StringSliceFlag{
|
||||||
Name: "relay",
|
Name: "relay",
|
||||||
@@ -244,21 +308,44 @@ var encode = &cli.Command{
|
|||||||
},
|
},
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
for d := range getStdinLinesOrBlank() {
|
for target := range getEncodeSubcommandInput(c.Args(), true) {
|
||||||
pubkey := getPubKey(c, "pubkey")
|
pubkey := getPubKey(c, "pubkey")
|
||||||
|
|
||||||
kind := nostr.Kind(c.Int("kind"))
|
kind := nostr.Kind(c.Int("kind"))
|
||||||
if d == "" {
|
d := c.String("identifier")
|
||||||
d = c.String("identifier")
|
relays := c.StringSlice("relay")
|
||||||
|
|
||||||
|
if entityPtr, ok := parseEntityPointerInput(target); ok {
|
||||||
|
relays = nostr.AppendUnique(relays, entityPtr.Relays...)
|
||||||
|
if pubkey == nostr.ZeroPK {
|
||||||
|
pubkey = entityPtr.PublicKey
|
||||||
|
}
|
||||||
|
if kind == 0 {
|
||||||
|
kind = entityPtr.Kind
|
||||||
|
}
|
||||||
|
if !c.IsSet("identifier") {
|
||||||
|
d = entityPtr.Identifier
|
||||||
|
}
|
||||||
|
} else if target != "" {
|
||||||
|
d = target
|
||||||
|
}
|
||||||
|
|
||||||
|
if pubkey == nostr.ZeroPK {
|
||||||
|
ctx = lineProcessingError(ctx, "pubkey must be set")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if kind == 0 {
|
||||||
|
ctx = lineProcessingError(ctx, "kind must be set")
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if kind.IsAddressable() {
|
if kind.IsAddressable() {
|
||||||
if !c.IsSet("identifier") {
|
if d == "" {
|
||||||
ctx = lineProcessingError(ctx, "\"d\" tag identifier must be set for addressable events")
|
ctx = lineProcessingError(ctx, "\"d\" tag identifier must be set for addressable events")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
} else if kind.IsReplaceable() {
|
} else if kind.IsReplaceable() {
|
||||||
if c.IsSet("identifier") {
|
if d != "" {
|
||||||
ctx = lineProcessingError(ctx, "\"d\" tag identifier must not be set for replaceable events")
|
ctx = lineProcessingError(ctx, "\"d\" tag identifier must not be set for replaceable events")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -267,7 +354,6 @@ var encode = &cli.Command{
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
relays := c.StringSlice("relay")
|
|
||||||
if getBoolInt(c, "outbox") > 0 {
|
if getBoolInt(c, "outbox") > 0 {
|
||||||
for _, r := range sys.FetchOutboxRelays(ctx, pubkey, int(getBoolInt(c, "outbox"))) {
|
for _, r := range sys.FetchOutboxRelays(ctx, pubkey, int(getBoolInt(c, "outbox"))) {
|
||||||
relays = nostr.AppendUnique(relays, r)
|
relays = nostr.AppendUnique(relays, r)
|
||||||
|
|||||||
Reference in New Issue
Block a user