text: // Copyright (c) 2012-2017, The CryptoNote developers, The Bytecoin developers
  // Copyright (c) 2018, The TurtleCoin Developers
  // Copyright (c) 2018, The Karai Developers
  //
  // Please see the included LICENSE file for more information.
  
  #pragma once
  
  #include "CryptoNoteProtocol/CryptoNoteProtocolDefinitions.h"
  #include "CryptoNoteCore/CryptoNoteBasic.h"
  #include "CryptoNoteCore/Difficulty.h"
  #include "crypto/hash.h"
  
  #include "BlockchainExplorerData.h"
  
  #include "Serialization/SerializationOverloads.h"
  #include "Serialization/BlockchainExplorerDataSerialization.h"
  #include <CryptoNoteCore/ICoreDefinitions.h>
  
  #include <WalletTypes.h>
  
  namespace CryptoNote {
  //-----------------------------------------------
  #define CORE_RPC_STATUS_OK "OK"
  #define CORE_RPC_STATUS_BUSY "BUSY"
  
  struct EMPTY_STRUCT {
    void serialize(ISerializer &s) {}
  };
  
  struct STATUS_STRUCT {
    std::string status;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(status)
    }
  };
  
  //Merged Mining Fix
  struct STATUS_STRUCT_EX {
     std::string status;
     std::string data;
  
      void serialize(ISerializer &s) {
       KV_MEMBER(status)
       KV_MEMBER(data)
     }
   };
  
  struct COMMAND_RPC_GET_HEIGHT {
    typedef EMPTY_STRUCT request;
  
    struct response {
      uint64_t height;
      uint32_t network_height;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(height)
        KV_MEMBER(network_height)
        KV_MEMBER(status)
      }
    };
  };
  
  struct COMMAND_RPC_GET_BLOCKS_FAST {
  
    struct request {
      std::vector<Crypto::Hash> block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */
  
      void serialize(ISerializer &s) {
        KV_MEMBER(block_ids);
      }
    };
  
    struct response {
      std::vector<RawBlock> blocks;
      uint64_t start_height;
      uint64_t current_height;
      std::string status;
    };
  };
  //-----------------------------------------------
  struct COMMAND_RPC_GET_TRANSACTIONS {
    struct request {
      std::vector<std::string> txs_hashes;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(txs_hashes)
      }
    };
  
    struct response {
      std::vector<std::string> txs_as_hex; //transactions blobs as hex
      std::vector<std::string> missed_tx;  //not found transactions
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(txs_as_hex)
        KV_MEMBER(missed_tx)
        KV_MEMBER(status)
      }
    };
  };
  //-----------------------------------------------
  struct COMMAND_RPC_GET_POOL_CHANGES {
    struct request {
      Crypto::Hash tailBlockId;
      std::vector<Crypto::Hash> knownTxsIds;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(tailBlockId)
        KV_MEMBER(knownTxsIds);
      }
    };
  
    struct response {
      bool isTailBlockActual;
      std::vector<BinaryArray> addedTxs;          // Added transactions blobs
      std::vector<Crypto::Hash> deletedTxsIds; // IDs of not found transactions
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(isTailBlockActual)
        KV_MEMBER(addedTxs)
        KV_MEMBER(deletedTxsIds);
        KV_MEMBER(status)
      }
    };
  };
  
  struct COMMAND_RPC_GET_POOL_CHANGES_LITE {
    struct request {
      Crypto::Hash tailBlockId;
      std::vector<Crypto::Hash> knownTxsIds;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(tailBlockId)
        KV_MEMBER(knownTxsIds);
      }
    };
  
    struct response {
      bool isTailBlockActual;
      std::vector<TransactionPrefixInfo> addedTxs;          // Added transactions blobs
      std::vector<Crypto::Hash> deletedTxsIds; // IDs of not found transactions
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(isTailBlockActual)
        KV_MEMBER(addedTxs)
        KV_MEMBER(deletedTxsIds);
        KV_MEMBER(status)
      }
    };
  };
  
  //-----------------------------------------------
  struct COMMAND_RPC_GET_TX_GLOBAL_OUTPUTS_INDEXES {
  
    struct request {
      Crypto::Hash txid;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(txid)
      }
    };
  
    struct response {
      std::vector<uint64_t> o_indexes;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(o_indexes)
        KV_MEMBER(status)
      }
    };
  };
  
  struct COMMAND_RPC_GET_GLOBAL_INDEXES_FOR_RANGE
  {
      struct request
      {
          uint64_t startHeight;
          uint64_t endHeight;
  
          void serialize(ISerializer &s)
          {
              KV_MEMBER(startHeight);
              KV_MEMBER(endHeight);
          }
      };
  
      struct response
      {
          std::unordered_map<Crypto::Hash, std::vector<uint64_t>> indexes;
  
          std::string status;
  
          void serialize(ISerializer &s)
          {
              KV_MEMBER(indexes)
              KV_MEMBER(status)
          }
      };
  };
  
  
  //-----------------------------------------------
  
  #pragma pack(push, 1)
  struct OutputEntry {
    uint32_t global_amount_index;
    Crypto::PublicKey out_key;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(global_amount_index)
      KV_MEMBER(out_key);
    }
  };
  #pragma pack(pop)
  
  struct RandomOuts {
    uint64_t amount;
    std::vector<OutputEntry> outs;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(amount)
      KV_MEMBER(outs);
    }
  };
  
  struct COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS
  {
      struct request {
        std::vector<uint64_t> amounts;
        uint16_t outs_count;
  
        void serialize(ISerializer &s) {
          KV_MEMBER(amounts)
          KV_MEMBER(outs_count)
        }
      };
  
      struct response {
        std::vector<RandomOuts> outs;
        std::string status;
  
        void serialize(ISerializer &s) {
          KV_MEMBER(outs);
          KV_MEMBER(status)
        }
      };
  };
  
  //-----------------------------------------------
  struct COMMAND_RPC_SEND_RAW_TX {
    struct request {
      std::string tx_as_hex;
  
      request() {}
      explicit request(const Transaction &);
  
      void serialize(ISerializer &s) {
        KV_MEMBER(tx_as_hex)
      }
    };
  
    struct response {
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
      }
    };
  };
  //-----------------------------------------------
  struct COMMAND_RPC_START_MINING {
    struct request {
      std::string miner_address;
      uint64_t threads_count;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(miner_address)
        KV_MEMBER(threads_count)
      }
    };
  
    struct response {
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
      }
    };
  };
  //-----------------------------------------------
  struct COMMAND_RPC_GET_INFO {
    typedef EMPTY_STRUCT request;
  
    struct response {
      std::string status;
      uint64_t height;
      uint64_t difficulty;
      uint64_t tx_count;
      uint64_t tx_pool_size;
      uint64_t alt_blocks_count;
      uint64_t outgoing_connections_count;
      uint64_t incoming_connections_count;
      uint64_t white_peerlist_size;
      uint64_t grey_peerlist_size;
      uint32_t last_known_block_index;
      uint32_t network_height;
      std::vector<uint64_t> upgrade_heights;
      uint64_t supported_height;
      uint32_t hashrate;
      uint8_t major_version;
      uint8_t minor_version;
      std::string version;
      uint64_t start_time;
      bool synced;
      bool testnet;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(height)
        KV_MEMBER(difficulty)
        KV_MEMBER(tx_count)
        KV_MEMBER(tx_pool_size)
        KV_MEMBER(alt_blocks_count)
        KV_MEMBER(outgoing_connections_count)
        KV_MEMBER(incoming_connections_count)
        KV_MEMBER(white_peerlist_size)
        KV_MEMBER(grey_peerlist_size)
        KV_MEMBER(last_known_block_index)
        KV_MEMBER(network_height)
        KV_MEMBER(upgrade_heights)
        KV_MEMBER(supported_height)
        KV_MEMBER(hashrate)
        KV_MEMBER(major_version)
        KV_MEMBER(minor_version)
        KV_MEMBER(start_time)
        KV_MEMBER(synced)
        KV_MEMBER(testnet)
        KV_MEMBER(version)
      }
    };
  };
  
  //-----------------------------------------------
  struct COMMAND_RPC_STOP_MINING {
    typedef EMPTY_STRUCT request;
    typedef STATUS_STRUCT response;
  };
  
  //-----------------------------------------------
  struct COMMAND_RPC_STOP_DAEMON {
    typedef EMPTY_STRUCT request;
    typedef STATUS_STRUCT response;
  };
  
  //
  struct COMMAND_RPC_GETBLOCKCOUNT {
    typedef std::vector<std::string> request;
  
    struct response {
      uint64_t count;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(count)
        KV_MEMBER(status)
      }
    };
  };
  
  struct COMMAND_RPC_GETBLOCKHASH {
    typedef std::vector<uint64_t> request;
    typedef std::string response;
  };
  
  struct COMMAND_RPC_GETBLOCKTEMPLATE {
    struct request {
      uint64_t reserve_size; //max 255 bytes
      std::string wallet_address;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(reserve_size)
        KV_MEMBER(wallet_address)
      }
    };
  
    struct response {
      uint64_t difficulty;
      uint32_t height;
      uint64_t reserved_offset;
      std::string blocktemplate_blob;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(difficulty)
        KV_MEMBER(height)
        KV_MEMBER(reserved_offset)
        KV_MEMBER(blocktemplate_blob)
        KV_MEMBER(status)
      }
    };
  };
  
  struct COMMAND_RPC_GET_CURRENCY_ID {
    typedef EMPTY_STRUCT request;
  
    struct response {
      std::string currency_id_blob;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(currency_id_blob)
      }
    };
  };
  
  struct COMMAND_RPC_SUBMITBLOCK {
    typedef std::vector<std::string> request;
    typedef STATUS_STRUCT_EX response;
  };
  
  struct block_header_response {
    uint8_t major_version;
    uint8_t minor_version;
    uint64_t timestamp;
    std::string prev_hash;
    uint32_t nonce;
    bool orphan_status;
    uint32_t height;
    uint32_t depth;
    std::string hash;
    uint64_t difficulty;
    uint64_t reward;
    uint32_t num_txes;
    uint64_t block_size;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(major_version)
      KV_MEMBER(minor_version)
      KV_MEMBER(timestamp)
      KV_MEMBER(prev_hash)
      KV_MEMBER(nonce)
      KV_MEMBER(orphan_status)
      KV_MEMBER(height)
      KV_MEMBER(depth)
      KV_MEMBER(hash)
      KV_MEMBER(difficulty)
      KV_MEMBER(reward)
  	KV_MEMBER(num_txes)
  	KV_MEMBER(block_size)
    }
  };
  
  struct BLOCK_HEADER_RESPONSE {
    std::string status;
    block_header_response block_header;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(block_header)
      KV_MEMBER(status)
    }
  };
  
  
  struct COMMAND_RPC_GET_BLOCK_HEADERS_RANGE
  {
  	struct request
  	{
  		uint64_t start_height;
  		uint64_t end_height;
  
  		void serialize(ISerializer &s) {
  			KV_MEMBER(start_height)
  			KV_MEMBER(end_height)
  		}
  		/*BEGIN_KV_SERIALIZE_MAP()
  		KV_SERIALIZE(start_height)
  		KV_SERIALIZE(end_height)
  		END_KV_SERIALIZE_MAP()*/
  	};
  
  	struct response
  	{
  		std::string status;
  		std::vector<block_header_response> headers;
  		bool untrusted;
  
  		void serialize(ISerializer &s) {
  			KV_MEMBER(status)
  			KV_MEMBER(headers)
  			KV_MEMBER(untrusted)
  		}
  		/*BEGIN_KV_SERIALIZE_MAP()
  		KV_SERIALIZE(status)
  		KV_SERIALIZE(headers)
  		KV_SERIALIZE(untrusted)
  		END_KV_SERIALIZE_MAP()*/
  	};
  };
  
  struct f_transaction_short_response {
    std::string hash;
    uint64_t fee;
    uint64_t amount_out;
    uint64_t size;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(hash)
      KV_MEMBER(fee)
      KV_MEMBER(amount_out)
      KV_MEMBER(size)
    }
  };
  
  struct f_transaction_details_response {
    std::string hash;
    uint64_t size;
    std::string paymentId;
    uint64_t mixin;
    uint64_t fee;
    uint64_t amount_out;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(hash)
      KV_MEMBER(size)
      KV_MEMBER(paymentId)
      KV_MEMBER(mixin)
      KV_MEMBER(fee)
      KV_MEMBER(amount_out)
    }
  };
  
  struct f_block_short_response {
    uint64_t difficulty;
    uint64_t timestamp;
    uint32_t height;
    std::string hash;
    uint64_t tx_count;
    uint64_t cumul_size;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(difficulty)
      KV_MEMBER(timestamp)
      KV_MEMBER(height)
      KV_MEMBER(hash)
      KV_MEMBER(cumul_size)
      KV_MEMBER(tx_count)
    }
  };
  
  struct f_block_details_response {
    uint8_t major_version;
    uint8_t minor_version;
    uint64_t timestamp;
    std::string prev_hash;
    uint32_t nonce;
    bool orphan_status;
    uint32_t height;
    uint64_t depth;
    std::string hash;
    uint64_t difficulty;
    uint64_t reward;
    uint64_t blockSize;
    uint64_t sizeMedian;
    uint64_t effectiveSizeMedian;
    uint64_t transactionsCumulativeSize;
    std::string alreadyGeneratedCoins;
    uint64_t alreadyGeneratedTransactions;
    uint64_t baseReward;
    double penalty;
    uint64_t totalFeeAmount;
    std::vector<f_transaction_short_response> transactions;
  
    void serialize(ISerializer &s) {
      KV_MEMBER(major_version)
      KV_MEMBER(minor_version)
      KV_MEMBER(timestamp)
      KV_MEMBER(prev_hash)
      KV_MEMBER(nonce)
      KV_MEMBER(orphan_status)
      KV_MEMBER(height)
      KV_MEMBER(depth)
      KV_MEMBER(hash)
      KV_MEMBER(difficulty)
      KV_MEMBER(reward)
      KV_MEMBER(blockSize)
      KV_MEMBER(sizeMedian)
      KV_MEMBER(effectiveSizeMedian)
      KV_MEMBER(transactionsCumulativeSize)
      KV_MEMBER(alreadyGeneratedCoins)
      KV_MEMBER(alreadyGeneratedTransactions)
      KV_MEMBER(baseReward)
      KV_MEMBER(penalty)
      KV_MEMBER(transactions)
      KV_MEMBER(totalFeeAmount)
    }
  };
  struct COMMAND_RPC_GET_LAST_BLOCK_HEADER {
    typedef EMPTY_STRUCT request;
    typedef BLOCK_HEADER_RESPONSE response;
  };
  
  struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH {
    struct request {
      std::string hash;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(hash)
      }
    };
  
    typedef BLOCK_HEADER_RESPONSE response;
  };
  
  struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT {
    struct request {
      uint64_t height;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(height)
      }
    };
  
    typedef BLOCK_HEADER_RESPONSE response;
  };
  
  struct F_COMMAND_RPC_GET_BLOCKS_LIST {
    struct request {
      uint64_t height;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(height)
      }
    };
  
    struct response {
      std::vector<f_block_short_response> blocks; //transactions blobs as hex
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(blocks)
        KV_MEMBER(status)
      }
    };
  };
  
  struct F_COMMAND_RPC_GET_BLOCK_DETAILS {
    struct request {
      std::string hash;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(hash)
      }
    };
  
    struct response {
      f_block_details_response block;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(block)
        KV_MEMBER(status)
      }
    };
  };
  
  struct F_COMMAND_RPC_GET_TRANSACTION_DETAILS {
    struct request {
      std::string hash;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(hash)
      }
    };
  
    struct response {
      Transaction tx;
      f_transaction_details_response txDetails;
      f_block_short_response block;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(tx)
        KV_MEMBER(txDetails)
        KV_MEMBER(block)
        KV_MEMBER(status)
      }
    };
  };
  
  struct F_COMMAND_RPC_GET_POOL {
    typedef EMPTY_STRUCT request;
  
    struct response {
      std::vector<f_transaction_short_response> transactions; //transactions blobs as hex
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(transactions)
        KV_MEMBER(status)
      }
    };
  };
  struct COMMAND_RPC_QUERY_BLOCKS {
    struct request {
      std::vector<Crypto::Hash> block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */
      uint64_t timestamp;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(block_ids);
        KV_MEMBER(timestamp)
      }
    };
  
    struct response {
      std::string status;
      uint64_t start_height;
      uint64_t current_height;
      uint64_t full_offset;
      std::vector<BlockFullInfo> items;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(start_height)
        KV_MEMBER(current_height)
        KV_MEMBER(full_offset)
        KV_MEMBER(items)
      }
    };
  };
  
  struct COMMAND_RPC_QUERY_BLOCKS_LITE {
    struct request {
      std::vector<Crypto::Hash> blockIds;
      uint64_t timestamp;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(blockIds);
        KV_MEMBER(timestamp)
      }
    };
  
    struct response {
      std::string status;
      uint64_t startHeight;
      uint64_t currentHeight;
      uint64_t fullOffset;
      std::vector<BlockShortInfo> items;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(startHeight)
        KV_MEMBER(currentHeight)
        KV_MEMBER(fullOffset)
        KV_MEMBER(items)
      }
    };
  };
  
  struct COMMAND_RPC_QUERY_BLOCKS_DETAILED {
    struct request {
      std::vector<Crypto::Hash> blockIds;
      uint64_t timestamp;
      uint32_t blockCount;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(blockIds);
        KV_MEMBER(timestamp)
        KV_MEMBER(blockCount)
      }
    };
  
    struct response {
      std::string status;
      uint64_t startHeight;
      uint64_t currentHeight;
      uint64_t fullOffset;
      std::vector<BlockDetails> blocks;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(startHeight)
        KV_MEMBER(currentHeight)
        KV_MEMBER(fullOffset)
        KV_MEMBER(blocks)
      }
    };
  };
  
  struct COMMAND_RPC_GET_WALLET_SYNC_DATA {
    struct request {
      std::vector<Crypto::Hash> blockIds;
  
      uint64_t startHeight;
      uint64_t startTimestamp;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(blockIds);
        KV_MEMBER(startHeight);
        KV_MEMBER(startTimestamp);
      }
    };
  
    struct response {
      std::string status;
      std::vector<WalletTypes::WalletBlockInfo> items;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(items)
      }
    };
  };
  
  struct COMMAND_RPC_GET_TRANSACTIONS_STATUS
  {
      struct request
      {
          std::unordered_set<Crypto::Hash> transactionHashes;
  
          void serialize(ISerializer &s)
          {
              KV_MEMBER(transactionHashes);
          }
      };
  
      struct response
      {
          std::string status;
  
          /* These transactions are in the transaction pool */
          std::unordered_set<Crypto::Hash> transactionsInPool;
  
          /* These transactions are in a block */
          std::unordered_set<Crypto::Hash> transactionsInBlock;
  
          /* We don't know anything about these hashes */
          std::unordered_set<Crypto::Hash> transactionsUnknown;
  
          void serialize(ISerializer &s)
          {
              KV_MEMBER(status);
              KV_MEMBER(transactionsInPool);
              KV_MEMBER(transactionsInBlock);
              KV_MEMBER(transactionsUnknown);
          }
      };
  };
  
  struct COMMAND_RPC_GET_BLOCKS_DETAILS_BY_HEIGHTS {
    struct request {
      std::vector<uint32_t> blockHeights;
  
      void serialize(ISerializer& s) {
        KV_MEMBER(blockHeights);
      }
    };
  
    struct response {
      std::vector<BlockDetails> blocks;
      std::string status;
  
      void serialize(ISerializer& s) {
        KV_MEMBER(status)
        KV_MEMBER(blocks)
      }
    };
  };
  
  struct COMMAND_RPC_GET_BLOCKS_DETAILS_BY_HASHES {
    struct request {
      std::vector<Crypto::Hash> blockHashes;
  
      void serialize(ISerializer& s) {
        KV_MEMBER(blockHashes);
      }
    };
  
    struct response {
      std::vector<BlockDetails> blocks;
      std::string status;
  
      void serialize(ISerializer& s) {
        KV_MEMBER(status)
        KV_MEMBER(blocks)
      }
    };
  };
  
  struct COMMAND_RPC_GET_BLOCK_DETAILS_BY_HEIGHT {
    struct request {
      uint32_t blockHeight;
  
      void serialize(ISerializer& s) {
        KV_MEMBER(blockHeight)
      }
    };
  
    struct response {
      BlockDetails block;
      std::string status;
  
      void serialize(ISerializer& s) {
        KV_MEMBER(status)
        KV_MEMBER(block)
      }
    };
  };
  
  struct COMMAND_RPC_GET_BLOCKS_HASHES_BY_TIMESTAMPS {
    struct request {
      uint64_t timestampBegin;
      uint64_t secondsCount;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(timestampBegin)
        KV_MEMBER(secondsCount)
      }
    };
  
    struct response {
      std::vector<Crypto::Hash> blockHashes;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(blockHashes)
      }
    };
  };
  
  struct COMMAND_RPC_GET_TRANSACTION_HASHES_BY_PAYMENT_ID {
    struct request {
      Crypto::Hash paymentId;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(paymentId)
      }
    };
  
    struct response {
      std::vector<Crypto::Hash> transactionHashes;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(transactionHashes);
      }
    };
  };
  
  struct COMMAND_RPC_GET_TRANSACTION_DETAILS_BY_HASHES {
    struct request {
      std::vector<Crypto::Hash> transactionHashes;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(transactionHashes);
      }
    };
  
    struct response {
      std::vector<TransactionDetails> transactions;
      std::string status;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(transactions)
      }
    };
  };
  
  struct COMMAND_RPC_GET_PEERS {
    // TODO: rename peers to white_peers - do at v1
    typedef EMPTY_STRUCT request;
  
    struct response {
      std::string status;
      std::vector<std::string> peers;
      std::vector<std::string> gray_peers;
  
      void serialize(ISerializer &s) {
        KV_MEMBER(status)
        KV_MEMBER(peers)
        KV_MEMBER(gray_peers)
      }
    };
  };
  
  struct COMMAND_RPC_GET_FEE_ADDRESS {
    typedef EMPTY_STRUCT request;
  
    struct response {
      std::string address;
      uint32_t amount;
      std::string status;
  
      void serialize(ISerializer & s) {
        KV_MEMBER(address)
        KV_MEMBER(amount)
        KV_MEMBER(status)
      }
    };
  };
  
  }
  