From 93d1aa9abc4402715f781db2bc26bdde4447e951 Mon Sep 17 00:00:00 2001
From: whythat <whythat@protonmail.com>
Date: Sat, 6 Oct 2018 00:24:06 +0300
Subject: [PATCH] rpcwallet: add 'ischange' field to 'getaddressinfo' response

---
 doc/release-notes-14282.md | 3 +++
 src/wallet/rpcwallet.cpp   | 2 ++
 src/wallet/wallet.cpp      | 9 +++++++--
 src/wallet/wallet.h        | 1 +
 4 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/doc/release-notes-14282.md b/doc/release-notes-14282.md
index e6d8e0b70..900ca0432 100644
--- a/doc/release-notes-14282.md
+++ b/doc/release-notes-14282.md
@@ -4,3 +4,6 @@ Low-level RPC changes
 `-usehd` was removed in version 0.16. From that version onwards, all new
 wallets created are hierarchical deterministic wallets. Version 0.18 makes
 specifying `-usehd` invalid config.
+
+`ischange` field of boolean type that shows if an address was used for change
+output was added to `getaddressinfo` method response.
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 7d0219201..00c809740 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -3540,6 +3540,7 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
             "  \"ismine\" : true|false,        (boolean) If the address is yours or not\n"
             "  \"iswatchonly\" : true|false,   (boolean) If the address is watchonly\n"
             "  \"isscript\" : true|false,      (boolean) If the key is a script\n"
+            "  \"ischange\" : true|false,      (boolean) If the address was used for change output\n"
             "  \"iswitness\" : true|false,     (boolean) If the address is a witness address\n"
             "  \"witness_version\" : version   (numeric, optional) The version number of the witness program\n"
             "  \"witness_program\" : \"hex\"     (string, optional) The hex value of the witness program\n"
@@ -3597,6 +3598,7 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
     if (pwallet->mapAddressBook.count(dest)) {
         ret.pushKV("label", pwallet->mapAddressBook[dest].name);
     }
+    ret.pushKV("ischange", pwallet->IsChange(scriptPubKey));
     const CKeyMetadata* meta = nullptr;
     CKeyID key_id = GetKeyForDestination(*pwallet, dest);
     if (!key_id.IsNull()) {
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp
index afe47d986..f37aa3211 100644
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -1261,6 +1261,11 @@ CAmount CWallet::GetCredit(const CTxOut& txout, const isminefilter& filter) cons
 }
 
 bool CWallet::IsChange(const CTxOut& txout) const
+{
+    return IsChange(txout.scriptPubKey);
+}
+
+bool CWallet::IsChange(const CScript& script) const
 {
     // TODO: fix handling of 'change' outputs. The assumption is that any
     // payment to a script that is ours, but is not in the address book
@@ -1269,10 +1274,10 @@ bool CWallet::IsChange(const CTxOut& txout) const
     // a better way of identifying which outputs are 'the send' and which are
     // 'the change' will need to be implemented (maybe extend CWalletTx to remember
     // which output, if any, was change).
-    if (::IsMine(*this, txout.scriptPubKey))
+    if (::IsMine(*this, script))
     {
         CTxDestination address;
-        if (!ExtractDestination(txout.scriptPubKey, address))
+        if (!ExtractDestination(script, address))
             return true;
 
         LOCK(cs_wallet);
diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h
index da326517c..64740fd82 100644
--- a/src/wallet/wallet.h
+++ b/src/wallet/wallet.h
@@ -961,6 +961,7 @@ public:
     isminetype IsMine(const CTxOut& txout) const;
     CAmount GetCredit(const CTxOut& txout, const isminefilter& filter) const;
     bool IsChange(const CTxOut& txout) const;
+    bool IsChange(const CScript& script) const;
     CAmount GetChange(const CTxOut& txout) const;
     bool IsMine(const CTransaction& tx) const;
     /** should probably be renamed to IsRelevantToMe */