@ -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 ] ) ;
}
}