2023-03-16 11:17:19 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
2023-06-14 21:01:31 +02:00
|
|
|
"crypto/rand"
|
|
|
|
|
"encoding/binary"
|
|
|
|
|
"encoding/hex"
|
2023-03-16 11:17:19 +02:00
|
|
|
"fmt"
|
2023-06-14 21:01:31 +02:00
|
|
|
"os"
|
2023-03-16 11:17:19 +02:00
|
|
|
|
|
|
|
|
"github.com/lightninglabs/lightning-terminal/litrpc"
|
2023-06-14 21:01:31 +02:00
|
|
|
"github.com/lightningnetwork/lnd/lncfg"
|
2023-03-16 11:17:19 +02:00
|
|
|
"github.com/urfave/cli"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var litCommands = []cli.Command{
|
2023-06-14 21:01:31 +02:00
|
|
|
{
|
|
|
|
|
Name: "bakesupermacaroon",
|
|
|
|
|
Usage: "Bake a new super macaroon with all of LiT's active " +
|
2023-10-26 12:31:40 -06:00
|
|
|
"permissions",
|
2025-12-09 15:57:14 +00:00
|
|
|
Description: "Bake a new super macaroon with all of LiT's " +
|
|
|
|
|
"active permissions.",
|
2023-06-14 21:01:31 +02:00
|
|
|
Category: "LiT",
|
|
|
|
|
Action: bakeSuperMacaroon,
|
|
|
|
|
Flags: []cli.Flag{
|
|
|
|
|
cli.StringFlag{
|
|
|
|
|
Name: "root_key_suffix",
|
|
|
|
|
Usage: "A 4-byte suffix to use in the " +
|
|
|
|
|
"construction of the root key ID. " +
|
|
|
|
|
"If not provided, then a random one " +
|
|
|
|
|
"will be generated. This must be " +
|
|
|
|
|
"specified as a hex string using a " +
|
|
|
|
|
"maximum of 8 characters.",
|
|
|
|
|
},
|
2024-10-14 11:00:51 +02:00
|
|
|
cli.BoolFlag{
|
|
|
|
|
Name: "read_only",
|
|
|
|
|
Usage: "Whether the macaroon should " +
|
|
|
|
|
"only contain read permissions.",
|
|
|
|
|
},
|
2023-06-14 21:01:31 +02:00
|
|
|
cli.StringFlag{
|
|
|
|
|
Name: "save_to",
|
2023-10-26 12:31:40 -06:00
|
|
|
Usage: "Save returned admin macaroon to " +
|
|
|
|
|
"this file.",
|
2023-06-14 21:01:31 +02:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
2023-10-26 12:31:40 -06:00
|
|
|
{
|
|
|
|
|
Name: "getinfo",
|
|
|
|
|
Usage: "Returns basic information related to the active " +
|
|
|
|
|
"daemon",
|
2025-12-09 15:57:14 +00:00
|
|
|
Description: "Returns basic information related to the " +
|
|
|
|
|
"active daemon.",
|
2023-10-26 12:31:40 -06:00
|
|
|
Category: "LiT",
|
|
|
|
|
Action: getInfo,
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
Name: "stop",
|
|
|
|
|
Usage: "Shutdown the LiT daemon",
|
|
|
|
|
Description: "Shutdown the LiT daemon.\n",
|
|
|
|
|
Category: "LiT",
|
|
|
|
|
Action: shutdownLit,
|
|
|
|
|
},
|
2023-03-16 11:17:19 +02:00
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func getInfo(cli *cli.Context) error {
|
|
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2023-03-16 11:17:19 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewProxyClient(clientConn)
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx := getContext()
|
|
|
|
|
resp, err := client.GetInfo(ctx, &litrpc.GetInfoRequest{})
|
2023-03-16 11:17:19 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printRespJSON(resp)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func shutdownLit(cli *cli.Context) error {
|
|
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2023-03-16 11:17:19 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewProxyClient(clientConn)
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx := getContext()
|
|
|
|
|
_, err = client.StopDaemon(ctx, &litrpc.StopDaemonRequest{})
|
2023-03-16 11:17:19 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fmt.Println("Successfully shutdown LiTd")
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
2023-06-14 21:01:31 +02:00
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
func bakeSuperMacaroon(cli *cli.Context) error {
|
2023-06-14 21:01:31 +02:00
|
|
|
var suffixBytes [4]byte
|
2025-01-13 09:07:30 +02:00
|
|
|
if cli.IsSet("root_key_suffix") {
|
2023-06-14 21:01:31 +02:00
|
|
|
suffixHex, err := hex.DecodeString(
|
2025-01-13 09:07:30 +02:00
|
|
|
cli.String("root_key_suffix"),
|
2023-06-14 21:01:31 +02:00
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
copy(suffixBytes[:], suffixHex)
|
|
|
|
|
} else {
|
|
|
|
|
_, err := rand.Read(suffixBytes[:])
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
suffix := binary.BigEndian.Uint32(suffixBytes[:])
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
clientConn, cleanup, err := connectClient(cli, false)
|
2023-06-14 21:01:31 +02:00
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
defer cleanup()
|
|
|
|
|
client := litrpc.NewProxyClient(clientConn)
|
|
|
|
|
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx := getContext()
|
2023-06-14 21:01:31 +02:00
|
|
|
resp, err := client.BakeSuperMacaroon(
|
2025-01-13 09:07:30 +02:00
|
|
|
ctx, &litrpc.BakeSuperMacaroonRequest{
|
2023-06-14 21:01:31 +02:00
|
|
|
RootKeyIdSuffix: suffix,
|
2025-01-13 09:07:30 +02:00
|
|
|
ReadOnly: cli.Bool("read_only"),
|
2023-06-14 21:01:31 +02:00
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the user specified the optional --save_to parameter, we'll save
|
|
|
|
|
// the macaroon to that file.
|
2025-01-13 09:07:30 +02:00
|
|
|
if cli.IsSet("save_to") {
|
|
|
|
|
macSavePath := lncfg.CleanAndExpandPath(cli.String("save_to"))
|
2023-06-14 21:01:31 +02:00
|
|
|
superMacBytes, err := hex.DecodeString(resp.Macaroon)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = os.WriteFile(macSavePath, superMacBytes, 0644)
|
|
|
|
|
if err != nil {
|
|
|
|
|
_ = os.Remove(macSavePath)
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
fmt.Printf("Super macaroon saved to %s\n", macSavePath)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
printRespJSON(resp)
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|