@@ -970,6 +970,19 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
970970 UniValue result (UniValue::VOBJ);
971971
972972 try {
973+ const bool internal = data.exists (" internal" ) ? data[" internal" ].get_bool () : false ;
974+ // Internal addresses should not have a label
975+ if (internal && data.exists (" label" )) {
976+ throw JSONRPCError (RPC_INVALID_PARAMETER, " Internal addresses should not have a label" );
977+ }
978+ const std::string& label = data.exists (" label" ) ? data[" label" ].get_str () : " " ;
979+
980+ ImportData import_data;
981+ std::map<CKeyID, CPubKey> pubkey_map;
982+ std::map<CKeyID, CKey> privkey_map;
983+ std::set<CScript> script_pub_keys;
984+ bool have_solving_data;
985+
973986 // First ensure scriptPubKey has either a script or JSON with "address" string
974987 const UniValue& scriptPubKey = data[" scriptPubKey" ];
975988 bool isScript = scriptPubKey.getType () == UniValue::VSTR;
@@ -983,9 +996,7 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
983996 const std::string& witness_script_hex = data.exists (" witnessscript" ) ? data[" witnessscript" ].get_str () : " " ;
984997 const UniValue& pubKeys = data.exists (" pubkeys" ) ? data[" pubkeys" ].get_array () : UniValue ();
985998 const UniValue& keys = data.exists (" keys" ) ? data[" keys" ].get_array () : UniValue ();
986- const bool internal = data.exists (" internal" ) ? data[" internal" ].get_bool () : false ;
987999 const bool watchOnly = data.exists (" watchonly" ) ? data[" watchonly" ].get_bool () : false ;
988- const std::string& label = data.exists (" label" ) ? data[" label" ].get_str () : " " ;
9891000
9901001 // If private keys are disabled, abort if private keys are being imported
9911002 if (pwallet->IsWalletFlagSet (WALLET_FLAG_DISABLE_PRIVATE_KEYS) && !keys.isNull ()) {
@@ -1011,9 +1022,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
10111022 throw JSONRPCError (RPC_INVALID_PARAMETER, " Internal must be set to true for nonstandard scriptPubKey imports." );
10121023 }
10131024 }
1025+ script_pub_keys.emplace (script);
10141026
10151027 // Parse all arguments
1016- ImportData import_data;
10171028 if (strRedeemScript.size ()) {
10181029 if (!IsHex (strRedeemScript)) {
10191030 throw JSONRPCError (RPC_INVALID_ADDRESS_OR_KEY, " Invalid redeem script \" " + strRedeemScript + " \" : must be hex string" );
@@ -1028,7 +1039,6 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
10281039 auto parsed_witnessscript = ParseHex (witness_script_hex);
10291040 import_data.witnessscript = MakeUnique<CScript>(parsed_witnessscript.begin (), parsed_witnessscript.end ());
10301041 }
1031- std::map<CKeyID, CPubKey> pubkey_map;
10321042 for (size_t i = 0 ; i < pubKeys.size (); ++i) {
10331043 const auto & str = pubKeys[i].get_str ();
10341044 if (!IsHex (str)) {
@@ -1041,7 +1051,6 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
10411051 }
10421052 pubkey_map.emplace (pubkey.GetID (), pubkey);
10431053 }
1044- std::map<CKeyID, CKey> privkey_map;
10451054 for (size_t i = 0 ; i < keys.size (); ++i) {
10461055 const auto & str = keys[i].get_str ();
10471056 CKey key = DecodeSecret (str);
@@ -1056,13 +1065,9 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
10561065 privkey_map.emplace (id, key);
10571066 }
10581067
1059- // Internal addresses should not have a label
1060- if (internal && data.exists (" label" )) {
1061- throw JSONRPCError (RPC_INVALID_PARAMETER, " Internal addresses should not have a label" );
1062- }
10631068
10641069 // Verify and process input data
1065- bool have_solving_data = import_data.redeemscript || import_data.witnessscript || pubkey_map.size () || privkey_map.size ();
1070+ have_solving_data = import_data.redeemscript || import_data.witnessscript || pubkey_map.size () || privkey_map.size ();
10661071 if (have_solving_data) {
10671072 // Match up data in import_data with the scriptPubKey in script.
10681073 auto error = RecurseImportData (script, import_data, ScriptContext::TOP);
@@ -1115,8 +1120,10 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
11151120 }
11161121
11171122 // Check whether we have any work to do
1118- if (::IsMine (*pwallet, script) & ISMINE_SPENDABLE) {
1119- throw JSONRPCError (RPC_WALLET_ERROR, " The wallet already contains the private key for this address or script" );
1123+ for (const CScript& script : script_pub_keys) {
1124+ if (::IsMine (*pwallet, script) & ISMINE_SPENDABLE) {
1125+ throw JSONRPCError (RPC_WALLET_ERROR, " The wallet already contains the private key for this address or script" );
1126+ }
11201127 }
11211128
11221129 // All good, time to import
@@ -1146,14 +1153,19 @@ static UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, con
11461153 throw JSONRPCError (RPC_WALLET_ERROR, " Error adding address to wallet" );
11471154 }
11481155 }
1149- if (!have_solving_data || !::IsMine (*pwallet, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1150- if (!pwallet->AddWatchOnly (script, timestamp)) {
1151- throw JSONRPCError (RPC_WALLET_ERROR, " Error adding address to wallet" );
1156+
1157+ for (const CScript& script : script_pub_keys) {
1158+ if (!have_solving_data || !::IsMine (*pwallet, script)) { // Always call AddWatchOnly for non-solvable watch-only, so that watch timestamp gets updated
1159+ if (!pwallet->AddWatchOnly (script, timestamp)) {
1160+ throw JSONRPCError (RPC_WALLET_ERROR, " Error adding address to wallet" );
1161+ }
1162+ }
1163+ CTxDestination dest;
1164+ ExtractDestination (script, dest);
1165+ if (!internal) {
1166+ assert (IsValidDestination (dest));
1167+ pwallet->SetAddressBook (dest, label, " receive" );
11521168 }
1153- }
1154- if (!internal) {
1155- assert (IsValidDestination (dest));
1156- pwallet->SetAddressBook (dest, label, " receive" );
11571169 }
11581170
11591171 result.pushKV (" success" , UniValue (true ));
0 commit comments