diff --git a/encode.go b/encode.go index c5f9db9..59c5a58 100644 --- a/encode.go +++ b/encode.go @@ -18,14 +18,68 @@ var encode = &cli.Command{ nak encode nprofile --relay nak encode nevent nak encode nevent --author --relay --relay - nak encode nsec `, - Before: func(ctx context.Context, c *cli.Command) (context.Context, error) { - if c.Args().Len() < 1 { - return ctx, fmt.Errorf("expected more than 1 argument.") - } - return ctx, nil + nak encode nsec + echo '{"pubkey":"7b225d32d3edb978dba1adfd9440105646babbabbda181ea383f74ba53c3be19","relays":["wss://nada.zero"]}' | nak encode + echo '{ + "id":"7b225d32d3edb978dba1adfd9440105646babbabbda181ea383f74ba53c3be19" + "relays":["wss://nada.zero"], + "author":"ebb6ff85430705651b311ed51328767078fd790b14f02d22efba68d5513376bc" + } | nak encode`, + Flags: []cli.Flag{ + &cli.StringSliceFlag{ + Name: "relay", + Aliases: []string{"r"}, + Usage: "attach relay hints to naddr code", + }, }, DisableSliceFlagSeparator: true, + Action: func(ctx context.Context, c *cli.Command) error { + if c.Args().Len() != 0 { + return nil + } + + relays := c.StringSlice("relay") + if err := normalizeAndValidateRelayURLs(relays); err != nil { + return err + } + + hasStdin := false + for jsonStr := range getJsonsOrBlank() { + if jsonStr == "{}" { + hasStdin = false + continue + } else { + hasStdin = true + } + + var eventPtr nostr.EventPointer + if err := json.Unmarshal([]byte(jsonStr), &eventPtr); err == nil && eventPtr.ID != nostr.ZeroID { + stdout(nip19.EncodeNevent(eventPtr.ID, appendUnique(relays, eventPtr.Relays...), eventPtr.Author)) + continue + } + + var profilePtr nostr.ProfilePointer + if err := json.Unmarshal([]byte(jsonStr), &profilePtr); err == nil && profilePtr.PublicKey != nostr.ZeroPK { + stdout(nip19.EncodeNprofile(profilePtr.PublicKey, appendUnique(relays, profilePtr.Relays...))) + continue + } + + var entityPtr nostr.EntityPointer + if err := json.Unmarshal([]byte(jsonStr), &entityPtr); err == nil && entityPtr.PublicKey != nostr.ZeroPK { + stdout(nip19.EncodeNaddr(entityPtr.PublicKey, entityPtr.Kind, entityPtr.Identifier, appendUnique(relays, entityPtr.Relays...))) + continue + } + + ctx = lineProcessingError(ctx, "couldn't decode JSON '%s'", jsonStr) + } + + if !hasStdin { + return nil + } + + exitIfLineProcessingError(ctx) + return nil + }, Commands: []*cli.Command{ { Name: "npub", @@ -100,11 +154,6 @@ var encode = &cli.Command{ Name: "nevent", Usage: "generate event codes with optionally attached relay information", Flags: []cli.Flag{ - &cli.StringSliceFlag{ - Name: "relay", - Aliases: []string{"r"}, - Usage: "attach relay hints to nevent code", - }, &PubKeyFlag{ Name: "author", Aliases: []string{"a"}, @@ -155,11 +204,6 @@ var encode = &cli.Command{ Usage: "kind of referred replaceable event", Required: true, }, - &cli.StringSliceFlag{ - Name: "relay", - Aliases: []string{"r"}, - Usage: "attach relay hints to naddr code", - }, }, DisableSliceFlagSeparator: true, Action: func(ctx context.Context, c *cli.Command) error { diff --git a/helpers.go b/helpers.go index c9f542c..a154d81 100644 --- a/helpers.go +++ b/helpers.go @@ -49,6 +49,7 @@ func isPiped() bool { func getJsonsOrBlank() iter.Seq[string] { var curr strings.Builder + var finalJsonErr error return func(yield func(string) bool) { hasStdin := writeStdinLinesOrNothing(func(stdinLine string) bool { // we're look for an event, but it may be in multiple lines, so if json parsing fails @@ -58,8 +59,10 @@ func getJsonsOrBlank() iter.Seq[string] { var dummy any if err := json.Unmarshal([]byte(stdinEvent), &dummy); err != nil { + finalJsonErr = err return true } + finalJsonErr = nil if !yield(stdinEvent) { return false @@ -72,6 +75,10 @@ func getJsonsOrBlank() iter.Seq[string] { if !hasStdin { yield("{}") } + + if finalJsonErr != nil { + log(color.YellowString("stdin json parse error: %s", finalJsonErr)) + } } } @@ -388,6 +395,19 @@ func clampError(err error, prefixAlreadyPrinted int) string { return msg } +func appendUnique[A comparable](list []A, newEls ...A) []A { +ex: + for _, newEl := range newEls { + for _, el := range list { + if el == newEl { + continue ex + } + } + list = append(list, newEl) + } + return list +} + var colors = struct { reset func(...any) (int, error) italic func(...any) string