@@ -1403,6 +1403,16 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
1403
1403
if (params[2 ].get_bool ())
1404
1404
filter = filter | ISMINE_WATCH_ONLY;
1405
1405
1406
+ bool has_filtered_address = false ;
1407
+ CTxDestination filtered_address = CNoDestination ();
1408
+ if (!fByAccounts && params.size () > 3 ) {
1409
+ if (!IsValidDestinationString (params[3 ].get_str ())) {
1410
+ throw JSONRPCError (RPC_WALLET_ERROR, " address_filter parameter was invalid" );
1411
+ }
1412
+ filtered_address = DecodeDestination (params[3 ].get_str ());
1413
+ has_filtered_address = true ;
1414
+ }
1415
+
1406
1416
// Tally
1407
1417
std::map<CTxDestination, tallyitem> mapTally;
1408
1418
for (const std::pair<uint256, CWalletTx>& pairWtx : pwallet->mapWallet ) {
@@ -1421,6 +1431,10 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
1421
1431
if (!ExtractDestination (txout.scriptPubKey , address))
1422
1432
continue ;
1423
1433
1434
+ if (has_filtered_address && !(filtered_address == address)) {
1435
+ continue ;
1436
+ }
1437
+
1424
1438
isminefilter mine = IsMine (*pwallet, address);
1425
1439
if (!(mine & filter))
1426
1440
continue ;
@@ -1437,10 +1451,24 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
1437
1451
// Reply
1438
1452
UniValue ret (UniValue::VARR);
1439
1453
std::map<std::string, tallyitem> mapAccountTally;
1440
- for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook ) {
1441
- const CTxDestination& dest = item.first ;
1442
- const std::string& strAccount = item.second .name ;
1443
- std::map<CTxDestination, tallyitem>::iterator it = mapTally.find (dest);
1454
+
1455
+ // Create mapAddressBook iterator
1456
+ // If we aren't filtering, go from begin() to end()
1457
+ auto start = pwallet->mapAddressBook .begin ();
1458
+ auto end = pwallet->mapAddressBook .end ();
1459
+ // If we are filtering, find() the applicable entry
1460
+ if (has_filtered_address) {
1461
+ start = pwallet->mapAddressBook .find (filtered_address);
1462
+ if (start != end) {
1463
+ end = std::next (start);
1464
+ }
1465
+ }
1466
+
1467
+ for (auto item_it = start; item_it != end; ++item_it)
1468
+ {
1469
+ const CTxDestination& address = item_it->first ;
1470
+ const std::string& strAccount = item_it->second .name ;
1471
+ auto it = mapTally.find (address);
1444
1472
if (it == mapTally.end () && !fIncludeEmpty )
1445
1473
continue ;
1446
1474
@@ -1466,7 +1494,7 @@ UniValue ListReceived(CWallet * const pwallet, const UniValue& params, bool fByA
1466
1494
UniValue obj (UniValue::VOBJ);
1467
1495
if (fIsWatchonly )
1468
1496
obj.pushKV (" involvesWatchonly" , true );
1469
- obj.pushKV (" address" , EncodeDestination (dest ));
1497
+ obj.pushKV (" address" , EncodeDestination (address ));
1470
1498
obj.pushKV (" account" , strAccount);
1471
1499
obj.pushKV (" amount" , ValueFromAmount (nAmount));
1472
1500
obj.pushKV (" confirmations" , (nConf == std::numeric_limits<int >::max () ? 0 : nConf));
@@ -1511,15 +1539,15 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
1511
1539
return NullUniValue;
1512
1540
}
1513
1541
1514
- if (request.fHelp || request.params .size () > 3 )
1542
+ if (request.fHelp || request.params .size () > 4 )
1515
1543
throw std::runtime_error (
1516
- " listreceivedbyaddress ( minconf include_empty include_watchonly)\n "
1544
+ " listreceivedbyaddress ( minconf include_empty include_watchonly address_filter )\n "
1517
1545
" \n List balances by receiving address.\n "
1518
1546
" \n Arguments:\n "
1519
1547
" 1. minconf (numeric, optional, default=1) The minimum number of confirmations before payments are included.\n "
1520
1548
" 2. include_empty (bool, optional, default=false) Whether to include addresses that haven't received any payments.\n "
1521
1549
" 3. include_watchonly (bool, optional, default=false) Whether to include watch-only addresses (see 'importaddress').\n "
1522
-
1550
+ " 4. address_filter (string, optional) If present, only return information on this address. \n "
1523
1551
" \n Result:\n "
1524
1552
" [\n "
1525
1553
" {\n "
@@ -1541,6 +1569,7 @@ UniValue listreceivedbyaddress(const JSONRPCRequest& request)
1541
1569
+ HelpExampleCli (" listreceivedbyaddress" , " " )
1542
1570
+ HelpExampleCli (" listreceivedbyaddress" , " 6 true" )
1543
1571
+ HelpExampleRpc (" listreceivedbyaddress" , " 6, true, true" )
1572
+ + HelpExampleRpc (" listreceivedbyaddress" , " 6, true, true, \" 1M72Sfpbz1BPpXFHz9m3CdqATR44Jvaydd\" " )
1544
1573
);
1545
1574
1546
1575
ObserveSafeMode ();
@@ -3837,7 +3866,7 @@ static const CRPCCommand commands[] =
3837
3866
{ " wallet" , " listaddressgroupings" , &listaddressgroupings, {} },
3838
3867
{ " wallet" , " listlockunspent" , &listlockunspent, {} },
3839
3868
{ " wallet" , " listreceivedbyaccount" , &listreceivedbyaccount, {" minconf" ," include_empty" ," include_watchonly" } },
3840
- { " wallet" , " listreceivedbyaddress" , &listreceivedbyaddress, {" minconf" ," include_empty" ," include_watchonly" } },
3869
+ { " wallet" , " listreceivedbyaddress" , &listreceivedbyaddress, {" minconf" ," include_empty" ," include_watchonly" , " address_filter " } },
3841
3870
{ " wallet" , " listsinceblock" , &listsinceblock, {" blockhash" ," target_confirmations" ," include_watchonly" ," include_removed" } },
3842
3871
{ " wallet" , " listtransactions" , &listtransactions, {" account" ," count" ," skip" ," include_watchonly" } },
3843
3872
{ " wallet" , " listunspent" , &listunspent, {" minconf" ," maxconf" ," addresses" ," include_unsafe" ," query_options" } },
0 commit comments