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