mirror of
https://github.com/fiatjaf/nak.git
synced 2024-11-22 08:19:06 -05:00
--connect to use nip46 as a client to sign event and auth messages.
This commit is contained in:
parent
01e1f52a70
commit
b7a7e0504f
|
@ -56,7 +56,7 @@ var bunker = &cli.Command{
|
||||||
}
|
}
|
||||||
|
|
||||||
// gather the secret key
|
// gather the secret key
|
||||||
sec, err := gatherSecretKeyFromArguments(c)
|
sec, _, err := gatherSecretKeyOrBunkerFromArguments(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
32
event.go
32
event.go
|
@ -44,6 +44,10 @@ example:
|
||||||
Name: "prompt-sec",
|
Name: "prompt-sec",
|
||||||
Usage: "prompt the user to paste a hex or nsec with which to sign the event",
|
Usage: "prompt the user to paste a hex or nsec with which to sign the event",
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "connect",
|
||||||
|
Usage: "sign event using NIP-46, expects a bunker://... URL",
|
||||||
|
},
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "envelope",
|
Name: "envelope",
|
||||||
Usage: "print the event enveloped in a [\"EVENT\", ...] message ready to be sent to a relay",
|
Usage: "print the event enveloped in a [\"EVENT\", ...] message ready to be sent to a relay",
|
||||||
|
@ -124,8 +128,7 @@ example:
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// gather the secret key
|
sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(c)
|
||||||
sec, err := gatherSecretKeyFromArguments(c)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -215,7 +218,11 @@ example:
|
||||||
}
|
}
|
||||||
|
|
||||||
if evt.Sig == "" || mustRehashAndResign {
|
if evt.Sig == "" || mustRehashAndResign {
|
||||||
if err := evt.Sign(sec); err != nil {
|
if bunker != nil {
|
||||||
|
if err := bunker.SignEvent(c.Context, &evt); err != nil {
|
||||||
|
return fmt.Errorf("failed to sign with bunker: %w", err)
|
||||||
|
}
|
||||||
|
} else if err := evt.Sign(sec); err != nil {
|
||||||
return fmt.Errorf("error signing with provided key: %w", err)
|
return fmt.Errorf("error signing with provided key: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -252,11 +259,24 @@ example:
|
||||||
}
|
}
|
||||||
|
|
||||||
// error publishing
|
// error publishing
|
||||||
if strings.HasPrefix(err.Error(), "msg: auth-required:") && sec != "" && doAuth {
|
if strings.HasPrefix(err.Error(), "msg: auth-required:") && (sec != "" || bunker != nil) && doAuth {
|
||||||
// if the relay is requesting auth and we can auth, let's do it
|
// if the relay is requesting auth and we can auth, let's do it
|
||||||
pk, _ := nostr.GetPublicKey(sec)
|
var pk string
|
||||||
|
if bunker != nil {
|
||||||
|
pk, err = bunker.GetPublicKey(c.Context)
|
||||||
|
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)
|
log("performing auth as %s... ", pk)
|
||||||
if err := relay.Auth(c.Context, func(evt *nostr.Event) error { return evt.Sign(sec) }); err == nil {
|
if err := relay.Auth(c.Context, func(evt *nostr.Event) error {
|
||||||
|
if bunker != nil {
|
||||||
|
return bunker.SignEvent(c.Context, evt)
|
||||||
|
}
|
||||||
|
return evt.Sign(sec)
|
||||||
|
}); err == nil {
|
||||||
// try to publish again, but this time don't try to auth again
|
// try to publish again, but this time don't try to auth again
|
||||||
doAuth = false
|
doAuth = false
|
||||||
goto publish
|
goto publish
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -9,7 +9,7 @@ require (
|
||||||
github.com/fatih/color v1.16.0
|
github.com/fatih/color v1.16.0
|
||||||
github.com/mailru/easyjson v0.7.7
|
github.com/mailru/easyjson v0.7.7
|
||||||
github.com/manifoldco/promptui v0.9.0
|
github.com/manifoldco/promptui v0.9.0
|
||||||
github.com/nbd-wtf/go-nostr v0.28.2
|
github.com/nbd-wtf/go-nostr v0.28.4
|
||||||
github.com/nbd-wtf/nostr-sdk v0.0.5
|
github.com/nbd-wtf/nostr-sdk v0.0.5
|
||||||
github.com/urfave/cli/v2 v2.25.7
|
github.com/urfave/cli/v2 v2.25.7
|
||||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -81,8 +81,8 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
||||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/nbd-wtf/go-nostr v0.28.2 h1:KhpGcs6KMLBqYExzKoqt7vP5Re2f8Kpy9SavYZa2PTI=
|
github.com/nbd-wtf/go-nostr v0.28.4 h1:chGBpdCQvM9aInf/vVDishY8GHapgqFc/RLl2WDnHQM=
|
||||||
github.com/nbd-wtf/go-nostr v0.28.2/go.mod h1:l9NRRaHPN+QwkqrjNKhnfYjQ0+nKP1xZrVxePPGUs+A=
|
github.com/nbd-wtf/go-nostr v0.28.4/go.mod h1:l9NRRaHPN+QwkqrjNKhnfYjQ0+nKP1xZrVxePPGUs+A=
|
||||||
github.com/nbd-wtf/nostr-sdk v0.0.5 h1:rec+FcDizDVO0W25PX0lgYMXvP7zNNOgI3Fu9UCm4BY=
|
github.com/nbd-wtf/nostr-sdk v0.0.5 h1:rec+FcDizDVO0W25PX0lgYMXvP7zNNOgI3Fu9UCm4BY=
|
||||||
github.com/nbd-wtf/nostr-sdk v0.0.5/go.mod h1:iJJsikesCGLNFZ9dLqhLPDzdt924EagUmdQxT3w2Lmk=
|
github.com/nbd-wtf/nostr-sdk v0.0.5/go.mod h1:iJJsikesCGLNFZ9dLqhLPDzdt924EagUmdQxT3w2Lmk=
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
|
|
21
helpers.go
21
helpers.go
|
@ -13,6 +13,7 @@ import (
|
||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"github.com/nbd-wtf/go-nostr/nip19"
|
"github.com/nbd-wtf/go-nostr/nip19"
|
||||||
|
"github.com/nbd-wtf/go-nostr/nip46"
|
||||||
"github.com/nbd-wtf/go-nostr/nip49"
|
"github.com/nbd-wtf/go-nostr/nip49"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
@ -129,35 +130,41 @@ func exitIfLineProcessingError(c *cli.Context) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func gatherSecretKeyFromArguments(c *cli.Context) (string, error) {
|
func gatherSecretKeyOrBunkerFromArguments(c *cli.Context) (string, *nip46.BunkerClient, error) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
if bunkerURL := c.String("connect"); bunkerURL != "" {
|
||||||
|
clientKey := nostr.GeneratePrivateKey()
|
||||||
|
bunker, err := nip46.ConnectBunker(c.Context, clientKey, bunkerURL, nil)
|
||||||
|
return "", bunker, err
|
||||||
|
}
|
||||||
sec := c.String("sec")
|
sec := c.String("sec")
|
||||||
if c.Bool("prompt-sec") {
|
if c.Bool("prompt-sec") {
|
||||||
if isPiped() {
|
if isPiped() {
|
||||||
return "", fmt.Errorf("can't prompt for a secret key when processing data from a pipe, try again without --prompt-sec")
|
return "", nil, fmt.Errorf("can't prompt for a secret key when processing data from a pipe, try again without --prompt-sec")
|
||||||
}
|
}
|
||||||
sec, err = askPassword("type your secret key as ncryptsec, nsec or hex: ", nil)
|
sec, err = askPassword("type your secret key as ncryptsec, nsec or hex: ", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to get secret key: %w", err)
|
return "", nil, fmt.Errorf("failed to get secret key: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(sec, "ncryptsec1") {
|
if strings.HasPrefix(sec, "ncryptsec1") {
|
||||||
sec, err = promptDecrypt(sec)
|
sec, err = promptDecrypt(sec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("failed to decrypt: %w", err)
|
return "", nil, fmt.Errorf("failed to decrypt: %w", err)
|
||||||
}
|
}
|
||||||
} else if bsec, err := hex.DecodeString(strings.Repeat("0", 64-len(sec)) + sec); err == nil {
|
} else if bsec, err := hex.DecodeString(strings.Repeat("0", 64-len(sec)) + sec); err == nil {
|
||||||
sec = hex.EncodeToString(bsec)
|
sec = hex.EncodeToString(bsec)
|
||||||
} else if prefix, hexvalue, err := nip19.Decode(sec); err != nil {
|
} else if prefix, hexvalue, err := nip19.Decode(sec); err != nil {
|
||||||
return "", fmt.Errorf("invalid nsec: %w", err)
|
return "", nil, fmt.Errorf("invalid nsec: %w", err)
|
||||||
} else if prefix == "nsec" {
|
} else if prefix == "nsec" {
|
||||||
sec = hexvalue.(string)
|
sec = hexvalue.(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ok := nostr.IsValid32ByteHex(sec); !ok {
|
if ok := nostr.IsValid32ByteHex(sec); !ok {
|
||||||
return "", fmt.Errorf("invalid secret key")
|
return "", nil, fmt.Errorf("invalid secret key")
|
||||||
}
|
}
|
||||||
return sec, nil
|
return sec, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func promptDecrypt(ncryptsec1 string) (string, error) {
|
func promptDecrypt(ncryptsec1 string) (string, error) {
|
||||||
|
|
24
req.go
24
req.go
|
@ -113,6 +113,10 @@ example:
|
||||||
Name: "prompt-sec",
|
Name: "prompt-sec",
|
||||||
Usage: "prompt the user to paste a hex or nsec with which to sign the AUTH challenge",
|
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",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
ArgsUsage: "[relay...]",
|
ArgsUsage: "[relay...]",
|
||||||
Action: func(c *cli.Context) error {
|
Action: func(c *cli.Context) error {
|
||||||
|
@ -124,13 +128,27 @@ example:
|
||||||
if !c.Bool("auth") {
|
if !c.Bool("auth") {
|
||||||
return fmt.Errorf("auth not authorized")
|
return fmt.Errorf("auth not authorized")
|
||||||
}
|
}
|
||||||
sec, err := gatherSecretKeyFromArguments(c)
|
sec, bunker, err := gatherSecretKeyOrBunkerFromArguments(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
pk, _ := nostr.GetPublicKey(sec)
|
|
||||||
|
var pk string
|
||||||
|
if bunker != nil {
|
||||||
|
pk, err = bunker.GetPublicKey(c.Context)
|
||||||
|
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...\n", pk)
|
log("performing auth as %s...\n", pk)
|
||||||
return evt.Sign(sec)
|
|
||||||
|
if bunker != nil {
|
||||||
|
return bunker.SignEvent(c.Context, evt)
|
||||||
|
} else {
|
||||||
|
return evt.Sign(sec)
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
if len(relays) == 0 {
|
if len(relays) == 0 {
|
||||||
log("failed to connect to any of the given relays.\n")
|
log("failed to connect to any of the given relays.\n")
|
||||||
|
|
Loading…
Reference in New Issue
Block a user