main.go raw
1 // Command nostrino-discover lists chain-data gateways announced on relays.
2 package main
3
4 import (
5 "context"
6 "encoding/json"
7 "flag"
8 "fmt"
9 "os"
10 "strings"
11 "time"
12
13 "git.smesh.lol/nostrino/pkg/registry"
14 "git.smesh.lol/nostrino/pkg/relay"
15 )
16
17 type stringsFlag []string
18
19 func (s *stringsFlag) String() string { return strings.Join(*s, ",") }
20 func (s *stringsFlag) Set(v string) error {
21 for _, part := range strings.Split(v, ",") {
22 if part = strings.TrimSpace(part); part != "" {
23 *s = append(*s, part)
24 }
25 }
26 return nil
27 }
28
29 func main() {
30 var relays stringsFlag
31 fs := flag.NewFlagSet("nostrino-discover", flag.ContinueOnError)
32 fs.Var(&relays, "relay", "relay URL; repeat or comma-separate")
33 chain := fs.String("chain", "btc", "chain name to discover")
34 collect := fs.Duration("collect", 1500*time.Millisecond, "how long to collect announcements after EOSE")
35 timeout := fs.Duration("timeout", 20*time.Second, "overall timeout")
36 asJSON := fs.Bool("json", false, "print JSON")
37 if err := fs.Parse(os.Args[1:]); err != nil {
38 os.Exit(2)
39 }
40 if len(relays) == 0 {
41 fmt.Fprintln(os.Stderr, "nostrino-discover: at least one -relay is required")
42 os.Exit(2)
43 }
44 ctx, cancel := context.WithTimeout(context.Background(), *timeout)
45 defer cancel()
46 infos, err := registry.Discover(ctx, relay.DialTransport, relays, *chain, *collect)
47 if err != nil {
48 fmt.Fprintln(os.Stderr, "nostrino-discover:", err)
49 os.Exit(1)
50 }
51 if *asJSON {
52 out, _ := json.MarshalIndent(infos, "", " ")
53 fmt.Println(string(out))
54 return
55 }
56 if len(infos) == 0 {
57 fmt.Println("no gateways announced")
58 return
59 }
60 for _, info := range infos {
61 fmt.Printf("%s updated=%s tip=%d\n", info.URI, time.Unix(info.UpdatedAt, 0).Format(time.RFC3339), info.Tip)
62 if info.Version != "" {
63 fmt.Printf(" version=%s chains=%s\n", info.Version, strings.Join(info.Chains, ","))
64 }
65 }
66 }
67