git / moonbite-core / src/mweb/mweb_wallet.h · raw

#pragma once#include <amount.h>#include <key.h>#include <mw/models/block/Block.h>#include <mw/models/tx/Transaction.h>#include <mw/models/wallet/Coin.h>#include <mw/models/wallet/StealthAddress.h>#include <mw/wallet/Keychain.h>#include <streams.h>#include <util/strencodings.h>#include <boost/optional.hpp>#include <boost/variant.hpp>#include <map>#include <set>class CWallet;namespace MWEB {class Wallet{    CWallet* m_pWallet;    std::map<mw::Hash, mw::Coin> m_coins;public:    Wallet(CWallet* pWallet)        : m_pWallet(pWallet) {}    bool IsChange(const StealthAddress& address) const;    bool GetCoin(const mw::Hash& output_id, mw::Coin& coin) const;    // Loops through the transactions in the wallet and attempts to fill    // in missing information for mw::Coin's, in particular the spend key.    // Intended to be called after unlocking an encrypted wallet.    bool UpgradeCoins();    std::vector<mw::Coin> RewindOutputs(const CTransaction& tx);    bool RewindOutput(const Output& output, mw::Coin& coin);    bool GetStealthAddress(const mw::Coin& coin, StealthAddress& address) const;    bool GetStealthAddress(const uint32_t index, StealthAddress& address) const;    void LoadToWallet(const mw::Coin& coin);    void SaveToWallet(const std::vector<mw::Coin>& coins);private:    mw::Keychain::Ptr GetKeychain() const;};struct WalletTxInfo{    // When connecting a block, if an output is found that belongs to us,    // we check if we have a CWalletTx that created it.    // If none is found, then we assume it is a newly received coin,    // so we create an empty transaction and store the received coin here.    boost::optional<mw::Coin> received_coin;    // When connecting a block, if one of the wallet's coins is spent,    // we check if we have a CWalletTx that spent it.    // If none is found, then we assume it was spent by another wallet,    // so we create an empty Transaction and store the spent hash here.    boost::optional<mw::Hash> spent_input;    mutable uint256 hash;    WalletTxInfo()        : received_coin(boost::none), spent_input(boost::none), hash() { }    WalletTxInfo(mw::Coin received)        : received_coin(std::move(received)), spent_input(boost::none), hash(received_coin->output_id.vec()) {}    WalletTxInfo(mw::Hash spent)        : received_coin(boost::none), spent_input(std::move(spent)), hash(spent_input->vec()) {}    SERIALIZE_METHODS(WalletTxInfo, obj)    {        bool received = !!obj.received_coin;        READWRITE(received);        if (received) {            mw::Coin coin;            SER_WRITE(obj, coin = *obj.received_coin);            READWRITE(coin);            SER_READ(obj, obj.hash = uint256(coin.output_id.vec()));            SER_READ(obj, obj.received_coin = boost::make_optional<mw::Coin>(std::move(coin)));        } else {            mw::Hash output_id;            SER_WRITE(obj, output_id = *obj.spent_input);            READWRITE(output_id);            SER_READ(obj, obj.hash = uint256(output_id.vec()));            SER_READ(obj, obj.spent_input = boost::make_optional<mw::Hash>(std::move(output_id)));        }    }    static WalletTxInfo FromHex(const std::string& str)    {        std::vector<uint8_t> bytes = ParseHex(str);        CDataStream stream((const char*)bytes.data(), (const char*)bytes.data() + bytes.size(), SER_DISK, PROTOCOL_VERSION);        WalletTxInfo wtx_info;        stream >> wtx_info;        return wtx_info;    }    std::string ToHex() const    {        CDataStream stream(SER_DISK, PROTOCOL_VERSION);        stream << *this;        return HexStr(std::vector<uint8_t>{stream.begin(), stream.end()});    }    const uint256& GetHash() const {        return hash;    }};} // namespace MWEB