diff --git a/bunker.go b/bunker.go index daf1c5e..64d2d4e 100644 --- a/bunker.go +++ b/bunker.go @@ -14,7 +14,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" "github.com/nbd-wtf/go-nostr/nip46" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/exp/slices" ) @@ -45,12 +45,12 @@ var bunker = &cli.Command{ Usage: "pubkeys for which we will always respond", }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { // try to connect to the relays here qs := url.Values{} relayURLs := make([]string, 0, c.Args().Len()) if relayUrls := c.Args().Slice(); len(relayUrls) > 0 { - _, relays := connectToAllRelays(c.Context, relayUrls) + _, relays := connectToAllRelays(ctx, relayUrls) if len(relays) == 0 { log("failed to connect to any of the given relays.\n") os.Exit(3) @@ -65,7 +65,7 @@ var bunker = &cli.Command{ } // gather the secret key - sec, _, err := gatherSecretKeyOrBunkerFromArguments(c) + sec, _, err := gatherSecretKeyOrBunkerFromArguments(ctx, c) if err != nil { return err } @@ -143,9 +143,9 @@ var bunker = &cli.Command{ printBunkerInfo() // subscribe to relays - pool := nostr.NewSimplePool(c.Context) + pool := nostr.NewSimplePool(ctx) now := nostr.Now() - events := pool.SubMany(c.Context, relayURLs, nostr.Filters{ + events := pool.SubMany(ctx, relayURLs, nostr.Filters{ { Kinds: []int{nostr.KindNostrConnect}, Tags: nostr.TagMap{"p": []string{pubkey}}, @@ -160,7 +160,7 @@ var bunker = &cli.Command{ // just a gimmick var cancelPreviousBunkerInfoPrint context.CancelFunc - _, cancel := context.WithCancel(c.Context) + _, cancel := context.WithCancel(ctx) cancelPreviousBunkerInfoPrint = cancel // asking user for authorization @@ -199,7 +199,7 @@ var bunker = &cli.Command{ for _, relayURL := range relayURLs { go func(relayURL string) { if relay, _ := pool.EnsureRelay(relayURL); relay != nil { - err := relay.Publish(c.Context, eventResponse) + err := relay.Publish(ctx, eventResponse) printLock.Lock() if err == nil { log("* sent response through %s\n", relay.URL) @@ -215,7 +215,7 @@ var bunker = &cli.Command{ // just after handling one request we trigger this go func() { - ctx, cancel := context.WithCancel(c.Context) + ctx, cancel := context.WithCancel(ctx) defer cancel() cancelPreviousBunkerInfoPrint = cancel // the idea is that we will print the bunker URL again so it is easier to copy-paste by users diff --git a/count.go b/count.go index ba3f1ed..cbb3540 100644 --- a/count.go +++ b/count.go @@ -1,13 +1,14 @@ package main import ( + "context" "encoding/json" "errors" "fmt" "strings" "github.com/nbd-wtf/go-nostr" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var count = &cli.Command{ @@ -63,7 +64,7 @@ var count = &cli.Command{ }, }, ArgsUsage: "[relay...]", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { filter := nostr.Filter{} if authors := c.StringSlice("author"); len(authors) > 0 { @@ -72,7 +73,11 @@ var count = &cli.Command{ if ids := c.StringSlice("id"); len(ids) > 0 { filter.IDs = ids } - if kinds := c.IntSlice("kind"); len(kinds) > 0 { + if kinds64 := c.IntSlice("kind"); len(kinds64) > 0 { + kinds := make([]int, len(kinds64)) + for i, v := range kinds64 { + kinds[i] = int(v) + } filter.Kinds = kinds } @@ -110,7 +115,7 @@ var count = &cli.Command{ filter.Until = &ts } if limit := c.Int("limit"); limit != 0 { - filter.Limit = limit + filter.Limit = int(limit) } relays := c.Args().Slice() @@ -118,12 +123,12 @@ var count = &cli.Command{ failures := make([]error, 0, len(relays)) if len(relays) > 0 { for _, relayUrl := range relays { - relay, err := nostr.RelayConnect(c.Context, relayUrl) + relay, err := nostr.RelayConnect(ctx, relayUrl) if err != nil { failures = append(failures, err) continue } - count, err := relay.Count(c.Context, nostr.Filters{filter}) + count, err := relay.Count(ctx, nostr.Filters{filter}) if err != nil { failures = append(failures, err) continue diff --git a/decode.go b/decode.go index 8dd752d..9c9d8be 100644 --- a/decode.go +++ b/decode.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/hex" "encoding/json" "strings" @@ -8,7 +9,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" sdk "github.com/nbd-wtf/nostr-sdk" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var decode = &cli.Command{ @@ -32,7 +33,7 @@ var decode = &cli.Command{ }, }, ArgsUsage: "", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for input := range getStdinLinesOrArguments(c.Args()) { if strings.HasPrefix(input, "nostr:") { input = input[6:] @@ -49,12 +50,12 @@ var decode = &cli.Command{ decodeResult.HexResult.PrivateKey = hex.EncodeToString(b) decodeResult.HexResult.PublicKey = hex.EncodeToString(b) } else { - lineProcessingError(c, "hex string with invalid number of bytes: %d", len(b)) + lineProcessingError(ctx, "hex string with invalid number of bytes: %d", len(b)) continue } } else if evp := sdk.InputToEventPointer(input); evp != nil { decodeResult = DecodeResult{EventPointer: evp} - } else if pp := sdk.InputToProfile(c.Context, input); pp != nil { + } else if pp := sdk.InputToProfile(ctx, input); pp != nil { decodeResult = DecodeResult{ProfilePointer: pp} } else if prefix, value, err := nip19.Decode(input); err == nil && prefix == "naddr" { ep := value.(nostr.EntityPointer) @@ -63,7 +64,7 @@ var decode = &cli.Command{ decodeResult.PrivateKey.PrivateKey = value.(string) decodeResult.PrivateKey.PublicKey, _ = nostr.GetPublicKey(value.(string)) } else { - lineProcessingError(c, "couldn't decode input '%s': %s", input, err) + lineProcessingError(ctx, "couldn't decode input '%s': %s", input, err) continue } @@ -71,7 +72,7 @@ var decode = &cli.Command{ } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, } diff --git a/encode.go b/encode.go index 24689e3..4eaf3ac 100644 --- a/encode.go +++ b/encode.go @@ -1,11 +1,12 @@ package main import ( + "context" "fmt" "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var encode = &cli.Command{ @@ -18,20 +19,20 @@ var encode = &cli.Command{ nak encode nevent nak encode nevent --author --relay --relay nak encode nsec `, - Before: func(c *cli.Context) error { + Before: func(ctx context.Context, c *cli.Command) error { if c.Args().Len() < 1 { return fmt.Errorf("expected more than 1 argument.") } return nil }, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ { Name: "npub", Usage: "encode a hex public key into bech32 'npub' format", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { if ok := nostr.IsValidPublicKey(target); !ok { - lineProcessingError(c, "invalid public key: %s", target) + lineProcessingError(ctx, "invalid public key: %s", target) continue } @@ -42,17 +43,17 @@ var encode = &cli.Command{ } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }, { Name: "nsec", Usage: "encode a hex private key into bech32 'nsec' format", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { if ok := nostr.IsValid32ByteHex(target); !ok { - lineProcessingError(c, "invalid private key: %s", target) + lineProcessingError(ctx, "invalid private key: %s", target) continue } @@ -63,7 +64,7 @@ var encode = &cli.Command{ } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }, @@ -77,10 +78,10 @@ var encode = &cli.Command{ Usage: "attach relay hints to nprofile code", }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { if ok := nostr.IsValid32ByteHex(target); !ok { - lineProcessingError(c, "invalid public key: %s", target) + lineProcessingError(ctx, "invalid public key: %s", target) continue } @@ -96,7 +97,7 @@ var encode = &cli.Command{ } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }, @@ -115,10 +116,10 @@ var encode = &cli.Command{ Usage: "attach an author pubkey as a hint to the nevent code", }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { if ok := nostr.IsValid32ByteHex(target); !ok { - lineProcessingError(c, "invalid event id: %s", target) + lineProcessingError(ctx, "invalid event id: %s", target) continue } @@ -141,7 +142,7 @@ var encode = &cli.Command{ } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }, @@ -161,7 +162,7 @@ var encode = &cli.Command{ Aliases: []string{"author", "a", "p"}, Required: true, }, - &cli.Int64Flag{ + &cli.IntFlag{ Name: "kind", Aliases: []string{"k"}, Usage: "kind of referred replaceable event", @@ -173,7 +174,7 @@ var encode = &cli.Command{ Usage: "attach relay hints to naddr code", }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for d := range getStdinLinesOrBlank() { pubkey := c.String("pubkey") if ok := nostr.IsValidPublicKey(pubkey); !ok { @@ -188,7 +189,7 @@ var encode = &cli.Command{ if d == "" { d = c.String("identifier") if d == "" { - lineProcessingError(c, "\"d\" tag identifier can't be empty") + lineProcessingError(ctx, "\"d\" tag identifier can't be empty") continue } } @@ -198,24 +199,24 @@ var encode = &cli.Command{ return err } - if npub, err := nip19.EncodeEntity(pubkey, kind, d, relays); err == nil { + if npub, err := nip19.EncodeEntity(pubkey, int(kind), d, relays); err == nil { stdout(npub) } else { return err } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }, { Name: "note", Usage: "generate note1 event codes (not recommended)", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for target := range getStdinLinesOrArguments(c.Args()) { if ok := nostr.IsValid32ByteHex(target); !ok { - lineProcessingError(c, "invalid event id: %s", target) + lineProcessingError(ctx, "invalid event id: %s", target) continue } @@ -226,7 +227,7 @@ var encode = &cli.Command{ } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }, diff --git a/event.go b/event.go index fa7e639..6e6b225 100644 --- a/event.go +++ b/event.go @@ -13,7 +13,7 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" "github.com/nbd-wtf/go-nostr/nson" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" "golang.org/x/exp/slices" ) @@ -36,7 +36,7 @@ example: Flags: []cli.Flag{ &cli.StringFlag{ Name: "sec", - Usage: "secret key to sign the event, as hex or nsec", + Usage: "secret key to sign the event, as nsec, ncryptsec or hex", DefaultText: "the key '1'", Value: "0000000000000000000000000000000000000000000000000000000000000001", }, @@ -141,11 +141,11 @@ example: }, }, ArgsUsage: "[relay...]", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { // try to connect to the relays here var relays []*nostr.Relay if relayUrls := c.Args().Slice(); len(relayUrls) > 0 { - _, relays = connectToAllRelays(c.Context, relayUrls) + _, relays = connectToAllRelays(ctx, relayUrls) if len(relays) == 0 { log("failed to connect to any of the given relays.\n") os.Exit(3) @@ -158,7 +158,7 @@ example: } }() - sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(c) + sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(ctx, c) if err != nil { return err } @@ -176,14 +176,14 @@ example: if stdinEvent != "" { if err := easyjson.Unmarshal([]byte(stdinEvent), &evt); err != nil { - lineProcessingError(c, "invalid event received from stdin: %s", err) + lineProcessingError(ctx, "invalid event received from stdin: %s", err) continue } kindWasSupplied = strings.Contains(stdinEvent, `"kind"`) } if kind := c.Int("kind"); slices.Contains(c.FlagNames(), "kind") { - evt.Kind = kind + evt.Kind = int(kind) mustRehashAndResign = true } else if !kindWasSupplied { evt.Kind = 1 @@ -248,7 +248,7 @@ example: if evt.Sig == "" || mustRehashAndResign { if bunker != nil { - if err := bunker.SignEvent(c.Context, &evt); err != nil { + if err := bunker.SignEvent(ctx, &evt); err != nil { return fmt.Errorf("failed to sign with bunker: %w", err) } } else if numSigners := c.Uint("musig"); numSigners > 1 && sec != "" { @@ -256,7 +256,7 @@ example: secNonce := c.String("musig-nonce-secret") pubNonces := c.StringSlice("musig-nonce") partialSigs := c.StringSlice("musig-partial") - signed, err := performMusig(c.Context, + signed, err := performMusig(ctx, sec, &evt, int(numSigners), pubkeys, pubNonces, secNonce, partialSigs) if err != nil { return fmt.Errorf("musig error: %w", err) @@ -291,7 +291,7 @@ example: for _, relay := range relays { publish: log("publishing to %s... ", relay.URL) - ctx, cancel := context.WithTimeout(c.Context, 10*time.Second) + ctx, cancel := context.WithTimeout(ctx, 10*time.Second) defer cancel() err := relay.Publish(ctx, evt) @@ -307,7 +307,7 @@ example: // if the relay is requesting auth and we can auth, let's do it var pk string if bunker != nil { - pk, err = bunker.GetPublicKey(c.Context) + pk, err = bunker.GetPublicKey(ctx) if err != nil { return fmt.Errorf("failed to get public key from bunker: %w", err) } @@ -315,9 +315,9 @@ example: pk, _ = nostr.GetPublicKey(sec) } log("performing auth as %s... ", pk) - if err := relay.Auth(c.Context, func(evt *nostr.Event) error { + if err := relay.Auth(ctx, func(evt *nostr.Event) error { if bunker != nil { - return bunker.SignEvent(c.Context, evt) + return bunker.SignEvent(ctx, evt) } return evt.Sign(sec) }); err == nil { @@ -337,7 +337,7 @@ example: } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, } diff --git a/fetch.go b/fetch.go index 64a8056..0a59108 100644 --- a/fetch.go +++ b/fetch.go @@ -1,10 +1,12 @@ package main import ( + "context" + "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" sdk "github.com/nbd-wtf/nostr-sdk" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var fetch = &cli.Command{ @@ -21,8 +23,8 @@ var fetch = &cli.Command{ }, }, ArgsUsage: "[nip19code]", - Action: func(c *cli.Context) error { - pool := nostr.NewSimplePool(c.Context) + Action: func(ctx context.Context, c *cli.Command) error { + pool := nostr.NewSimplePool(ctx) defer func() { pool.Relays.Range(func(_ string, relay *nostr.Relay) bool { @@ -36,7 +38,7 @@ var fetch = &cli.Command{ prefix, value, err := nip19.Decode(code) if err != nil { - lineProcessingError(c, "failed to decode: %s", err) + lineProcessingError(ctx, "failed to decode: %s", err) continue } @@ -75,7 +77,7 @@ var fetch = &cli.Command{ } if authorHint != "" { - relayList := sdk.FetchRelaysForPubkey(c.Context, pool, authorHint, + relayList := sdk.FetchRelaysForPubkey(ctx, pool, authorHint, "wss://purplepag.es", "wss://relay.damus.io", "wss://relay.noswhere.com", "wss://nos.lol", "wss://public.relaying.io", "wss://relay.nostr.band") for _, relayListItem := range relayList { @@ -86,16 +88,16 @@ var fetch = &cli.Command{ } if len(relays) == 0 { - lineProcessingError(c, "no relay hints found") + lineProcessingError(ctx, "no relay hints found") continue } - for ie := range pool.SubManyEose(c.Context, relays, nostr.Filters{filter}) { + for ie := range pool.SubManyEose(ctx, relays, nostr.Filters{filter}) { stdout(ie.Event) } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, } diff --git a/go.mod b/go.mod index 7537692..d1c7446 100644 --- a/go.mod +++ b/go.mod @@ -7,11 +7,12 @@ toolchain go1.21.0 require ( github.com/btcsuite/btcd/btcec/v2 v2.3.3 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 github.com/fatih/color v1.16.0 github.com/mailru/easyjson v0.7.7 github.com/nbd-wtf/go-nostr v0.31.2 github.com/nbd-wtf/nostr-sdk v0.0.5 - github.com/urfave/cli/v2 v2.25.7 + github.com/urfave/cli/v3 v3.0.0-alpha9 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 ) @@ -20,9 +21,7 @@ require ( github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/chzyer/logex v1.1.10 // indirect github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/decred/dcrd/crypto/blake256 v1.0.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/fiatjaf/eventstore v0.2.16 // indirect github.com/gobwas/httphead v0.1.0 // indirect github.com/gobwas/pool v0.2.1 // indirect @@ -31,7 +30,6 @@ require ( github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/puzpuzpuz/xsync/v3 v3.1.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/tidwall/gjson v1.17.1 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect diff --git a/go.sum b/go.sum index 17ac72c..5b5786c 100644 --- a/go.sum +++ b/go.sum @@ -29,8 +29,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -96,8 +94,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/puzpuzpuz/xsync/v3 v3.1.0 h1:EewKT7/LNac5SLiEblJeUu8z5eERHrmRLnMQL2d7qX4= github.com/puzpuzpuz/xsync/v3 v3.1.0/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= @@ -110,8 +106,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= -github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v3 v3.0.0-alpha9 h1:P0RMy5fQm1AslQS+XCmy9UknDXctOmG/q/FZkUFnJSo= +github.com/urfave/cli/v3 v3.0.0-alpha9/go.mod h1:0kK/RUFHyh+yIKSfWxwheGndfnrvYSmYFVeKCh03ZUc= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/helpers.go b/helpers.go index 5e0cb9a..d6778db 100644 --- a/helpers.go +++ b/helpers.go @@ -16,7 +16,7 @@ import ( "github.com/nbd-wtf/go-nostr/nip19" "github.com/nbd-wtf/go-nostr/nip46" "github.com/nbd-wtf/go-nostr/nip49" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) const ( @@ -133,18 +133,18 @@ func connectToAllRelays( return pool, relays } -func lineProcessingError(c *cli.Context, msg string, args ...any) { - c.Context = context.WithValue(c.Context, LINE_PROCESSING_ERROR, true) +func lineProcessingError(ctx context.Context, msg string, args ...any) { + ctx = context.WithValue(ctx, LINE_PROCESSING_ERROR, true) log(msg+"\n", args...) } -func exitIfLineProcessingError(c *cli.Context) { - if val := c.Context.Value(LINE_PROCESSING_ERROR); val != nil && val.(bool) { +func exitIfLineProcessingError(ctx context.Context) { + if val := ctx.Value(LINE_PROCESSING_ERROR); val != nil && val.(bool) { os.Exit(123) } } -func gatherSecretKeyOrBunkerFromArguments(c *cli.Context) (string, *nip46.BunkerClient, error) { +func gatherSecretKeyOrBunkerFromArguments(ctx context.Context, c *cli.Command) (string, *nip46.BunkerClient, error) { var err error if bunkerURL := c.String("connect"); bunkerURL != "" { @@ -154,7 +154,7 @@ func gatherSecretKeyOrBunkerFromArguments(c *cli.Context) (string, *nip46.Bunker } else { clientKey = nostr.GeneratePrivateKey() } - bunker, err := nip46.ConnectBunker(c.Context, clientKey, bunkerURL, nil, func(s string) { + bunker, err := nip46.ConnectBunker(ctx, clientKey, bunkerURL, nil, func(s string) { fmt.Fprintf(color.Error, color.CyanString("[nip46]: open the following URL: %s"), s) }) return "", bunker, err diff --git a/key.go b/key.go index e14600c..0bb12cf 100644 --- a/key.go +++ b/key.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/hex" "encoding/json" "fmt" @@ -13,14 +14,14 @@ import ( "github.com/nbd-wtf/go-nostr" "github.com/nbd-wtf/go-nostr/nip19" "github.com/nbd-wtf/go-nostr/nip49" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var key = &cli.Command{ Name: "key", Usage: "operations on secret keys: generate, derive, encrypt, decrypt.", Description: ``, - Subcommands: []*cli.Command{ + Commands: []*cli.Command{ generate, public, encrypt, @@ -33,7 +34,7 @@ var generate = &cli.Command{ Name: "generate", Usage: "generates a secret key", Description: ``, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { sec := nostr.GeneratePrivateKey() stdout(sec) return nil @@ -45,11 +46,11 @@ var public = &cli.Command{ Usage: "computes a public key from a secret key", Description: ``, ArgsUsage: "[secret]", - Action: func(c *cli.Context) error { - for sec := range getSecretKeysFromStdinLinesOrSlice(c, c.Args().Slice()) { + Action: func(ctx context.Context, c *cli.Command) error { + for sec := range getSecretKeysFromStdinLinesOrSlice(ctx, c, c.Args().Slice()) { pubkey, err := nostr.GetPublicKey(sec) if err != nil { - lineProcessingError(c, "failed to derive public key: %s", err) + lineProcessingError(ctx, "failed to derive public key: %s", err) continue } stdout(pubkey) @@ -71,7 +72,7 @@ var encrypt = &cli.Command{ DefaultText: "16", }, }, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { keys := make([]string, 0, 1) var password string switch c.Args().Len() { @@ -84,10 +85,10 @@ var encrypt = &cli.Command{ if password == "" { return fmt.Errorf("no password given") } - for sec := range getSecretKeysFromStdinLinesOrSlice(c, keys) { + for sec := range getSecretKeysFromStdinLinesOrSlice(ctx, c, keys) { ncryptsec, err := nip49.Encrypt(sec, password, uint8(c.Int("logn")), 0x02) if err != nil { - lineProcessingError(c, "failed to encrypt: %s", err) + lineProcessingError(ctx, "failed to encrypt: %s", err) continue } stdout(ncryptsec) @@ -101,7 +102,7 @@ var decrypt = &cli.Command{ Usage: "takes an ncrypsec and a password and decrypts it into an nsec", Description: `uses the NIP-49 standard.`, ArgsUsage: " ", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { var ncryptsec string var password string switch c.Args().Len() { @@ -132,7 +133,7 @@ var decrypt = &cli.Command{ for ncryptsec := range getStdinLinesOrArgumentsFromSlice([]string{ncryptsec}) { sec, err := nip49.Decrypt(ncryptsec, password) if err != nil { - lineProcessingError(c, "failed to decrypt: %s", err) + lineProcessingError(ctx, "failed to decrypt: %s", err) continue } nsec, _ := nip19.EncodePrivateKey(sec) @@ -153,7 +154,7 @@ var combine = &cli.Command{ However, if the intent is to check if two existing Nostr pubkeys match a given combined pubkey, then it might be sufficient to calculate the combined key for all the possible combinations of pubkeys in the input.`, ArgsUsage: "[pubkey...]", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { type Combination struct { Variants []string `json:"input_variants"` Output struct { @@ -253,7 +254,7 @@ However, if the intent is to check if two existing Nostr pubkeys match a given c }, } -func getSecretKeysFromStdinLinesOrSlice(c *cli.Context, keys []string) chan string { +func getSecretKeysFromStdinLinesOrSlice(ctx context.Context, c *cli.Command, keys []string) chan string { ch := make(chan string) go func() { for sec := range getStdinLinesOrArgumentsFromSlice(keys) { @@ -263,13 +264,13 @@ func getSecretKeysFromStdinLinesOrSlice(c *cli.Context, keys []string) chan stri if strings.HasPrefix(sec, "nsec1") { _, data, err := nip19.Decode(sec) if err != nil { - lineProcessingError(c, "invalid nsec code: %s", err) + lineProcessingError(ctx, "invalid nsec code: %s", err) continue } sec = data.(string) } if !nostr.IsValid32ByteHex(sec) { - lineProcessingError(c, "invalid hex key") + lineProcessingError(ctx, "invalid hex key") continue } ch <- sec diff --git a/main.go b/main.go index 1d0c194..ac761bc 100644 --- a/main.go +++ b/main.go @@ -1,14 +1,13 @@ package main import ( + "context" "os" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) -var q int - -var app = &cli.App{ +var app = &cli.Command{ Name: "nak", Suggest: true, UseShortOptionHandling: true, @@ -29,9 +28,9 @@ var app = &cli.App{ &cli.BoolFlag{ Name: "quiet", Usage: "do not print logs and info messages to stderr, use -qq to also not print anything to stdout", - Count: &q, Aliases: []string{"q"}, - Action: func(ctx *cli.Context, b bool) error { + Action: func(ctx context.Context, c *cli.Command, b bool) error { + q := c.Count("quiet") if q >= 1 { log = func(msg string, args ...any) {} if q >= 2 { @@ -45,7 +44,7 @@ var app = &cli.App{ } func main() { - if err := app.Run(os.Args); err != nil { + if err := app.Run(context.Background(), os.Args); err != nil { stdout(err) os.Exit(1) } diff --git a/relay.go b/relay.go index 8174873..0ff9f3d 100644 --- a/relay.go +++ b/relay.go @@ -1,12 +1,13 @@ package main import ( + "context" "encoding/json" "fmt" "strings" "github.com/nbd-wtf/go-nostr/nip11" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var relay = &cli.Command{ @@ -15,7 +16,7 @@ var relay = &cli.Command{ Description: `example: nak relay nostr.wine`, ArgsUsage: "", - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for url := range getStdinLinesOrArguments(c.Args()) { if url == "" { return fmt.Errorf("specify the ") @@ -25,9 +26,9 @@ var relay = &cli.Command{ url = "wss://" + url } - info, err := nip11.Fetch(c.Context, url) + info, err := nip11.Fetch(ctx, url) if err != nil { - lineProcessingError(c, "failed to fetch '%s' information document: %w", url, err) + lineProcessingError(ctx, "failed to fetch '%s' information document: %w", url, err) continue } diff --git a/req.go b/req.go index 39d0def..3ab5295 100644 --- a/req.go +++ b/req.go @@ -1,6 +1,7 @@ package main import ( + "context" "encoding/json" "fmt" "os" @@ -9,7 +10,7 @@ import ( "github.com/mailru/easyjson" "github.com/nbd-wtf/go-nostr" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) const CATEGORY_FILTER_ATTRIBUTES = "FILTER ATTRIBUTES" @@ -124,23 +125,23 @@ example: }, }, ArgsUsage: "[relay...]", - Action: func(c *cli.Context) error { + 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(c.Context, relayUrls, nostr.WithAuthHandler(func(evt *nostr.Event) error { + pool, relays = connectToAllRelays(ctx, relayUrls, nostr.WithAuthHandler(func(evt *nostr.Event) error { if !c.Bool("auth") { return fmt.Errorf("auth not authorized") } - sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(c) + sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(ctx, c) if err != nil { return err } var pk string if bunker != nil { - pk, err = bunker.GetPublicKey(c.Context) + pk, err = bunker.GetPublicKey(ctx) if err != nil { return fmt.Errorf("failed to get public key from bunker: %w", err) } @@ -150,7 +151,7 @@ example: log("performing auth as %s...\n", pk) if bunker != nil { - return bunker.SignEvent(c.Context, evt) + return bunker.SignEvent(ctx, evt) } else { return evt.Sign(sec) } @@ -175,7 +176,7 @@ example: filter := nostr.Filter{} if stdinFilter != "" { if err := easyjson.Unmarshal([]byte(stdinFilter), &filter); err != nil { - lineProcessingError(c, "invalid filter '%s' received from stdin: %s", stdinFilter, err) + lineProcessingError(ctx, "invalid filter '%s' received from stdin: %s", stdinFilter, err) continue } } @@ -186,8 +187,8 @@ example: if ids := c.StringSlice("id"); len(ids) > 0 { filter.IDs = append(filter.IDs, ids...) } - if kinds := c.IntSlice("kind"); len(kinds) > 0 { - filter.Kinds = append(filter.Kinds, kinds...) + for _, kind64 := range c.IntSlice("kind") { + filter.Kinds = append(filter.Kinds, int(kind64)) } if search := c.String("search"); search != "" { filter.Search = search @@ -245,7 +246,7 @@ example: } } if limit := c.Int("limit"); limit != 0 { - filter.Limit = limit + filter.Limit = int(limit) } else if c.IsSet("limit") || c.Bool("stream") { filter.LimitZero = true } @@ -255,7 +256,7 @@ example: if c.Bool("stream") { fn = pool.SubMany } - for ie := range fn(c.Context, relayUrls, nostr.Filters{filter}) { + for ie := range fn(ctx, relayUrls, nostr.Filters{filter}) { stdout(ie.Event) } } else { @@ -272,7 +273,7 @@ example: } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, } diff --git a/verify.go b/verify.go index 39da863..1857fd0 100644 --- a/verify.go +++ b/verify.go @@ -1,10 +1,11 @@ package main import ( + "context" "encoding/json" "github.com/nbd-wtf/go-nostr" - "github.com/urfave/cli/v2" + "github.com/urfave/cli/v3" ) var verify = &cli.Command{ @@ -14,28 +15,28 @@ var verify = &cli.Command{ echo '{"id":"a889df6a387419ff204305f4c2d296ee328c3cd4f8b62f205648a541b4554dfb","pubkey":"c6047f9441ed7d6d3045406e95c07cd85c778e4b8cef3ca7abac09b95c709ee5","created_at":1698623783,"kind":1,"tags":[],"content":"hello from the nostr army knife","sig":"84876e1ee3e726da84e5d195eb79358b2b3eaa4d9bd38456fde3e8a2af3f1cd4cda23f23fda454869975b3688797d4c66e12f4c51c1b43c6d2997c5e61865661"}' | nak verify it outputs nothing if the verification is successful.`, - Action: func(c *cli.Context) error { + Action: func(ctx context.Context, c *cli.Command) error { for stdinEvent := range getStdinLinesOrArguments(c.Args()) { evt := nostr.Event{} if stdinEvent != "" { if err := json.Unmarshal([]byte(stdinEvent), &evt); err != nil { - lineProcessingError(c, "invalid event: %s", err) + lineProcessingError(ctx, "invalid event: %s", err) continue } } if evt.GetID() != evt.ID { - lineProcessingError(c, "invalid .id, expected %s, got %s", evt.GetID(), evt.ID) + lineProcessingError(ctx, "invalid .id, expected %s, got %s", evt.GetID(), evt.ID) continue } if ok, err := evt.CheckSignature(); !ok { - lineProcessingError(c, "invalid signature: %s", err) + lineProcessingError(ctx, "invalid signature: %s", err) continue } } - exitIfLineProcessingError(c) + exitIfLineProcessingError(ctx) return nil }, }