@@ -10,6 +10,7 @@ import (
10
10
"os"
11
11
"path/filepath"
12
12
"regexp"
13
+ "strings"
13
14
"sync"
14
15
"time"
15
16
@@ -20,11 +21,14 @@ import (
20
21
"github.com/lightninglabs/loop/loopd"
21
22
"github.com/lightninglabs/loop/looprpc"
22
23
"github.com/lightningnetwork/lnd"
24
+ "github.com/lightningnetwork/lnd/build"
23
25
"github.com/lightningnetwork/lnd/lnrpc"
24
26
"github.com/lightningnetwork/lnd/lntest/wait"
25
27
"github.com/lightningnetwork/lnd/signal"
26
28
"github.com/rakyll/statik/fs"
27
29
"google.golang.org/grpc"
30
+ "google.golang.org/grpc/codes"
31
+ "google.golang.org/grpc/status"
28
32
"gopkg.in/macaroon-bakery.v2/bakery"
29
33
30
34
// Import generated go package that contains all static files for the
@@ -183,6 +187,12 @@ func (g *LightningTerminal) Run() error {
183
187
return fmt .Errorf ("error starting UI HTTP server: %v" , err )
184
188
}
185
189
190
+ // Now that we have started the main UI web server, show some useful
191
+ // information to the user so they can access the web UI easily.
192
+ if err := g .showStartupInfo (); err != nil {
193
+ return fmt .Errorf ("error displaying startup info: %v" , err )
194
+ }
195
+
186
196
// Wait for lnd to be unlocked, then start all clients.
187
197
select {
188
198
case <- readyChan :
@@ -544,6 +554,86 @@ func (g *LightningTerminal) startMainWebServer() error {
544
554
return nil
545
555
}
546
556
557
+ // showStartupInfo shows useful information to the user to easily access the
558
+ // web UI that was just started.
559
+ func (g * LightningTerminal ) showStartupInfo () error {
560
+ info := struct {
561
+ mode string
562
+ status string
563
+ alias string
564
+ version string
565
+ webURI string
566
+ }{
567
+ mode : g .cfg .LndMode ,
568
+ status : "locked" ,
569
+ alias : g .cfg .Lnd .Alias ,
570
+ version : build .Version (),
571
+ webURI : fmt .Sprintf ("https://%s" , strings .ReplaceAll (
572
+ strings .ReplaceAll (
573
+ g .cfg .HTTPSListen , "0.0.0.0" , "127.0.0.1" ,
574
+ ), "[::]" , "[::1]" ,
575
+ )),
576
+ }
577
+
578
+ // In remote mode we try to query the info.
579
+ if g .cfg .LndMode == ModeRemote {
580
+ // We try to query GetInfo on the remote node to find out the
581
+ // alias. But the wallet might be locked.
582
+ host , network , tlsPath , macPath , _ := g .cfg .lndConnectParams ()
583
+ basicClient , err := lndclient .NewBasicClient (
584
+ host , tlsPath , filepath .Dir (macPath ), string (network ),
585
+ lndclient .MacFilename (filepath .Base (macPath )),
586
+ )
587
+ if err != nil {
588
+ return fmt .Errorf ("error querying remote node: %v" , err )
589
+ }
590
+
591
+ ctx := context .Background ()
592
+ res , err := basicClient .GetInfo (ctx , & lnrpc.GetInfoRequest {})
593
+ if err != nil {
594
+ s , ok := status .FromError (err )
595
+ if ! ok || s .Code () != codes .Unimplemented {
596
+ // Some other error that we didn't expect at
597
+ // this moment.
598
+ return fmt .Errorf ("error querying remote " +
599
+ "node : %v" , err )
600
+ }
601
+
602
+ // Node is locked.
603
+ info .status = "locked"
604
+ info .alias = "???? (node is locked)"
605
+ } else {
606
+ info .status = "online"
607
+ info .alias = res .Alias
608
+ info .version = res .Version
609
+ }
610
+ }
611
+
612
+ // In integrated mode, we can derive the state from our configuration.
613
+ if g .cfg .LndMode == ModeIntegrated {
614
+ // If the integrated node is running with no seed backup, the
615
+ // wallet cannot be locked and the node is online right away.
616
+ if g .cfg .Lnd .NoSeedBackup {
617
+ info .status = "online"
618
+ }
619
+ }
620
+
621
+ str := "" +
622
+ "----------------------------------------------------------\n " +
623
+ " Lightning Terminal (LiT) by Lightning Labs \n " +
624
+ " \n " +
625
+ " Operating mode %s \n " +
626
+ " Node status %s \n " +
627
+ " Alias %s \n " +
628
+ " Version %s \n " +
629
+ " Web interface %s \n " +
630
+ "----------------------------------------------------------\n "
631
+ fmt .Printf (str , info .mode , info .status , info .alias , info .version ,
632
+ info .webURI )
633
+
634
+ return nil
635
+ }
636
+
547
637
// ClientRouteWrapper is a wrapper around a FileSystem which properly handles
548
638
// URL routes that are defined in the client app but unknown to the backend
549
639
// http server
0 commit comments