Browse Source

tools: add a new 'dumponchaindescriptors' command to hsmtool

This adds a command which outputs the two output descriptors
corresponding to our onchain wallet.

This can be useful for an external service to monitor / send fund to our
wallet.

Further, an "xpriv" version of such descriptors could be used to import
onchain funds on a new wallet.

Changelog-Added: lightning-hsmtool: a new command was added to hsmtool for dumping descriptors of the onchain wallet
Signed-off-by: Antoine Poinsot <darosior@protonmail.com>
ppa-prep
Antoine Poinsot 4 years ago
committed by neil saitug
parent
commit
9f8e2e0502
  1. 2
      tools/Makefile
  2. 62
      tools/hsmtool.c

2
tools/Makefile

@ -17,7 +17,7 @@ tools/headerversions: FORCE tools/headerversions.o $(CCAN_OBJS)
tools/check-bolt: tools/check-bolt.o $(CCAN_OBJS) $(TOOLS_COMMON_OBJS) tools/check-bolt: tools/check-bolt.o $(CCAN_OBJS) $(TOOLS_COMMON_OBJS)
tools/hsmtool: tools/hsmtool.o $(CCAN_OBJS) $(TOOLS_COMMON_OBJS) $(BITCOIN_OBJS) common/amount.o common/bech32.o common/bigsize.o common/derive_basepoints.o common/node_id.o common/type_to_string.o wire/fromwire.o wire/towire.o tools/hsmtool: tools/hsmtool.o $(CCAN_OBJS) $(TOOLS_COMMON_OBJS) $(BITCOIN_OBJS) common/amount.o common/bech32.o common/bigsize.o common/derive_basepoints.o common/descriptor_checksum.o common/node_id.o common/type_to_string.o wire/fromwire.o wire/towire.o
tools/lightning-hsmtool: tools/hsmtool tools/lightning-hsmtool: tools/hsmtool
cp $< $@ cp $< $@

62
tools/hsmtool.c

@ -6,8 +6,10 @@
#include <ccan/read_write_all/read_write_all.h> #include <ccan/read_write_all/read_write_all.h>
#include <ccan/str/str.h> #include <ccan/str/str.h>
#include <ccan/tal/path/path.h> #include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h>
#include <common/bech32.h> #include <common/bech32.h>
#include <common/derive_basepoints.h> #include <common/derive_basepoints.h>
#include <common/descriptor_checksum.h>
#include <common/node_id.h> #include <common/node_id.h>
#include <common/type_to_string.h> #include <common/type_to_string.h>
#include <common/utils.h> #include <common/utils.h>
@ -39,6 +41,7 @@ static void show_usage(const char *progname)
printf(" - guesstoremote <P2WPKH address> <node id> <tries> " printf(" - guesstoremote <P2WPKH address> <node id> <tries> "
"<path/to/hsm_secret> [hsm_secret password]\n"); "<path/to/hsm_secret> [hsm_secret password]\n");
printf(" - generatehsm <path/to/new//hsm_secret>\n"); printf(" - generatehsm <path/to/new//hsm_secret>\n");
printf(" - dumponchaindescriptors <path/to/hsm_secret> <password>\n");
exit(0); exit(0);
} }
@ -513,6 +516,58 @@ static int generate_hsm(const char *hsm_secret_path)
return 0; return 0;
} }
static int dumponchaindescriptors(const char *hsm_secret_path, const char *passwd)
{
struct secret hsm_secret;
u8 bip32_seed[BIP32_ENTROPY_LEN_256];
u32 salt = 0;
struct ext_key master_extkey;
char *enc_xpub, *descriptor;
struct descriptor_checksum checksum;
if (passwd)
get_encrypted_hsm_secret(&hsm_secret, hsm_secret_path, passwd);
else
get_hsm_secret(&hsm_secret, hsm_secret_path);
/* We use m/0/0/k as the derivation tree for onchain funds. */
/* The root seed is derived from hsm_secret using hkdf.. */
do {
hkdf_sha256(bip32_seed, sizeof(bip32_seed),
&salt, sizeof(salt),
&hsm_secret, sizeof(hsm_secret),
"bip32 seed", strlen("bip32 seed"));
salt++;
/* ..Which is used to derive m/ */
} while (bip32_key_from_seed(bip32_seed, sizeof(bip32_seed),
/* An xpub can easily be converted to a tpub */
BIP32_VER_MAIN_PRIVATE,
0, &master_extkey) != WALLY_OK);
if (bip32_key_to_base58(&master_extkey, BIP32_FLAG_KEY_PUBLIC, &enc_xpub) != WALLY_OK)
errx(ERROR_LIBWALLY, "Can't encode xpub");
/* Now we format the descriptor strings (we only ever create P2WPKH and
* P2SH-P2WPKH outputs). */
descriptor = tal_fmt(NULL, "wpkh(%s/0/0/*)", enc_xpub);
if (!descriptor_checksum(descriptor, strlen(descriptor), &checksum))
errx(ERROR_LIBWALLY, "Can't derive descriptor checksum for wpkh");
printf("%s#%s\n", descriptor, checksum.csum);
tal_free(descriptor);
descriptor = tal_fmt(NULL, "sh(wpkh(%s/0/0/*))", enc_xpub);
if (!descriptor_checksum(descriptor, strlen(descriptor), &checksum))
errx(ERROR_LIBWALLY, "Can't derive descriptor checksum for sh(wpkh)");
printf("%s#%s\n", descriptor, checksum.csum);
tal_free(descriptor);
wally_free_string(enc_xpub);
return 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
const char *method; const char *method;
@ -573,5 +628,12 @@ int main(int argc, char *argv[])
return generate_hsm(hsm_secret_path); return generate_hsm(hsm_secret_path);
} }
if (streq(method, "dumponchaindescriptors")) {
if (argc < 3)
show_usage(argv[0]);
return dumponchaindescriptors(argv[2], argc > 3 ? argv[3] : NULL);
}
show_usage(argv[0]); show_usage(argv[0]);
} }

Loading…
Cancel
Save