| 
 | 1 | +package main  | 
 | 2 | + | 
 | 3 | +import (  | 
 | 4 | +	"fmt"  | 
 | 5 | + | 
 | 6 | +	chantools_lnd "github.com/lightninglabs/chantools/lnd"  | 
 | 7 | +	"github.com/lightningnetwork/lnd/keychain"  | 
 | 8 | +	"github.com/spf13/cobra"  | 
 | 9 | +	"github.com/tv42/zbase32"  | 
 | 10 | +)  | 
 | 11 | + | 
 | 12 | +var (  | 
 | 13 | +	signedMsgPrefix = []byte("Lightning Signed Message:")  | 
 | 14 | +)  | 
 | 15 | + | 
 | 16 | +type signMessageCommand struct {  | 
 | 17 | +	Msg string  | 
 | 18 | + | 
 | 19 | +	rootKey *rootKey  | 
 | 20 | +	cmd     *cobra.Command  | 
 | 21 | +}  | 
 | 22 | + | 
 | 23 | +func newSignMessageCommand() *cobra.Command {  | 
 | 24 | +	cc := &signMessageCommand{}  | 
 | 25 | +	cc.cmd = &cobra.Command{  | 
 | 26 | +		Use:   "signmessage",  | 
 | 27 | +		Short: "Sign a message with the node's private key.",  | 
 | 28 | +		Long: `Sign msg with the resident node's private key.  | 
 | 29 | +		Returns the signature as a zbase32 string.`,  | 
 | 30 | +		Example: `chantools signmessage --msg=foobar`,  | 
 | 31 | +		RunE:    cc.Execute,  | 
 | 32 | +	}  | 
 | 33 | +	cc.cmd.Flags().StringVar(  | 
 | 34 | +		&cc.Msg, "msg", "", "the message to sign",  | 
 | 35 | +	)  | 
 | 36 | + | 
 | 37 | +	cc.rootKey = newRootKey(cc.cmd, "decrypting the backup")  | 
 | 38 | + | 
 | 39 | +	return cc.cmd  | 
 | 40 | +}  | 
 | 41 | + | 
 | 42 | +func (c *signMessageCommand) Execute(_ *cobra.Command, _ []string) error {  | 
 | 43 | +	if c.Msg == "" {  | 
 | 44 | +		return fmt.Errorf("please enter a valid msg")  | 
 | 45 | +	}  | 
 | 46 | + | 
 | 47 | +	extendedKey, err := c.rootKey.read()  | 
 | 48 | +	if err != nil {  | 
 | 49 | +		return fmt.Errorf("error reading root key: %w", err)  | 
 | 50 | +	}  | 
 | 51 | + | 
 | 52 | +	signer := &chantools_lnd.Signer{  | 
 | 53 | +		ExtendedKey: extendedKey,  | 
 | 54 | +		ChainParams: chainParams,  | 
 | 55 | +	}  | 
 | 56 | + | 
 | 57 | +	// Create the key locator for the node key.  | 
 | 58 | +	keyLocator := keychain.KeyLocator{  | 
 | 59 | +		Family: keychain.KeyFamilyNodeKey,  | 
 | 60 | +		Index:  0,  | 
 | 61 | +	}  | 
 | 62 | + | 
 | 63 | +	// Fetch the private key for node key.  | 
 | 64 | +	privKey, err := signer.FetchPrivKey(&keychain.KeyDescriptor{  | 
 | 65 | +		KeyLocator: keyLocator,  | 
 | 66 | +	})  | 
 | 67 | +	if err != nil {  | 
 | 68 | +		return err  | 
 | 69 | +	}  | 
 | 70 | + | 
 | 71 | +	// Create a new signer.  | 
 | 72 | +	privKeyMsgSigner := keychain.NewPrivKeyMessageSigner(  | 
 | 73 | +		privKey, keyLocator,  | 
 | 74 | +	)  | 
 | 75 | + | 
 | 76 | +	// Prepend the special lnd prefix.  | 
 | 77 | +	// See: https://github.com/lightningnetwork/lnd/blob/63e698ec4990e678089533561fd95cfd684b67db/rpcserver.go#L1576 .  | 
 | 78 | +	msg := []byte(c.Msg)  | 
 | 79 | +	msg = append(signedMsgPrefix, msg...)  | 
 | 80 | +	sigBytes, err := privKeyMsgSigner.SignMessageCompact(msg, true)  | 
 | 81 | +	if err != nil {  | 
 | 82 | +		return err  | 
 | 83 | +	}  | 
 | 84 | + | 
 | 85 | +	// Encode the signature.  | 
 | 86 | +	sig := zbase32.EncodeToString(sigBytes)  | 
 | 87 | +	fmt.Println(sig)  | 
 | 88 | + | 
 | 89 | +	return nil  | 
 | 90 | +}  | 
0 commit comments