1 // Copyright (c) 2016 The Zcash developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #ifndef ASYNCRPCOPERATION_SENDMANY_H
6 #define ASYNCRPCOPERATION_SENDMANY_H
8 #include "asyncrpcoperation.h"
11 #include "primitives/transaction.h"
12 #include "zcash/JoinSplit.hpp"
13 #include "zcash/Address.hpp"
15 #include "paymentdisclosure.h"
17 #include <unordered_map>
22 // Default transaction fee if caller does not specify one.
23 #define ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE 10000
25 using namespace libzcash;
27 // A recipient is a tuple of address, amount, memo (optional if zaddr)
28 typedef std::tuple<std::string, CAmount, std::string> SendManyRecipient;
30 // Input UTXO is a tuple (quadruple) of txid, vout, amount, coinbase)
31 typedef std::tuple<uint256, int, CAmount, bool> SendManyInputUTXO;
33 // Input JSOP is a tuple of JSOutpoint, note and amount
34 typedef std::tuple<JSOutPoint, SproutNote, CAmount> SendManyInputJSOP;
36 // Package of info which is passed to perform_joinsplit methods.
37 struct AsyncJoinSplitInfo
39 std::vector<JSInput> vjsin;
40 std::vector<JSOutput> vjsout;
41 std::vector<SproutNote> notes;
46 // A struct to help us track the witness and anchor for a given JSOutPoint
47 struct WitnessAnchorData {
48 boost::optional<ZCIncrementalWitness> witness;
52 class AsyncRPCOperation_sendmany : public AsyncRPCOperation {
54 AsyncRPCOperation_sendmany(CMutableTransaction contextualTx, std::string fromAddress, std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue);
55 virtual ~AsyncRPCOperation_sendmany();
57 // We don't want to be copied or moved around
58 AsyncRPCOperation_sendmany(AsyncRPCOperation_sendmany const&) = delete; // Copy construct
59 AsyncRPCOperation_sendmany(AsyncRPCOperation_sendmany&&) = delete; // Move construct
60 AsyncRPCOperation_sendmany& operator=(AsyncRPCOperation_sendmany const&) = delete; // Copy assign
61 AsyncRPCOperation_sendmany& operator=(AsyncRPCOperation_sendmany &&) = delete; // Move assign
65 virtual UniValue getStatus() const;
67 bool testmode = false; // Set to true to disable sending txs and generating proofs
69 bool paymentDisclosureMode = false; // Set to true to save esk for encrypted notes in payment disclosure database.
72 friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing
74 UniValue contextinfo_; // optional data to include in return value from getStatus()
76 uint32_t consensusBranchId_;
79 std::string fromaddress_;
82 CBitcoinAddress fromtaddr_;
83 PaymentAddress frompaymentaddress_;
84 SpendingKey spendingkey_;
86 uint256 joinSplitPubKey_;
87 unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES];
89 // The key is the result string from calling JSOutPoint::ToString()
90 std::unordered_map<std::string, WitnessAnchorData> jsopWitnessAnchorMap;
92 std::vector<SendManyRecipient> t_outputs_;
93 std::vector<SendManyRecipient> z_outputs_;
94 std::vector<SendManyInputUTXO> t_inputs_;
95 std::vector<SendManyInputJSOP> z_inputs_;
99 void add_taddr_change_output_to_tx(CAmount amount);
100 void add_taddr_outputs_to_tx();
101 bool find_unspent_notes();
102 bool find_utxos(bool fAcceptCoinbase);
103 boost::array<unsigned char, ZC_MEMO_SIZE> get_memo_from_hex_string(std::string s);
106 // JoinSplit without any input notes to spend
107 UniValue perform_joinsplit(AsyncJoinSplitInfo &);
109 // JoinSplit with input notes to spend (JSOutPoints))
110 UniValue perform_joinsplit(AsyncJoinSplitInfo &, std::vector<JSOutPoint> & );
112 // JoinSplit where you have the witnesses and anchor
113 UniValue perform_joinsplit(
114 AsyncJoinSplitInfo & info,
115 std::vector<boost::optional < ZCIncrementalWitness>> witnesses,
118 void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error
120 // payment disclosure!
121 std::vector<PaymentDisclosureKeyInfo> paymentDisclosureData_;
125 // To test private methods, a friend class can act as a proxy
126 class TEST_FRIEND_AsyncRPCOperation_sendmany {
128 std::shared_ptr<AsyncRPCOperation_sendmany> delegate;
130 TEST_FRIEND_AsyncRPCOperation_sendmany(std::shared_ptr<AsyncRPCOperation_sendmany> ptr) : delegate(ptr) {}
132 CTransaction getTx() {
133 return delegate->tx_;
136 void setTx(CTransaction tx) {
142 void add_taddr_change_output_to_tx(CAmount amount) {
143 delegate->add_taddr_change_output_to_tx(amount);
146 void add_taddr_outputs_to_tx() {
147 delegate->add_taddr_outputs_to_tx();
150 bool find_unspent_notes() {
151 return delegate->find_unspent_notes();
154 bool find_utxos(bool fAcceptCoinbase) {
155 return delegate->find_utxos(fAcceptCoinbase);
158 boost::array<unsigned char, ZC_MEMO_SIZE> get_memo_from_hex_string(std::string s) {
159 return delegate->get_memo_from_hex_string(s);
163 return delegate->main_impl();
166 UniValue perform_joinsplit(AsyncJoinSplitInfo &info) {
167 return delegate->perform_joinsplit(info);
170 UniValue perform_joinsplit(AsyncJoinSplitInfo &info, std::vector<JSOutPoint> &v ) {
171 return delegate->perform_joinsplit(info, v);
174 UniValue perform_joinsplit(
175 AsyncJoinSplitInfo & info,
176 std::vector<boost::optional < ZCIncrementalWitness>> witnesses,
179 return delegate->perform_joinsplit(info, witnesses, anchor);
182 void sign_send_raw_transaction(UniValue obj) {
183 delegate->sign_send_raw_transaction(obj);
186 void set_state(OperationStatus state) {
187 delegate->state_.store(state);
192 #endif /* ASYNCRPCOPERATION_SENDMANY_H */