Add Sapling ExtFVK support to z_exportviewingkey

This commit is contained in:
Jack Grigg 2020-02-18 21:41:11 +00:00
parent 3c7385bc8e
commit a1d22b2d4a
3 changed files with 53 additions and 14 deletions

View File

@ -933,20 +933,11 @@ UniValue z_exportviewingkey(const UniValue& params, bool fHelp)
if (!IsValidPaymentAddress(address)) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
}
// TODO: Add Sapling support. For now, return an error to the user.
if (boost::get<libzcash::SproutPaymentAddress>(&address) == nullptr) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Currently, only Sprout zaddrs are supported");
}
auto addr = boost::get<libzcash::SproutPaymentAddress>(address);
libzcash::SproutViewingKey vk;
if (!pwalletMain->GetSproutViewingKey(addr, vk)) {
libzcash::SproutSpendingKey k;
if (!pwalletMain->GetSproutSpendingKey(addr, k)) {
auto vk = boost::apply_visitor(GetViewingKeyForPaymentAddress(pwalletMain), address);
if (vk) {
return EncodeViewingKey(vk.get());
} else {
throw JSONRPCError(RPC_WALLET_ERROR, "Wallet does not hold private key or viewing key for this zaddr");
}
vk = k.viewing_key();
}
return EncodeViewingKey(vk);
}

View File

@ -5015,6 +5015,42 @@ bool PaymentAddressBelongsToWallet::operator()(const libzcash::InvalidEncoding&
return false;
}
boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const
{
libzcash::SproutViewingKey vk;
if (!m_wallet->GetSproutViewingKey(zaddr, vk)) {
libzcash::SproutSpendingKey k;
if (!m_wallet->GetSproutSpendingKey(zaddr, k)) {
return boost::none;
}
vk = k.viewing_key();
}
return libzcash::ViewingKey(vk);
}
boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
libzcash::SaplingExtendedFullViewingKey extfvk;
if (m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
m_wallet->GetSaplingFullViewingKey(ivk, extfvk))
{
return libzcash::ViewingKey(extfvk);
} else {
return boost::none;
}
}
boost::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::InvalidEncoding& no) const
{
// Defaults to InvalidEncoding
return libzcash::ViewingKey();
}
bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return m_wallet->HaveSproutSpendingKey(zaddr);

View File

@ -1453,6 +1453,18 @@ public:
bool operator()(const libzcash::InvalidEncoding& no) const;
};
class GetViewingKeyForPaymentAddress : public boost::static_visitor<boost::optional<libzcash::ViewingKey>>
{
private:
CWallet *m_wallet;
public:
GetViewingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
boost::optional<libzcash::ViewingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
boost::optional<libzcash::ViewingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
boost::optional<libzcash::ViewingKey> operator()(const libzcash::InvalidEncoding& no) const;
};
class HaveSpendingKeyForPaymentAddress : public boost::static_visitor<bool>
{
private: