|
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