@@ -1056,8 +1056,6 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
1056
1056
1057
1057
static UniValue ProcessImportDescriptor (ImportData& import_data, std::map<CKeyID, CPubKey>& pubkey_map, std::map<CKeyID, CKey>& privkey_map, std::set<CScript>& script_pub_keys, bool & have_solving_data, const UniValue& data, std::vector<std::pair<CKeyID, bool >>& ordered_pubkeys)
1058
1058
{
1059
- const bool internal = data.exists (" internal" ) ? data[" internal" ].get_bool () : false ;
1060
-
1061
1059
UniValue warnings (UniValue::VARR);
1062
1060
1063
1061
const std::string& descriptor = data[" desc" ].get_str ();
@@ -1067,18 +1065,25 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
1067
1065
if (parsed_descs.empty ()) {
1068
1066
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, error);
1069
1067
}
1070
- const auto & parsed_desc = parsed_descs.at (0 );
1071
- if (parsed_desc->GetOutputType () == OutputType::BECH32M) {
1068
+ if (parsed_descs.at (0 )->GetOutputType () == OutputType::BECH32M) {
1072
1069
throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Bech32m descriptors cannot be imported into legacy wallets" );
1073
1070
}
1074
1071
1075
- have_solving_data = parsed_desc->IsSolvable ();
1072
+ std::optional<bool > internal;
1073
+ if (data.exists (" internal" )) {
1074
+ if (parsed_descs.size () > 1 ) {
1075
+ throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Cannot have multipath descriptor while also specifying \' internal\' " );
1076
+ }
1077
+ internal = data[" internal" ].get_bool ();
1078
+ }
1079
+
1080
+ have_solving_data = parsed_descs.at (0 )->IsSolvable ();
1076
1081
const bool watch_only = data.exists (" watchonly" ) ? data[" watchonly" ].get_bool () : false ;
1077
1082
1078
1083
int64_t range_start = 0 , range_end = 0 ;
1079
- if (!parsed_desc ->IsRange () && data.exists (" range" )) {
1084
+ if (!parsed_descs. at ( 0 ) ->IsRange () && data.exists (" range" )) {
1080
1085
throw JSONRPCError (RPC_INVALID_PARAMETER, " Range should not be specified for an un-ranged descriptor" );
1081
- } else if (parsed_desc ->IsRange ()) {
1086
+ } else if (parsed_descs. at ( 0 ) ->IsRange ()) {
1082
1087
if (!data.exists (" range" )) {
1083
1088
throw JSONRPCError (RPC_INVALID_PARAMETER, " Descriptor is ranged, please specify the range" );
1084
1089
}
@@ -1087,25 +1092,34 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
1087
1092
1088
1093
const UniValue& priv_keys = data.exists (" keys" ) ? data[" keys" ].get_array () : UniValue ();
1089
1094
1090
- // Expand all descriptors to get public keys and scripts, and private keys if available.
1091
- for (int i = range_start; i <= range_end; ++i) {
1092
- FlatSigningProvider out_keys;
1093
- std::vector<CScript> scripts_temp;
1094
- parsed_desc->Expand (i, keys, scripts_temp, out_keys);
1095
- std::copy (scripts_temp.begin (), scripts_temp.end (), std::inserter (script_pub_keys, script_pub_keys.end ()));
1096
- for (const auto & key_pair : out_keys.pubkeys ) {
1097
- ordered_pubkeys.emplace_back (key_pair.first , internal);
1098
- }
1095
+ for (size_t j = 0 ; j < parsed_descs.size (); ++j) {
1096
+ const auto & parsed_desc = parsed_descs.at (j);
1097
+ bool desc_internal = internal.has_value () && internal.value ();
1098
+ if (parsed_descs.size () == 2 ) {
1099
+ desc_internal = j == 1 ;
1100
+ } else if (parsed_descs.size () > 2 ) {
1101
+ CHECK_NONFATAL (!desc_internal);
1102
+ }
1103
+ // Expand all descriptors to get public keys and scripts, and private keys if available.
1104
+ for (int i = range_start; i <= range_end; ++i) {
1105
+ FlatSigningProvider out_keys;
1106
+ std::vector<CScript> scripts_temp;
1107
+ parsed_desc->Expand (i, keys, scripts_temp, out_keys);
1108
+ std::copy (scripts_temp.begin (), scripts_temp.end (), std::inserter (script_pub_keys, script_pub_keys.end ()));
1109
+ for (const auto & key_pair : out_keys.pubkeys ) {
1110
+ ordered_pubkeys.emplace_back (key_pair.first , desc_internal);
1111
+ }
1099
1112
1100
- for (const auto & x : out_keys.scripts ) {
1101
- import_data.import_scripts .emplace (x.second );
1102
- }
1113
+ for (const auto & x : out_keys.scripts ) {
1114
+ import_data.import_scripts .emplace (x.second );
1115
+ }
1103
1116
1104
- parsed_desc->ExpandPrivate (i, keys, out_keys);
1117
+ parsed_desc->ExpandPrivate (i, keys, out_keys);
1105
1118
1106
- std::copy (out_keys.pubkeys .begin (), out_keys.pubkeys .end (), std::inserter (pubkey_map, pubkey_map.end ()));
1107
- std::copy (out_keys.keys .begin (), out_keys.keys .end (), std::inserter (privkey_map, privkey_map.end ()));
1108
- import_data.key_origins .insert (out_keys.origins .begin (), out_keys.origins .end ());
1119
+ std::copy (out_keys.pubkeys .begin (), out_keys.pubkeys .end (), std::inserter (pubkey_map, pubkey_map.end ()));
1120
+ std::copy (out_keys.keys .begin (), out_keys.keys .end (), std::inserter (privkey_map, privkey_map.end ()));
1121
+ import_data.key_origins .insert (out_keys.origins .begin (), out_keys.origins .end ());
1122
+ }
1109
1123
}
1110
1124
1111
1125
for (size_t i = 0 ; i < priv_keys.size (); ++i) {
0 commit comments