mirror of
https://github.com/fiatjaf/nak.git
synced 2025-05-03 13:19:55 -04:00
much more colors everywhere and everything is prettier.
This commit is contained in:
parent
7ae2e686cb
commit
703c186958
@ -49,7 +49,7 @@ var bunker = &cli.Command{
|
|||||||
qs := url.Values{}
|
qs := url.Values{}
|
||||||
relayURLs := make([]string, 0, c.Args().Len())
|
relayURLs := make([]string, 0, c.Args().Len())
|
||||||
if relayUrls := c.Args().Slice(); len(relayUrls) > 0 {
|
if relayUrls := c.Args().Slice(); len(relayUrls) > 0 {
|
||||||
relays := connectToAllRelays(ctx, relayUrls, nil)
|
relays := connectToAllRelays(ctx, c, relayUrls, nil)
|
||||||
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")
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
|
2
count.go
2
count.go
@ -70,7 +70,7 @@ var count = &cli.Command{
|
|||||||
biggerUrlSize := 0
|
biggerUrlSize := 0
|
||||||
relayUrls := c.Args().Slice()
|
relayUrls := c.Args().Slice()
|
||||||
if len(relayUrls) > 0 {
|
if len(relayUrls) > 0 {
|
||||||
relays := connectToAllRelays(ctx, relayUrls, nil)
|
relays := connectToAllRelays(ctx, c, relayUrls, nil)
|
||||||
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")
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
|
12
dvm.go
12
dvm.go
@ -7,7 +7,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"github.com/nbd-wtf/go-nostr/nip90"
|
"github.com/nbd-wtf/go-nostr/nip90"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
@ -60,7 +59,7 @@ var dvm = &cli.Command{
|
|||||||
Flags: flags,
|
Flags: flags,
|
||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
relayUrls := c.StringSlice("relay")
|
relayUrls := c.StringSlice("relay")
|
||||||
relays := connectToAllRelays(ctx, relayUrls, nil)
|
relays := connectToAllRelays(ctx, c, relayUrls, nil)
|
||||||
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")
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
@ -103,10 +102,7 @@ var dvm = &cli.Command{
|
|||||||
log("- publishing job request... ")
|
log("- publishing job request... ")
|
||||||
first := true
|
first := true
|
||||||
for res := range sys.Pool.PublishMany(ctx, relayUrls, evt) {
|
for res := range sys.Pool.PublishMany(ctx, relayUrls, evt) {
|
||||||
cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://")
|
cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://")
|
||||||
if !ok {
|
|
||||||
cleanUrl = res.RelayURL
|
|
||||||
}
|
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
log(", ")
|
log(", ")
|
||||||
@ -114,9 +110,9 @@ var dvm = &cli.Command{
|
|||||||
first = false
|
first = false
|
||||||
|
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
log("%s: %s", color.RedString(cleanUrl), res.Error)
|
log("%s: %s", colors.errorf(cleanUrl), res.Error)
|
||||||
} else {
|
} else {
|
||||||
log("%s: ok", color.GreenString(cleanUrl))
|
log("%s: ok", colors.successf(cleanUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
129
event.go
129
event.go
@ -8,6 +8,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
"github.com/mailru/easyjson"
|
"github.com/mailru/easyjson"
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"github.com/nbd-wtf/go-nostr/nip13"
|
"github.com/nbd-wtf/go-nostr/nip13"
|
||||||
@ -133,8 +134,17 @@ example:
|
|||||||
Action: func(ctx context.Context, c *cli.Command) error {
|
Action: func(ctx context.Context, c *cli.Command) error {
|
||||||
// try to connect to the relays here
|
// try to connect to the relays here
|
||||||
var relays []*nostr.Relay
|
var relays []*nostr.Relay
|
||||||
|
|
||||||
|
// these are defaults, they will be replaced if we use the magic dynamic thing
|
||||||
|
logthis := func(relayUrl string, s string, args ...any) { log(s, args...) }
|
||||||
|
colorizethis := func(relayUrl string, colorize func(string, ...any) string) {}
|
||||||
|
|
||||||
if relayUrls := c.Args().Slice(); len(relayUrls) > 0 {
|
if relayUrls := c.Args().Slice(); len(relayUrls) > 0 {
|
||||||
relays = connectToAllRelays(ctx, relayUrls, nil)
|
relays = connectToAllRelays(ctx, c, relayUrls, nil,
|
||||||
|
nostr.WithAuthHandler(func(ctx context.Context, authEvent nostr.RelayEvent) error {
|
||||||
|
return authSigner(ctx, c, func(s string, args ...any) {}, authEvent)
|
||||||
|
}),
|
||||||
|
)
|
||||||
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")
|
||||||
os.Exit(3)
|
os.Exit(3)
|
||||||
@ -301,37 +311,104 @@ example:
|
|||||||
successRelays := make([]string, 0, len(relays))
|
successRelays := make([]string, 0, len(relays))
|
||||||
if len(relays) > 0 {
|
if len(relays) > 0 {
|
||||||
os.Stdout.Sync()
|
os.Stdout.Sync()
|
||||||
for _, relay := range relays {
|
|
||||||
publish:
|
if supportsDynamicMultilineMagic() {
|
||||||
log("publishing to %s... ", relay.URL)
|
// overcomplicated multiline rendering magic
|
||||||
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
err := relay.Publish(ctx, evt)
|
urls := make([]string, len(relays))
|
||||||
if err == nil {
|
lines := make([][][]byte, len(urls))
|
||||||
// published fine
|
flush := func() {
|
||||||
log("success.\n")
|
for _, line := range lines {
|
||||||
successRelays = append(successRelays, relay.URL)
|
for _, part := range line {
|
||||||
continue // continue to next relay
|
os.Stderr.Write(part)
|
||||||
}
|
}
|
||||||
|
os.Stderr.Write([]byte{'\n'})
|
||||||
// error publishing
|
|
||||||
if strings.HasPrefix(err.Error(), "msg: auth-required:") && kr != nil && doAuth {
|
|
||||||
// if the relay is requesting auth and we can auth, let's do it
|
|
||||||
pk, _ := kr.GetPublicKey(ctx)
|
|
||||||
log("performing auth as %s... ", pk)
|
|
||||||
if err := relay.Auth(ctx, func(authEvent *nostr.Event) error {
|
|
||||||
return kr.SignEvent(ctx, authEvent)
|
|
||||||
}); err == nil {
|
|
||||||
// try to publish again, but this time don't try to auth again
|
|
||||||
doAuth = false
|
|
||||||
goto publish
|
|
||||||
} else {
|
|
||||||
log("auth error: %s. ", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log("failed: %s\n", err)
|
render := func() {
|
||||||
|
clearLines(len(lines))
|
||||||
|
flush()
|
||||||
|
}
|
||||||
|
flush()
|
||||||
|
|
||||||
|
logthis = func(relayUrl, s string, args ...any) {
|
||||||
|
idx := slices.Index(urls, relayUrl)
|
||||||
|
lines[idx] = append(lines[idx], []byte(fmt.Sprintf(s, args...)))
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
colorizethis = func(relayUrl string, colorize func(string, ...any) string) {
|
||||||
|
cleanUrl, _ := strings.CutPrefix(relayUrl, "wss://")
|
||||||
|
idx := slices.Index(urls, relayUrl)
|
||||||
|
lines[idx][0] = []byte(fmt.Sprintf("publishing to %s... ", colorize(cleanUrl)))
|
||||||
|
render()
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, relay := range relays {
|
||||||
|
urls[i] = relay.URL
|
||||||
|
lines[i] = make([][]byte, 1, 3)
|
||||||
|
colorizethis(relay.URL, color.CyanString)
|
||||||
|
}
|
||||||
|
render()
|
||||||
|
|
||||||
|
for res := range sys.Pool.PublishMany(ctx, urls, evt) {
|
||||||
|
if res.Error == nil {
|
||||||
|
colorizethis(res.RelayURL, colors.successf)
|
||||||
|
logthis(res.RelayURL, "success.")
|
||||||
|
successRelays = append(successRelays, res.RelayURL)
|
||||||
|
} else {
|
||||||
|
colorizethis(res.RelayURL, colors.errorf)
|
||||||
|
|
||||||
|
// in this case it's likely that the lowest-level error is the one that will be more helpful
|
||||||
|
low := unwrapAll(res.Error)
|
||||||
|
|
||||||
|
// hack for some messages such as from relay.westernbtc.com
|
||||||
|
msg := strings.ReplaceAll(low.Error(), evt.PubKey, "author")
|
||||||
|
|
||||||
|
// do not allow the message to overflow the term window
|
||||||
|
msg = clampMessage(msg, 20+len(res.RelayURL))
|
||||||
|
|
||||||
|
logthis(res.RelayURL, msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// normal dumb flow
|
||||||
|
for _, relay := range relays {
|
||||||
|
publish:
|
||||||
|
cleanUrl, _ := strings.CutPrefix(relay.URL, "wss://")
|
||||||
|
log("publishing to %s... ", color.CyanString(cleanUrl))
|
||||||
|
ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
err := relay.Publish(ctx, evt)
|
||||||
|
if err == nil {
|
||||||
|
// published fine
|
||||||
|
log("success.\n")
|
||||||
|
successRelays = append(successRelays, relay.URL)
|
||||||
|
continue // continue to next relay
|
||||||
|
}
|
||||||
|
|
||||||
|
// error publishing
|
||||||
|
if strings.HasPrefix(err.Error(), "msg: auth-required:") && kr != nil && doAuth {
|
||||||
|
// if the relay is requesting auth and we can auth, let's do it
|
||||||
|
pk, _ := kr.GetPublicKey(ctx)
|
||||||
|
npub, _ := nip19.EncodePublicKey(pk)
|
||||||
|
log("authenticating as %s... ", color.YellowString("%s…%s", npub[0:7], npub[58:]))
|
||||||
|
if err := relay.Auth(ctx, func(authEvent *nostr.Event) error {
|
||||||
|
return kr.SignEvent(ctx, authEvent)
|
||||||
|
}); err == nil {
|
||||||
|
// try to publish again, but this time don't try to auth again
|
||||||
|
doAuth = false
|
||||||
|
goto publish
|
||||||
|
} else {
|
||||||
|
log("auth error: %s. ", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("failed: %s\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(successRelays) > 0 && c.Bool("nevent") {
|
if len(successRelays) > 0 && c.Bool("nevent") {
|
||||||
nevent, _ := nip19.EncodeEvent(evt.ID, successRelays, evt.PubKey)
|
nevent, _ := nip19.EncodeEvent(evt.ID, successRelays, evt.PubKey)
|
||||||
log(nevent + "\n")
|
log(nevent + "\n")
|
||||||
|
2
go.mod
2
go.mod
@ -77,3 +77,5 @@ require (
|
|||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.31.0 // indirect
|
||||||
golang.org/x/text v0.23.0 // indirect
|
golang.org/x/text v0.23.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
|
replace github.com/nbd-wtf/go-nostr => ../go-nostr
|
||||||
|
6
go.sum
6
go.sum
@ -35,8 +35,6 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku
|
|||||||
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||||
github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g=
|
|
||||||
github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
|
||||||
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
|
||||||
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
|
||||||
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU=
|
||||||
@ -55,8 +53,6 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
|
|||||||
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
|
||||||
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
|
||||||
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
|
||||||
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
|
|
||||||
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
|
||||||
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
|
github.com/coder/websocket v1.8.13 h1:f3QZdXy7uGVz+4uCJy2nTZyM0yTBj8yANEHhqlXZ9FE=
|
||||||
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
github.com/coder/websocket v1.8.13/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
@ -157,8 +153,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
|||||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||||
github.com/nbd-wtf/go-nostr v0.51.8 h1:CIoS+YqChcm4e1L1rfMZ3/mIwTz4CwApM2qx7MHNzmE=
|
|
||||||
github.com/nbd-wtf/go-nostr v0.51.8/go.mod h1:d6+DfvMWYG5pA3dmNMBJd6WCHVDDhkXbHqvfljf0Gzg=
|
|
||||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
94
helpers.go
94
helpers.go
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"iter"
|
"iter"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -19,6 +20,7 @@ import (
|
|||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
jsoniter "github.com/json-iterator/go"
|
jsoniter "github.com/json-iterator/go"
|
||||||
"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/sdk"
|
"github.com/nbd-wtf/go-nostr/sdk"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
"golang.org/x/term"
|
"golang.org/x/term"
|
||||||
@ -151,8 +153,9 @@ func normalizeAndValidateRelayURLs(wsurls []string) error {
|
|||||||
|
|
||||||
func connectToAllRelays(
|
func connectToAllRelays(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
c *cli.Command,
|
||||||
relayUrls []string,
|
relayUrls []string,
|
||||||
preAuthSigner func(ctx context.Context, log func(s string, args ...any), authEvent nostr.RelayEvent) (err error), // if this exists we will force preauth
|
preAuthSigner func(ctx context.Context, c *cli.Command, log func(s string, args ...any), authEvent nostr.RelayEvent) (err error), // if this exists we will force preauth
|
||||||
opts ...nostr.PoolOption,
|
opts ...nostr.PoolOption,
|
||||||
) []*nostr.Relay {
|
) []*nostr.Relay {
|
||||||
sys.Pool = nostr.NewSimplePool(context.Background(),
|
sys.Pool = nostr.NewSimplePool(context.Background(),
|
||||||
@ -198,7 +201,7 @@ func connectToAllRelays(
|
|||||||
colorizepreamble(color.CyanString)
|
colorizepreamble(color.CyanString)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
relay := connectToSingleRelay(ctx, url, preAuthSigner, colorizepreamble, logthis)
|
relay := connectToSingleRelay(ctx, c, url, preAuthSigner, colorizepreamble, logthis)
|
||||||
if relay != nil {
|
if relay != nil {
|
||||||
relays = append(relays, relay)
|
relays = append(relays, relay)
|
||||||
}
|
}
|
||||||
@ -210,7 +213,7 @@ func connectToAllRelays(
|
|||||||
// simple flow
|
// simple flow
|
||||||
for _, url := range relayUrls {
|
for _, url := range relayUrls {
|
||||||
log("connecting to %s... ", color.CyanString(url))
|
log("connecting to %s... ", color.CyanString(url))
|
||||||
relay := connectToSingleRelay(ctx, url, preAuthSigner, nil, log)
|
relay := connectToSingleRelay(ctx, c, url, preAuthSigner, nil, log)
|
||||||
if relay != nil {
|
if relay != nil {
|
||||||
relays = append(relays, relay)
|
relays = append(relays, relay)
|
||||||
}
|
}
|
||||||
@ -223,8 +226,9 @@ func connectToAllRelays(
|
|||||||
|
|
||||||
func connectToSingleRelay(
|
func connectToSingleRelay(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
|
c *cli.Command,
|
||||||
url string,
|
url string,
|
||||||
preAuthSigner func(ctx context.Context, log func(s string, args ...any), authEvent nostr.RelayEvent) (err error),
|
preAuthSigner func(ctx context.Context, c *cli.Command, log func(s string, args ...any), authEvent nostr.RelayEvent) (err error),
|
||||||
colorizepreamble func(c func(string, ...any) string),
|
colorizepreamble func(c func(string, ...any) string),
|
||||||
logthis func(s string, args ...any),
|
logthis func(s string, args ...any),
|
||||||
) *nostr.Relay {
|
) *nostr.Relay {
|
||||||
@ -242,7 +246,7 @@ func connectToSingleRelay(
|
|||||||
if challengeTag[1] == "" {
|
if challengeTag[1] == "" {
|
||||||
return fmt.Errorf("auth not received yet *****") // what a giant hack
|
return fmt.Errorf("auth not received yet *****") // what a giant hack
|
||||||
}
|
}
|
||||||
return preAuthSigner(ctx, logthis, nostr.RelayEvent{Event: authEvent, Relay: relay})
|
return preAuthSigner(ctx, c, logthis, nostr.RelayEvent{Event: authEvent, Relay: relay})
|
||||||
}); err == nil {
|
}); err == nil {
|
||||||
// auth succeeded
|
// auth succeeded
|
||||||
goto preauthSuccess
|
goto preauthSuccess
|
||||||
@ -255,7 +259,7 @@ func connectToSingleRelay(
|
|||||||
} else {
|
} else {
|
||||||
// it failed for some other reason, so skip this relay
|
// it failed for some other reason, so skip this relay
|
||||||
if colorizepreamble != nil {
|
if colorizepreamble != nil {
|
||||||
colorizepreamble(color.RedString)
|
colorizepreamble(colors.errorf)
|
||||||
}
|
}
|
||||||
logthis(err.Error())
|
logthis(err.Error())
|
||||||
return nil
|
return nil
|
||||||
@ -263,7 +267,7 @@ func connectToSingleRelay(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if colorizepreamble != nil {
|
if colorizepreamble != nil {
|
||||||
colorizepreamble(color.RedString)
|
colorizepreamble(colors.errorf)
|
||||||
}
|
}
|
||||||
logthis("failed to get an AUTH challenge in enough time.")
|
logthis("failed to get an AUTH challenge in enough time.")
|
||||||
return nil
|
return nil
|
||||||
@ -271,15 +275,18 @@ func connectToSingleRelay(
|
|||||||
|
|
||||||
preauthSuccess:
|
preauthSuccess:
|
||||||
if colorizepreamble != nil {
|
if colorizepreamble != nil {
|
||||||
colorizepreamble(color.GreenString)
|
colorizepreamble(colors.successf)
|
||||||
}
|
}
|
||||||
logthis("ok.")
|
logthis("ok.")
|
||||||
return relay
|
return relay
|
||||||
} else {
|
} else {
|
||||||
if colorizepreamble != nil {
|
if colorizepreamble != nil {
|
||||||
colorizepreamble(color.RedString)
|
colorizepreamble(colors.errorf)
|
||||||
}
|
}
|
||||||
logthis(err.Error())
|
|
||||||
|
// if we're here that means we've failed to connect, this may be a huge message
|
||||||
|
// but we're likely to only be interested in the lowest level error (although we can leave space)
|
||||||
|
logthis(clampError(err, len(url)+12))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -309,6 +316,29 @@ func supportsDynamicMultilineMagic() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func authSigner(ctx context.Context, c *cli.Command, log func(s string, args ...any), authEvent nostr.RelayEvent) (err error) {
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
cleanUrl, _ := strings.CutPrefix(authEvent.Relay.URL, "wss://")
|
||||||
|
log("%s auth failed: %s", colors.errorf(cleanUrl), err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
if !c.Bool("auth") && !c.Bool("force-pre-auth") {
|
||||||
|
return fmt.Errorf("auth required, but --auth flag not given")
|
||||||
|
}
|
||||||
|
kr, _, err := gatherKeyerFromArguments(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pk, _ := kr.GetPublicKey(ctx)
|
||||||
|
npub, _ := nip19.EncodePublicKey(pk)
|
||||||
|
log("authenticating as %s... ", color.YellowString("%s…%s", npub[0:7], npub[58:]))
|
||||||
|
|
||||||
|
return kr.SignEvent(ctx, authEvent.Event)
|
||||||
|
}
|
||||||
|
|
||||||
func lineProcessingError(ctx context.Context, msg string, args ...any) context.Context {
|
func lineProcessingError(ctx context.Context, msg string, args ...any) context.Context {
|
||||||
log(msg+"\n", args...)
|
log(msg+"\n", args...)
|
||||||
return context.WithValue(ctx, LINE_PROCESSING_ERROR, true)
|
return context.WithValue(ctx, LINE_PROCESSING_ERROR, true)
|
||||||
@ -334,16 +364,50 @@ func leftPadKey(k string) string {
|
|||||||
return strings.Repeat("0", 64-len(k)) + k
|
return strings.Repeat("0", 64-len(k)) + k
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func unwrapAll(err error) error {
|
||||||
|
low := err
|
||||||
|
for n := low; n != nil; n = errors.Unwrap(low) {
|
||||||
|
low = n
|
||||||
|
}
|
||||||
|
return low
|
||||||
|
}
|
||||||
|
|
||||||
|
func clampMessage(msg string, prefixAlreadyPrinted int) string {
|
||||||
|
termSize, _, _ := term.GetSize(0)
|
||||||
|
if len(msg) > termSize-prefixAlreadyPrinted {
|
||||||
|
msg = msg[0:termSize-prefixAlreadyPrinted-1] + "…"
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func clampError(err error, prefixAlreadyPrinted int) string {
|
||||||
|
termSize, _, _ := term.GetSize(0)
|
||||||
|
msg := err.Error()
|
||||||
|
if len(msg) > termSize-prefixAlreadyPrinted {
|
||||||
|
err = unwrapAll(err)
|
||||||
|
msg = clampMessage(err.Error(), prefixAlreadyPrinted)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
var colors = struct {
|
var colors = struct {
|
||||||
reset func(...any) (int, error)
|
reset func(...any) (int, error)
|
||||||
italic func(...any) string
|
italic func(...any) string
|
||||||
italicf func(string, ...any) string
|
italicf func(string, ...any) string
|
||||||
bold func(...any) string
|
bold func(...any) string
|
||||||
boldf func(string, ...any) string
|
boldf func(string, ...any) string
|
||||||
|
error func(...any) string
|
||||||
|
errorf func(string, ...any) string
|
||||||
|
success func(...any) string
|
||||||
|
successf func(string, ...any) string
|
||||||
}{
|
}{
|
||||||
color.New(color.Reset).Print,
|
color.New(color.Reset).Print,
|
||||||
color.New(color.Italic).Sprint,
|
color.New(color.Italic).Sprint,
|
||||||
color.New(color.Italic).Sprintf,
|
color.New(color.Italic).Sprintf,
|
||||||
color.New(color.Bold).Sprint,
|
color.New(color.Bold).Sprint,
|
||||||
color.New(color.Bold).Sprintf,
|
color.New(color.Bold).Sprintf,
|
||||||
|
color.New(color.Bold, color.FgHiRed).Sprint,
|
||||||
|
color.New(color.Bold, color.FgHiRed).Sprintf,
|
||||||
|
color.New(color.Bold, color.FgHiGreen).Sprint,
|
||||||
|
color.New(color.Bold, color.FgHiGreen).Sprintf,
|
||||||
}
|
}
|
||||||
|
@ -348,11 +348,7 @@ func (e *EntityDir) handleWrite() {
|
|||||||
success := false
|
success := false
|
||||||
first := true
|
first := true
|
||||||
for res := range e.root.sys.Pool.PublishMany(e.root.ctx, relays, evt) {
|
for res := range e.root.sys.Pool.PublishMany(e.root.ctx, relays, evt) {
|
||||||
cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://")
|
cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://")
|
||||||
if !ok {
|
|
||||||
cleanUrl = res.RelayURL
|
|
||||||
}
|
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
log(", ")
|
log(", ")
|
||||||
}
|
}
|
||||||
|
@ -179,11 +179,7 @@ func (n *ViewDir) publishNote() {
|
|||||||
success := false
|
success := false
|
||||||
first := true
|
first := true
|
||||||
for res := range n.root.sys.Pool.PublishMany(n.root.ctx, relays, evt) {
|
for res := range n.root.sys.Pool.PublishMany(n.root.ctx, relays, evt) {
|
||||||
cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://")
|
cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://")
|
||||||
if !ok {
|
|
||||||
cleanUrl = res.RelayURL
|
|
||||||
}
|
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
log(", ")
|
log(", ")
|
||||||
}
|
}
|
||||||
|
36
req.go
36
req.go
@ -9,7 +9,6 @@ import (
|
|||||||
"github.com/fatih/color"
|
"github.com/fatih/color"
|
||||||
"github.com/mailru/easyjson"
|
"github.com/mailru/easyjson"
|
||||||
"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/nip77"
|
"github.com/nbd-wtf/go-nostr/nip77"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
@ -79,44 +78,21 @@ example:
|
|||||||
relayUrls := c.Args().Slice()
|
relayUrls := c.Args().Slice()
|
||||||
if len(relayUrls) > 0 {
|
if len(relayUrls) > 0 {
|
||||||
// this is used both for the normal AUTH (after "auth-required:" is received) or forced pre-auth
|
// this is used both for the normal AUTH (after "auth-required:" is received) or forced pre-auth
|
||||||
authSigner := func(ctx context.Context, log func(s string, args ...any), authEvent nostr.RelayEvent) (err error) {
|
|
||||||
defer func() {
|
|
||||||
if err != nil {
|
|
||||||
log("%s failed: %s",
|
|
||||||
authEvent.Tags.Find("relay")[1],
|
|
||||||
err,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
if !c.Bool("auth") && !c.Bool("force-pre-auth") {
|
|
||||||
return fmt.Errorf("auth required, but --auth flag not given")
|
|
||||||
}
|
|
||||||
kr, _, err := gatherKeyerFromArguments(ctx, c)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
pk, _ := kr.GetPublicKey(ctx)
|
|
||||||
npub, _ := nip19.EncodePublicKey(pk)
|
|
||||||
log("authenticating as %s... ", color.YellowString("%s…%s", npub[0:7], npub[58:]))
|
|
||||||
|
|
||||||
return kr.SignEvent(ctx, authEvent.Event)
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect to all relays we expect to use in this call in parallel
|
// connect to all relays we expect to use in this call in parallel
|
||||||
forcePreAuthSigner := authSigner
|
forcePreAuthSigner := authSigner
|
||||||
if !c.Bool("force-pre-auth") {
|
if !c.Bool("force-pre-auth") {
|
||||||
forcePreAuthSigner = nil
|
forcePreAuthSigner = nil
|
||||||
}
|
}
|
||||||
relays := connectToAllRelays(ctx,
|
relays := connectToAllRelays(
|
||||||
|
ctx,
|
||||||
|
c,
|
||||||
relayUrls,
|
relayUrls,
|
||||||
forcePreAuthSigner,
|
forcePreAuthSigner,
|
||||||
nostr.WithAuthHandler(func(ctx context.Context, authEvent nostr.RelayEvent) error {
|
nostr.WithAuthHandler(func(ctx context.Context, authEvent nostr.RelayEvent) error {
|
||||||
return authSigner(ctx, func(s string, args ...any) {
|
return authSigner(ctx, c, func(s string, args ...any) {
|
||||||
if strings.HasPrefix(s, "authenticating as") {
|
if strings.HasPrefix(s, "authenticating as") {
|
||||||
url := authEvent.Tags.Find("relay")[1]
|
cleanUrl, _ := strings.CutPrefix(authEvent.Relay.URL, "wss://")
|
||||||
s = "authenticating to " + color.CyanString(url) + " as" + s[len("authenticating as"):]
|
s = "authenticating to " + color.CyanString(cleanUrl) + " as" + s[len("authenticating as"):]
|
||||||
}
|
}
|
||||||
log(s+"\n", args...)
|
log(s+"\n", args...)
|
||||||
}, authEvent)
|
}, authEvent)
|
||||||
|
30
wallet.go
30
wallet.go
@ -6,7 +6,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/fatih/color"
|
|
||||||
"github.com/nbd-wtf/go-nostr"
|
"github.com/nbd-wtf/go-nostr"
|
||||||
"github.com/nbd-wtf/go-nostr/nip60"
|
"github.com/nbd-wtf/go-nostr/nip60"
|
||||||
"github.com/nbd-wtf/go-nostr/nip61"
|
"github.com/nbd-wtf/go-nostr/nip61"
|
||||||
@ -60,20 +59,16 @@ func prepareWallet(ctx context.Context, c *cli.Command) (*nip60.Wallet, func(),
|
|||||||
log("- saving kind:%d event (%s)... ", event.Kind, desc)
|
log("- saving kind:%d event (%s)... ", event.Kind, desc)
|
||||||
first := true
|
first := true
|
||||||
for res := range sys.Pool.PublishMany(ctx, relays, event) {
|
for res := range sys.Pool.PublishMany(ctx, relays, event) {
|
||||||
cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://")
|
cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://")
|
||||||
if !ok {
|
|
||||||
cleanUrl = res.RelayURL
|
|
||||||
}
|
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
log(", ")
|
log(", ")
|
||||||
}
|
}
|
||||||
first = false
|
first = false
|
||||||
|
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
log("%s: %s", color.RedString(cleanUrl), res.Error)
|
log("%s: %s", colors.errorf(cleanUrl), res.Error)
|
||||||
} else {
|
} else {
|
||||||
log("%s: ok", color.GreenString(cleanUrl))
|
log("%s: ok", colors.successf(cleanUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log("\n")
|
log("\n")
|
||||||
@ -376,19 +371,15 @@ var wallet = &cli.Command{
|
|||||||
log("- publishing nutzap... ")
|
log("- publishing nutzap... ")
|
||||||
first := true
|
first := true
|
||||||
for res := range results {
|
for res := range results {
|
||||||
cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://")
|
cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://")
|
||||||
if !ok {
|
|
||||||
cleanUrl = res.RelayURL
|
|
||||||
}
|
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
log(", ")
|
log(", ")
|
||||||
}
|
}
|
||||||
first = false
|
first = false
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
log("%s: %s", color.RedString(cleanUrl), res.Error)
|
log("%s: %s", colors.errorf(cleanUrl), res.Error)
|
||||||
} else {
|
} else {
|
||||||
log("%s: ok", color.GreenString(cleanUrl))
|
log("%s: ok", colors.successf(cleanUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -463,10 +454,7 @@ var wallet = &cli.Command{
|
|||||||
log("- saving kind:10019 event... ")
|
log("- saving kind:10019 event... ")
|
||||||
first := true
|
first := true
|
||||||
for res := range sys.Pool.PublishMany(ctx, relays, evt) {
|
for res := range sys.Pool.PublishMany(ctx, relays, evt) {
|
||||||
cleanUrl, ok := strings.CutPrefix(res.RelayURL, "wss://")
|
cleanUrl, _ := strings.CutPrefix(res.RelayURL, "wss://")
|
||||||
if !ok {
|
|
||||||
cleanUrl = res.RelayURL
|
|
||||||
}
|
|
||||||
|
|
||||||
if !first {
|
if !first {
|
||||||
log(", ")
|
log(", ")
|
||||||
@ -474,9 +462,9 @@ var wallet = &cli.Command{
|
|||||||
first = false
|
first = false
|
||||||
|
|
||||||
if res.Error != nil {
|
if res.Error != nil {
|
||||||
log("%s: %s", color.RedString(cleanUrl), res.Error)
|
log("%s: %s", colors.errorf(cleanUrl), res.Error)
|
||||||
} else {
|
} else {
|
||||||
log("%s: ok", color.GreenString(cleanUrl))
|
log("%s: ok", colors.successf(cleanUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user