@@ -1063,28 +1063,35 @@ static UniValue ProcessImportLegacy(ImportData& import_data, std::map<CKeyID, CP
10631063
10641064static 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)
10651065{
1066- const bool internal = data.exists (" internal" ) ? data[" internal" ].get_bool () : false ;
1067-
10681066 UniValue warnings (UniValue::VARR);
10691067
10701068 const std::string& descriptor = data[" desc" ].get_str ();
10711069 FlatSigningProvider keys;
10721070 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 ) {
10751073 throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, error);
10761074 }
1077- if (parsed_desc ->GetOutputType () == OutputType::BECH32M) {
1075+ if (parsed_descs. first ->GetOutputType () == OutputType::BECH32M) {
10781076 throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Bech32m descriptors cannot be imported into legacy wallets" );
10791077 }
10801078
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 ();
10821089 const bool watch_only = data.exists (" watchonly" ) ? data[" watchonly" ].get_bool () : false ;
10831090
10841091 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" )) {
10861093 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 ()) {
10881095 if (!data.exists (" range" )) {
10891096 throw JSONRPCError (RPC_INVALID_PARAMETER, " Descriptor is ranged, please specify the range" );
10901097 }
@@ -1093,25 +1100,28 @@ static UniValue ProcessImportDescriptor(ImportData& import_data, std::map<CKeyID
10931100
10941101 const UniValue& priv_keys = data.exists (" keys" ) ? data[" keys" ].get_array () : UniValue ();
10951102
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+ }
11051114
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+ }
11091118
1110- parsed_desc->ExpandPrivate (i, keys, out_keys);
1119+ parsed_desc->ExpandPrivate (i, keys, out_keys);
11111120
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+ }
11151125 }
11161126
11171127 for (size_t i = 0 ; i < priv_keys.size (); ++i) {
0 commit comments