package main import ( "context" "fmt" "fiatjaf.com/nostr" "fiatjaf.com/nostr/nip19" "github.com/urfave/cli/v3" ) var encode = &cli.Command{ Name: "encode", Usage: "encodes notes and other stuff to nip19 entities", Description: `example usage: nak encode npub nak encode nprofile 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 }, DisableSliceFlagSeparator: true, Commands: []*cli.Command{ { Name: "npub", Usage: "encode a hex public key into bech32 'npub' format", DisableSliceFlagSeparator: true, Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { pk, err := nostr.PubKeyFromHexCheap(target) if err != nil { ctx = lineProcessingError(ctx, "invalid public key '%s': %w", target, err) continue } stdout(nip19.EncodeNpub(pk)) } exitIfLineProcessingError(ctx) return nil }, }, { Name: "nsec", Usage: "encode a hex private key into bech32 'nsec' format", DisableSliceFlagSeparator: true, Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { sk, err := nostr.SecretKeyFromHex(target) if err != nil { ctx = lineProcessingError(ctx, "invalid private key '%s': %w", target, err) continue } stdout(nip19.EncodeNsec(sk)) } exitIfLineProcessingError(ctx) return nil }, }, { Name: "nprofile", Usage: "generate profile codes with attached relay information", Flags: []cli.Flag{ &cli.StringSliceFlag{ Name: "relay", Aliases: []string{"r"}, Usage: "attach relay hints to nprofile code", }, }, DisableSliceFlagSeparator: true, Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { pk, err := nostr.PubKeyFromHexCheap(target) if err != nil { ctx = lineProcessingError(ctx, "invalid public key '%s': %w", target, err) continue } relays := c.StringSlice("relay") if err := normalizeAndValidateRelayURLs(relays); err != nil { return err } stdout(nip19.EncodeNprofile(pk, relays)) } exitIfLineProcessingError(ctx) return nil }, }, { 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"}, Usage: "attach an author pubkey as a hint to the nevent code", }, }, DisableSliceFlagSeparator: true, Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { id, err := nostr.IDFromHex(target) if err != nil { ctx = lineProcessingError(ctx, "invalid event id: %s", target) continue } author := getPubKey(c, "author") relays := c.StringSlice("relay") if err := normalizeAndValidateRelayURLs(relays); err != nil { return err } stdout(nip19.EncodeNevent(id, relays, author)) } exitIfLineProcessingError(ctx) return nil }, }, { Name: "naddr", Usage: "generate codes for addressable events", Flags: []cli.Flag{ &cli.StringFlag{ Name: "identifier", Aliases: []string{"d"}, Usage: "the \"d\" tag identifier of this replaceable event -- can also be read from stdin", Required: true, }, &PubKeyFlag{ Name: "pubkey", Usage: "pubkey of the naddr author", Aliases: []string{"author", "a", "p"}, Required: true, }, &cli.IntFlag{ Name: "kind", Aliases: []string{"k"}, 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 { for d := range getStdinLinesOrBlank() { pubkey := getPubKey(c, "pubkey") kind := c.Int("kind") if kind < 30000 || kind >= 40000 { return fmt.Errorf("kind must be between 30000 and 39999, got %d", kind) } if d == "" { d = c.String("identifier") if d == "" { ctx = lineProcessingError(ctx, "\"d\" tag identifier can't be empty") continue } } relays := c.StringSlice("relay") if err := normalizeAndValidateRelayURLs(relays); err != nil { return err } stdout(nip19.EncodeNaddr(pubkey, nostr.Kind(kind), d, relays)) } exitIfLineProcessingError(ctx) return nil }, }, }, }