diff --git a/lightningd/Makefile b/lightningd/Makefile index 844d2748f..8876dc55c 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -115,6 +115,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/penalty_base.o \ common/per_peer_state.o \ common/permute_tx.o \ + common/psbt_keypath.o \ common/psbt_open.o \ common/pseudorand.o \ common/random_select.o \ diff --git a/wallet/test/Makefile b/wallet/test/Makefile index 278287cfb..c6c26ac91 100644 --- a/wallet/test/Makefile +++ b/wallet/test/Makefile @@ -21,6 +21,7 @@ WALLET_TEST_COMMON_OBJS := \ common/node_id.o \ common/onionreply.o \ common/key_derive.o \ + common/psbt_keypath.o \ common/pseudorand.o \ common/setup.o \ common/timeout.o \ diff --git a/wallet/walletrpc.c b/wallet/walletrpc.c index 1d32d89de..fb2d3815b 100644 --- a/wallet/walletrpc.c +++ b/wallet/walletrpc.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -658,6 +659,35 @@ static struct command_result *match_psbt_inputs_to_utxos(struct command *cmd, return NULL; } +static void match_psbt_outputs_to_wallet(struct wally_psbt *psbt, + struct wallet *w) +{ + assert(psbt->tx->num_outputs == psbt->num_outputs); + tal_wally_start(); + for (size_t outndx = 0; outndx < psbt->num_outputs; ++outndx) { + u32 index; + bool is_p2sh; + const u8 *script; + struct ext_key ext; + + script = wally_tx_output_get_script(tmpctx, + &psbt->tx->outputs[outndx]); + if (!script) + continue; + + if (!wallet_can_spend(w, script, &index, &is_p2sh)) + continue; + + if (bip32_key_from_parent( + w->bip32_base, index, BIP32_FLAG_KEY_PUBLIC, &ext) != WALLY_OK) { + abort(); + } + + psbt_set_keypath(index, &ext, &psbt->outputs[outndx].keypaths); + } + tal_wally_end(psbt); +} + static struct command_result *param_input_numbers(struct command *cmd, const char *name, const char *buffer, @@ -721,6 +751,9 @@ static struct command_result *json_signpsbt(struct command *cmd, return command_fail(cmd, LIGHTNINGD, "No wallet inputs to sign"); + /* Update the keypaths on any outputs that are in our wallet (change addresses). */ + match_psbt_outputs_to_wallet(psbt, cmd->ld->wallet); + /* FIXME: hsm will sign almost anything, but it should really * fail cleanly (not abort!) and let us report the error here. */ u8 *msg = towire_hsmd_sign_withdrawal(cmd,