|
14 | 14 | #include <key.h>
|
15 | 15 | #include <key_io.h>
|
16 | 16 | #include <optional.h>
|
| 17 | +#include <outputtype.h> |
17 | 18 | #include <policy/fees.h>
|
18 | 19 | #include <policy/policy.h>
|
19 | 20 | #include <primitives/block.h>
|
@@ -3864,7 +3865,7 @@ std::shared_ptr<CWallet> CWallet::Create(interfaces::Chain& chain, const std::st
|
3864 | 3865 | walletInstance->SetupLegacyScriptPubKeyMan();
|
3865 | 3866 | }
|
3866 | 3867 |
|
3867 |
| - if (!(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { |
| 3868 | + if ((wallet_creation_flags & WALLET_FLAG_EXTERNAL_SIGNER) || !(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) { |
3868 | 3869 | LOCK(walletInstance->cs_wallet);
|
3869 | 3870 | if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
3870 | 3871 | walletInstance->SetupDescriptorScriptPubKeyMans();
|
@@ -4488,32 +4489,65 @@ void CWallet::SetupDescriptorScriptPubKeyMans()
|
4488 | 4489 | {
|
4489 | 4490 | AssertLockHeld(cs_wallet);
|
4490 | 4491 |
|
4491 |
| - // Make a seed |
4492 |
| - CKey seed_key; |
4493 |
| - seed_key.MakeNewKey(true); |
4494 |
| - CPubKey seed = seed_key.GetPubKey(); |
4495 |
| - assert(seed_key.VerifyPubKey(seed)); |
| 4492 | + if (!IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) { |
| 4493 | + // Make a seed |
| 4494 | + CKey seed_key; |
| 4495 | + seed_key.MakeNewKey(true); |
| 4496 | + CPubKey seed = seed_key.GetPubKey(); |
| 4497 | + assert(seed_key.VerifyPubKey(seed)); |
4496 | 4498 |
|
4497 |
| - // Get the extended key |
4498 |
| - CExtKey master_key; |
4499 |
| - master_key.SetSeed(seed_key.begin(), seed_key.size()); |
| 4499 | + // Get the extended key |
| 4500 | + CExtKey master_key; |
| 4501 | + master_key.SetSeed(seed_key.begin(), seed_key.size()); |
4500 | 4502 |
|
4501 |
| - for (bool internal : {false, true}) { |
4502 |
| - for (OutputType t : OUTPUT_TYPES) { |
4503 |
| - auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, internal)); |
4504 |
| - if (IsCrypted()) { |
4505 |
| - if (IsLocked()) { |
4506 |
| - throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors"); |
| 4503 | + for (bool internal : {false, true}) { |
| 4504 | + for (OutputType t : OUTPUT_TYPES) { |
| 4505 | + auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this, internal)); |
| 4506 | + if (IsCrypted()) { |
| 4507 | + if (IsLocked()) { |
| 4508 | + throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors"); |
| 4509 | + } |
| 4510 | + if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) { |
| 4511 | + throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors"); |
| 4512 | + } |
4507 | 4513 | }
|
4508 |
| - if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) { |
4509 |
| - throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors"); |
| 4514 | + spk_manager->SetupDescriptorGeneration(master_key, t); |
| 4515 | + uint256 id = spk_manager->GetID(); |
| 4516 | + m_spk_managers[id] = std::move(spk_manager); |
| 4517 | + AddActiveScriptPubKeyMan(id, t, internal); |
| 4518 | + } |
| 4519 | + } |
| 4520 | + } else { |
| 4521 | +#ifdef ENABLE_EXTERNAL_SIGNER |
| 4522 | + ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner(); |
| 4523 | + |
| 4524 | + // TODO: add account parameter |
| 4525 | + int account = 0; |
| 4526 | + UniValue signer_res = signer.GetDescriptors(account); |
| 4527 | + |
| 4528 | + if (!signer_res.isObject()) throw std::runtime_error(std::string(__func__) + ": Unexpected result"); |
| 4529 | + for (bool internal : {false, true}) { |
| 4530 | + const UniValue& descriptor_vals = find_value(signer_res, internal ? "internal" : "receive"); |
| 4531 | + if (!descriptor_vals.isArray()) throw std::runtime_error(std::string(__func__) + ": Unexpected result"); |
| 4532 | + for (const UniValue& desc_val : descriptor_vals.get_array().getValues()) { |
| 4533 | + std::string desc_str = desc_val.getValStr(); |
| 4534 | + FlatSigningProvider keys; |
| 4535 | + std::string dummy_error; |
| 4536 | + std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, dummy_error, false); |
| 4537 | + if (!desc->GetOutputType()) { |
| 4538 | + continue; |
4510 | 4539 | }
|
| 4540 | + OutputType t = *desc->GetOutputType(); |
| 4541 | + auto spk_manager = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this, internal)); |
| 4542 | + spk_manager->SetupDescriptor(std::move(desc)); |
| 4543 | + uint256 id = spk_manager->GetID(); |
| 4544 | + m_spk_managers[id] = std::move(spk_manager); |
| 4545 | + AddActiveScriptPubKeyMan(id, t, internal); |
4511 | 4546 | }
|
4512 |
| - spk_manager->SetupDescriptorGeneration(master_key, t); |
4513 |
| - uint256 id = spk_manager->GetID(); |
4514 |
| - m_spk_managers[id] = std::move(spk_manager); |
4515 |
| - AddActiveScriptPubKeyMan(id, t, internal); |
4516 | 4547 | }
|
| 4548 | +#else |
| 4549 | + throw std::runtime_error(std::string(__func__) + ": Wallets with external signers require Boost::Process library."); |
| 4550 | +#endif |
4517 | 4551 | }
|
4518 | 4552 | }
|
4519 | 4553 |
|
|
0 commit comments