| 3671 | } |
| 3672 | |
| 3673 | void CWallet::SetupDescriptorScriptPubKeyMans() |
| 3674 | { |
| 3675 | AssertLockHeld(cs_wallet); |
| 3676 | |
| 3677 | if (!IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER)) { |
| 3678 | // Make a seed |
| 3679 | CKey seed_key; |
| 3680 | seed_key.MakeNewKey(true); |
| 3681 | CPubKey seed = seed_key.GetPubKey(); |
| 3682 | assert(seed_key.VerifyPubKey(seed)); |
| 3683 | |
| 3684 | // Get the extended key |
| 3685 | CExtKey master_key; |
| 3686 | master_key.SetSeed(seed_key); |
| 3687 | |
| 3688 | for (bool internal : {false, true}) { |
| 3689 | for (OutputType t : OUTPUT_TYPES) { |
| 3690 | auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this)); |
| 3691 | if (IsCrypted()) { |
| 3692 | if (IsLocked()) { |
| 3693 | throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors"); |
| 3694 | } |
| 3695 | if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) { |
| 3696 | throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors"); |
| 3697 | } |
| 3698 | } |
| 3699 | spk_manager->SetupDescriptorGeneration(master_key, t, internal); |
| 3700 | uint256 id = spk_manager->GetID(); |
| 3701 | m_spk_managers[id] = std::move(spk_manager); |
| 3702 | AddActiveScriptPubKeyMan(id, t, internal); |
| 3703 | } |
| 3704 | } |
| 3705 | } else { |
| 3706 | ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner(); |
| 3707 | |
| 3708 | // TODO: add account parameter |
| 3709 | int account = 0; |
| 3710 | UniValue signer_res = signer.GetDescriptors(account); |
| 3711 | |
| 3712 | if (!signer_res.isObject()) throw std::runtime_error(std::string(__func__) + ": Unexpected result"); |
| 3713 | for (bool internal : {false, true}) { |
| 3714 | const UniValue& descriptor_vals = find_value(signer_res, internal ? "internal" : "receive"); |
| 3715 | if (!descriptor_vals.isArray()) throw std::runtime_error(std::string(__func__) + ": Unexpected result"); |
| 3716 | for (const UniValue& desc_val : descriptor_vals.get_array().getValues()) { |
| 3717 | std::string desc_str = desc_val.getValStr(); |
| 3718 | FlatSigningProvider keys; |
| 3719 | std::string desc_error; |
| 3720 | std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, desc_error, false); |
| 3721 | if (desc == nullptr) { |
| 3722 | throw std::runtime_error(std::string(__func__) + ": Invalid descriptor \"" + desc_str + "\" (" + desc_error + ")"); |
| 3723 | } |
| 3724 | if (!desc->GetOutputType()) { |
| 3725 | continue; |
| 3726 | } |
| 3727 | OutputType t = *desc->GetOutputType(); |
| 3728 | auto spk_manager = std::unique_ptr<ExternalSignerScriptPubKeyMan>(new ExternalSignerScriptPubKeyMan(*this)); |
| 3729 | spk_manager->SetupDescriptor(std::move(desc)); |
| 3730 | uint256 id = spk_manager->GetID(); |