Skip to content

Commit 8ec1875

Browse files
committed
[RPC] Add shield address support to getaddressinfo
1 parent 501782a commit 8ec1875

File tree

1 file changed

+42
-18
lines changed

1 file changed

+42
-18
lines changed

src/wallet/rpcwallet.cpp

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,11 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
143143
"getaddressinfo ( \"address\" )\n"
144144
"\nReturn information about the given PIVX address.\n"
145145
"Some of the information will only be present if the address is in the active wallet.\n"
146+
"Metadata for shield addresses is available only if the wallet is unlocked.\n"
146147
"{Result:\n"
147148
" \"address\" : \"address\", (string) The bitcoin address validated.\n"
148-
" \"scriptPubKey\" : \"hex\", (string) The hex-encoded scriptPubKey generated by the address.\n"
149+
" \"isshield\" : true|false, (boolean) If the address is shield or transparent.\n"
150+
" \"scriptPubKey\" : \"hex\", (string, only if isshield=false) The hex-encoded scriptPubKey generated by the address.\n"
149151
" \"ismine\" : true|false, (boolean) If the address is yours.\n"
150152
" \"iswatchonly\" : true|false, (boolean) If the address is watchonly.\n"
151153
" \"label\" : \"label\" (string) The label associated with the address, \"\" is the default label.\n"
@@ -169,23 +171,26 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
169171

170172
LOCK(pwallet->cs_wallet);
171173

174+
const std::string& strAdd = request.params[0].get_str();
172175
UniValue ret(UniValue::VOBJ);
176+
ret.pushKV("address", strAdd);
173177

174-
CTxDestination dest = DecodeDestination(request.params[0].get_str());
178+
const CWDestination& dest = Standard::DecodeDestination(strAdd);
175179
// Make sure the destination is valid
176-
if (!IsValidDestination(dest)) {
180+
if (!Standard::IsValidDestination(dest)) {
177181
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
178182
}
179183

180-
std::string currentAddress = request.params[0].get_str();
181-
ret.pushKV("address", currentAddress);
184+
const CTxDestination* pTransDest = Standard::GetTransparentDestination(dest);
185+
ret.pushKV("isshield", pTransDest == nullptr);
182186

183-
CScript scriptPubKey = GetScriptForDestination(dest);
184-
ret.pushKV("scriptPubKey", HexStr(scriptPubKey.begin(), scriptPubKey.end()));
187+
if (pTransDest) {
188+
ret.pushKV("scriptPubKey", HexStr(GetScriptForDestination(*pTransDest)));
189+
}
185190

186191
isminetype mine = IsMine(*pwallet, dest);
187192
ret.pushKV("ismine", bool(mine & ISMINE_SPENDABLE_ALL));
188-
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY));
193+
ret.pushKV("iswatchonly", bool(mine & ISMINE_WATCH_ONLY_ALL));
189194

190195
// Return label field if existing. Currently only one label can be
191196
// associated with an address, so the label should be equivalent to the
@@ -198,20 +203,39 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
198203
//ret.pushKV("ischange", pwallet->IsChange(scriptPubKey));
199204

200205
ScriptPubKeyMan* spk_man = pwallet->GetScriptPubKeyMan();
201-
if (spk_man) {
202-
CKeyID* keyID = boost::get<CKeyID>(&dest);
206+
SaplingScriptPubKeyMan* sspk_man = pwalletMain->GetSaplingScriptPubKeyMan();
207+
CKeyMetadata* meta = nullptr;
208+
209+
if (spk_man && pTransDest) {
210+
// transparent destination
211+
const CKeyID* keyID = boost::get<CKeyID>(pTransDest);
203212
if (keyID) {
204-
std::map<CKeyID, CKeyMetadata>::iterator it = pwallet->mapKeyMetadata.find(*keyID);
213+
auto it = pwallet->mapKeyMetadata.find(*keyID);
205214
if(it != pwallet->mapKeyMetadata.end()) {
206-
const CKeyMetadata& meta = it->second;
207-
ret.pushKV("timestamp", meta.nCreateTime);
208-
if (meta.HasKeyOrigin()) {
209-
ret.pushKV("hdkeypath", meta.key_origin.pathToString());
210-
ret.pushKV("hdseedid", meta.hd_seed_id.GetHex());
211-
ret.pushKV("hdmasterfingerprint", HexStr(meta.key_origin.fingerprint, meta.key_origin.fingerprint + 4));
212-
}
215+
meta = &it->second;
213216
}
214217
}
218+
} else if (sspk_man && !pTransDest) {
219+
// shield destination
220+
const libzcash::SaplingPaymentAddress pa = *Standard::GetShieldedDestination(dest);
221+
libzcash::SaplingExtendedSpendingKey extsk;
222+
if (pwalletMain->GetSaplingExtendedSpendingKey(pa, extsk)) {
223+
const auto& ivk = extsk.expsk.full_viewing_key().in_viewing_key();
224+
auto it = sspk_man->mapSaplingZKeyMetadata.find(ivk);
225+
if (it != sspk_man->mapSaplingZKeyMetadata.end()) {
226+
meta = &it->second;
227+
}
228+
}
229+
}
230+
231+
// Add metadata
232+
if (meta) {
233+
ret.pushKV("timestamp", meta->nCreateTime);
234+
if (meta->HasKeyOrigin()) {
235+
ret.pushKV("hdkeypath", meta->key_origin.pathToString());
236+
ret.pushKV("hdseedid", meta->hd_seed_id.GetHex());
237+
ret.pushKV("hdmasterfingerprint", HexStr(meta->key_origin.fingerprint, meta->key_origin.fingerprint + 4));
238+
}
215239
}
216240

217241
// Return a `labels` array containing the label associated with the address,

0 commit comments

Comments
 (0)