mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 09:53:54 +01:00
lncli: add sign/verify message with an address
adds the functionality in the lncli walletkit to sign and verify a message with a single address. Signing works only with lnd default wallet account. Verifying signature on messages with external addresses is also supported.
This commit is contained in:
parent
39b77edca1
commit
5edf64f4c5
@ -52,6 +52,8 @@ var (
|
|||||||
Usage: "Interact with wallet addresses.",
|
Usage: "Interact with wallet addresses.",
|
||||||
Subcommands: []cli.Command{
|
Subcommands: []cli.Command{
|
||||||
listAddressesCommand,
|
listAddressesCommand,
|
||||||
|
signMessageWithAddrCommand,
|
||||||
|
verifyMessageWithAddrCommand,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -1193,6 +1195,200 @@ func listAddresses(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var signMessageWithAddrCommand = cli.Command{
|
||||||
|
Name: "signmessage",
|
||||||
|
Usage: "Sign a message with the private key of the provided " +
|
||||||
|
"address.",
|
||||||
|
ArgsUsage: "address msg",
|
||||||
|
Description: `
|
||||||
|
Sign a message with the private key of the specified address, and
|
||||||
|
return the signature. Signing is solely done in the ECDSA compact
|
||||||
|
signature format. This is also done when signing with a P2TR address
|
||||||
|
meaning that the private key of the P2TR address (internal key) is used
|
||||||
|
to sign the provided message with the ECDSA format. Only addresses are
|
||||||
|
accepted which are owned by the internal lnd wallet.
|
||||||
|
`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "address",
|
||||||
|
Usage: "specify the address which private key " +
|
||||||
|
"will be used to sign the message",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "msg",
|
||||||
|
Usage: "the message to sign for",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(signMessageWithAddr),
|
||||||
|
}
|
||||||
|
|
||||||
|
func signMessageWithAddr(ctx *cli.Context) error {
|
||||||
|
ctxc := getContext()
|
||||||
|
|
||||||
|
// Display the command's help message if we do not have the expected
|
||||||
|
// number of arguments/flags.
|
||||||
|
if ctx.NArg() > 2 || ctx.NumFlags() > 2 {
|
||||||
|
return cli.ShowCommandHelp(ctx, "signmessagewithaddr")
|
||||||
|
}
|
||||||
|
|
||||||
|
walletClient, cleanUp := getWalletClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
var (
|
||||||
|
args = ctx.Args()
|
||||||
|
addr string
|
||||||
|
msg []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("address"):
|
||||||
|
addr = ctx.String("address")
|
||||||
|
|
||||||
|
case ctx.Args().Present():
|
||||||
|
addr = args.First()
|
||||||
|
args = args.Tail()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("address argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("msg"):
|
||||||
|
msg = []byte(ctx.String("msg"))
|
||||||
|
|
||||||
|
case ctx.Args().Present():
|
||||||
|
msg = []byte(args.First())
|
||||||
|
args = args.Tail()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("msg argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := walletClient.SignMessageWithAddr(
|
||||||
|
ctxc,
|
||||||
|
&walletrpc.SignMessageWithAddrRequest{
|
||||||
|
Msg: msg,
|
||||||
|
Addr: addr,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
printRespJSON(resp)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var verifyMessageWithAddrCommand = cli.Command{
|
||||||
|
Name: "verifymessage",
|
||||||
|
Usage: "Verify a message signed with the private key of the " +
|
||||||
|
"provided address.",
|
||||||
|
ArgsUsage: "address sig msg",
|
||||||
|
Description: `
|
||||||
|
Verify a message signed with the signature of the public key
|
||||||
|
of the provided address. The signature must be in compact ECDSA format
|
||||||
|
The verification is independent whether the address belongs to the
|
||||||
|
wallet or not. This is achieved by only accepting ECDSA compacted
|
||||||
|
signatures. When verifying a signature with a taproot address, the
|
||||||
|
signature still has to be in the ECDSA compact format and no tapscript
|
||||||
|
has to be included in the P2TR address.
|
||||||
|
Supports address types P2PKH, P2WKH, NP2WKH, P2TR.
|
||||||
|
|
||||||
|
Besides whether the signature is valid or not, the recoverd public key
|
||||||
|
of the compact ECDSA signature is returned.
|
||||||
|
`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "address",
|
||||||
|
Usage: "specify the address which corresponding" +
|
||||||
|
"public key will be used",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "sig",
|
||||||
|
Usage: "the base64 encoded compact signature " +
|
||||||
|
"of the message",
|
||||||
|
},
|
||||||
|
cli.StringFlag{
|
||||||
|
Name: "msg",
|
||||||
|
Usage: "the message to sign",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: actionDecorator(verifyMessageWithAddr),
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyMessageWithAddr(ctx *cli.Context) error {
|
||||||
|
ctxc := getContext()
|
||||||
|
|
||||||
|
// Display the command's help message if we do not have the expected
|
||||||
|
// number of arguments/flags.
|
||||||
|
if ctx.NArg() > 3 || ctx.NumFlags() > 3 {
|
||||||
|
return cli.ShowCommandHelp(ctx, "signmessagewithaddr")
|
||||||
|
}
|
||||||
|
|
||||||
|
walletClient, cleanUp := getWalletClient(ctx)
|
||||||
|
defer cleanUp()
|
||||||
|
|
||||||
|
var (
|
||||||
|
args = ctx.Args()
|
||||||
|
addr string
|
||||||
|
sig string
|
||||||
|
msg []byte
|
||||||
|
)
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("address"):
|
||||||
|
addr = ctx.String("address")
|
||||||
|
|
||||||
|
case args.Present():
|
||||||
|
addr = args.First()
|
||||||
|
args = args.Tail()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("address argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("sig"):
|
||||||
|
sig = ctx.String("sig")
|
||||||
|
|
||||||
|
case ctx.Args().Present():
|
||||||
|
sig = args.First()
|
||||||
|
args = args.Tail()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("sig argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch {
|
||||||
|
case ctx.IsSet("msg"):
|
||||||
|
msg = []byte(ctx.String("msg"))
|
||||||
|
|
||||||
|
case ctx.Args().Present():
|
||||||
|
msg = []byte(args.First())
|
||||||
|
args = args.Tail()
|
||||||
|
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("msg argument missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := walletClient.VerifyMessageWithAddr(
|
||||||
|
ctxc,
|
||||||
|
&walletrpc.VerifyMessageWithAddrRequest{
|
||||||
|
Msg: msg,
|
||||||
|
Signature: sig,
|
||||||
|
Addr: addr,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
printRespJSON(resp)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
var importAccountCommand = cli.Command{
|
var importAccountCommand = cli.Command{
|
||||||
Name: "import",
|
Name: "import",
|
||||||
Usage: "Import an on-chain account into the wallet through its " +
|
Usage: "Import an on-chain account into the wallet through its " +
|
||||||
|
Loading…
Reference in New Issue
Block a user