From 85427c67f665e20b4ca329150f6d631d6c15e1cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Mon, 1 Oct 2018 18:58:07 +0300 Subject: [PATCH 01/18] Added multi wallet support --- src/bitcoinapi/bitcoinapi.cpp | 7 +++++++ src/bitcoinapi/bitcoinapi.h | 1 + 2 files changed, 8 insertions(+) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 557c1ed..d1fe350 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -38,6 +38,13 @@ BitcoinAPI::BitcoinAPI(const string& user, const string& password, const string& httpClient->SetTimeout(httpTimeout); } +BitcoinAPI::BitcoinAPI(const string& user, const string& password, const string& host, int port, const string& wallet, int httpTimeout) +: httpClient(new HttpClient("http://" + user + ":" + password + "@" + host + ":" + IntegerToString(port) + "/wallet/" + wallet)), + client(new Client(*httpClient, JSONRPC_CLIENT_V1)) +{ + httpClient->SetTimeout(httpTimeout); +} + BitcoinAPI::~BitcoinAPI() { delete client; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index 30070fd..b8c9e99 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -26,6 +26,7 @@ class BitcoinAPI public: /* === Constructor and Destructor === */ BitcoinAPI(const std::string& user, const std::string& password, const std::string& host, int port, int httpTimeout); + BitcoinAPI(const std::string& user, const std::string& password, const std::string& host, int port, const std::string& wallet, int httpTimeout); ~BitcoinAPI(); /* === Auxiliary functions === */ From 7ff90c473fb5733001a2a2d4e47042d4d354484d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Thu, 11 Oct 2018 23:09:06 +0300 Subject: [PATCH 02/18] Added watchonly support to listsinceblock, added fee variable to transactioninfo_t structure --- src/bitcoinapi/bitcoinapi.cpp | 6 +++++- src/bitcoinapi/bitcoinapi.h | 2 +- src/bitcoinapi/types.h | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index ce4e62c..7619d3d 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -580,6 +580,7 @@ vector BitcoinAPI::listtransactions() { tmp.address = val["address"].asString(); tmp.category = val["category"].asString(); tmp.amount = val["amount"].asDouble(); + tmp.fee = val["fee"].asDouble(); tmp.confirmations = val["confirmations"].asInt(); tmp.blockhash = val["blockhash"].asString(); tmp.blockindex = val["blockindex"].asInt(); @@ -618,6 +619,7 @@ vector BitcoinAPI::listtransactions(const string& account, in tmp.address = val["address"].asString(); tmp.category = val["category"].asString(); tmp.amount = val["amount"].asDouble(); + tmp.fee = val["fee"].asDouble(); tmp.confirmations = val["confirmations"].asInt(); tmp.blockhash = val["blockhash"].asString(); tmp.blockindex = val["blockindex"].asInt(); @@ -1010,13 +1012,14 @@ mininginfo_t BitcoinAPI::getmininginfo() { } -txsinceblock_t BitcoinAPI::listsinceblock(const string& blockhash, int target_confirmations) { +txsinceblock_t BitcoinAPI::listsinceblock(const string& blockhash, int target_confirmations, bool includewatchonly) { string command = "listsinceblock"; Value params, result; txsinceblock_t ret; params.append(blockhash); params.append(target_confirmations); + params.append(includewatchonly); result = sendcommand(command, params); for(ValueIterator it = result["transactions"].begin(); it != result["transactions"].end(); it++){ @@ -1027,6 +1030,7 @@ txsinceblock_t BitcoinAPI::listsinceblock(const string& blockhash, int target_co tmp.address = val["address"].asString(); tmp.category = val["category"].asString(); tmp.amount = val["amount"].asDouble(); + tmp.fee = val["fee"].asDouble(); tmp.confirmations = val["confirmations"].asInt(); tmp.blockhash = val["blockhash"].asString(); tmp.blockindex = val["blockindex"].asInt(); diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index bb4bd35..7c965ce 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -134,7 +134,7 @@ class BitcoinAPI workdata_t getwork(); bool getwork(const std::string& data); - txsinceblock_t listsinceblock(const std::string& blockhash = "", int target_confirmations = 1); + txsinceblock_t listsinceblock(const std::string& blockhash = "", int target_confirmations = 1, bool includewatchonly = false); /* === Low level calls === */ diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index 92fa6fa..226d140 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -86,6 +86,7 @@ std::vector walletconflicts; int time; int timereceived; + double fee; }; struct multisig_t{ From 7312bcea229f269175d8aa8d997798319aaa3c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Thu, 11 Oct 2018 23:41:17 +0300 Subject: [PATCH 03/18] Added estimatesmartfee function --- src/bitcoinapi/bitcoinapi.cpp | 11 +++++++++++ src/bitcoinapi/bitcoinapi.h | 3 ++- src/bitcoinapi/types.h | 5 +++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 7619d3d..048fca4 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -406,6 +406,17 @@ double BitcoinAPI::estimatefee(int blocks) { return result.asDouble(); } +smartfee_t BitcoinAPI::estimatesmartfee(int blocks) { + string command = "estimatesmartfee"; + Value params, result; + smartfee_t ret; + params.append(blocks); + result = sendcommand(command, params); + ret.feerate = result["feerate"].asDouble(); + ret.blocks = result["blocks"].asInt(); + return ret; +} + string BitcoinAPI::signmessage(const std::string& bitcoinaddress, const std::string& message) { string command = "signmessage"; Value params, result; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index 7c965ce..8de8724 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -65,6 +65,7 @@ class BitcoinAPI void keypoolrefill(); bool settxfee(double amount); double estimatefee(int blocks); + smartfee_t estimatesmartfee(int blocks); std::string signmessage(const std::string& bitcoinaddress, const std::string& message); bool verifymessage(const std::string& bitcoinaddress, const std::string& signature, const std::string& message); @@ -83,7 +84,7 @@ class BitcoinAPI std::vector listreceivedbyaccount(int minconf = 1, bool includeempty = false); std::vector listreceivedbyaddress(int minconf = 1, bool includeempty = false); - + gettransaction_t gettransaction(const std::string& tx, bool watch); std::vector listtransactions(); std::vector listtransactions(const std::string& account, int count = 10, int from = 0); diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index 226d140..c672c02 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -210,6 +210,11 @@ /* === Other === */ + + struct smartfee_t{ + double feerate; + int blocks; + }; struct utxoinfo_t{ std::string bestblock; int confirmations; From 51818920efefe9ce0363d130a0a16787f59a0258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Sat, 20 Oct 2018 18:43:33 +0300 Subject: [PATCH 04/18] Initial functions for omni layer support --- src/bitcoinapi/bitcoinapi.h | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index 8de8724..3c857e9 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -11,6 +11,8 @@ #ifndef BITCOIN_API_H #define BITCOIN_API_H +#define _OMNI_SUPPORT_ + #include "types.h" #include "exception.h" @@ -29,6 +31,22 @@ class BitcoinAPI BitcoinAPI(const std::string& user, const std::string& password, const std::string& host, int port, const std::string& wallet, int httpTimeout = 50000); ~BitcoinAPI(); + #ifdef _OMNI_SUPPORT_ + /* + virtual double estimatesmartfee(int requestedBlockCount) = 0; + virtual bool settxfee(double fee) = 0; + virtual std::string getnewaddress(const std::string& account = "") = 0; + virtual void walletpassphrase(const std::string& password, int timeout) = 0; + virtual void walletlock() = 0; + virtual std::string sendfrom(const std::string& fromaccount, const std::string& tobitcoinaddress, double amount) = 0; + virtual std::string sendmany(const std::string& fromaccount, const std::map& amounts) = 0; + +*/ + void omni_funded_send(); + void omni_funded_sendall(); + void omni_send(); + #endif + /* === Auxiliary functions === */ Json::Value sendcommand(const std::string& command, const Json::Value& params); From 436a5db7dd74edbd5078097cddf05cdccbe78b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Mon, 29 Oct 2018 18:25:49 +0300 Subject: [PATCH 05/18] Added initial omni layer functions --- src/bitcoinapi/bitcoinapi.cpp | 86 +++++++++++++++++++++++++++++++++++ src/bitcoinapi/bitcoinapi.h | 9 ++++ src/bitcoinapi/exception.h | 2 +- src/bitcoinapi/types.h | 33 ++++++++++++++ 4 files changed, 129 insertions(+), 1 deletion(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 048fca4..b27a624 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1383,3 +1383,89 @@ utxosetinfo_t BitcoinAPI::gettxoutsetinfo() { return ret; } + +#ifdef _OMNI_SUPPORT_ + +std::vector BitcoinAPI::omni_getwalletbalances(bool includewatchonly) +{ + string command = "omni_getwalletbalances"; + Value params, result; + vector ret; + + params.append(includewatchonly); + result = sendcommand(command, params); + + for(ValueIterator it = result.begin(); it != result.end(); it++){ + omni_detailed_balance_t tmp; + Value val = (*it); + + tmp.balance = val["balance"].asDouble(); + tmp.reserved = val["reserved"].asDouble(); + tmp.propertyid = val["propertyid"].asDouble(); + tmp.name = val["name"].asString(); + tmp.propertyid = val["propertyid"].asInt(); + + ret.push_back(tmp); + } + + return ret; +} + +omni_balance_t BitcoinAPI::omni_getbalance(const std::string& address, int propertyid) +{ + string command = "omni_getbalance"; + Value params, result; + omni_balance_t ret; + + params.append(address); + params.append(propertyid); + + result = sendcommand(command, params); + + ret.balance = result["balance"].asDouble(); + ret.reserved = result["reserved"].asDouble(); + ret.frozen = result["frozen"].asDouble(); + + return ret; +} + +std::vector BitcoinAPI::omni_listtransactions(const std::string& txid, int count, int skip, int startblock, int endblock) +{ + string command = "omni_listtransactions"; + Value params, result; + vector ret; + + params.append(txid); + params.append(count); + params.append(skip); + params.append(startblock); + params.append(endblock); + result = sendcommand(command, params); + + for(ValueIterator it = result.begin(); it != result.end(); it++){ + omni_transaction_t tmp; + Value val = (*it); + tmp.txid = val["txid"].asString(); + tmp.sendingaddress = val["sendingaddress"].asString(); + tmp.referenceaddress = val["referenceaddress"].asString(); + tmp.ismine = val["ismine"].asBool(); + tmp.confirmations = val["confirmations"].asInt(); + tmp.fee = val["fee"].asDouble(); + tmp.blocktime = val["blocktime"].asUInt(); + tmp.valid = val["valid"].asBool(); + tmp.positioninblock = val["positioninblock"].asUInt(); + tmp.version = val["version"].asInt(); + tmp.type_int = val["type_int"].asInt(); + tmp.type = val["type"].asString(); + tmp.amount = val["amount"].asDouble(); + tmp.blockhash = val["blockhash"].asString(); + tmp.block = val["block"].asUInt(); + + ret.push_back(tmp); + } + + return ret; + +} + +#endif diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index 3c857e9..0cb6a8f 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -42,9 +42,18 @@ class BitcoinAPI virtual std::string sendmany(const std::string& fromaccount, const std::map& amounts) = 0; */ +/* void omni_funded_send(); void omni_funded_sendall(); void omni_send(); + */ + + void omni_funded_sendall(); + + std::vector omni_getwalletbalances(bool includewatchonly); + omni_balance_t omni_getbalance(const std::string& address, int propertyid); + std::vector omni_listtransactions(const std::string& txid = "*", int count = 10, int skip = 0, int startblock = 0, int endblock = 999999999); + #endif /* === Auxiliary functions === */ diff --git a/src/bitcoinapi/exception.h b/src/bitcoinapi/exception.h index ccdbc3d..dfd1ee3 100644 --- a/src/bitcoinapi/exception.h +++ b/src/bitcoinapi/exception.h @@ -40,7 +40,7 @@ class BitcoinException: public std::exception /* Authentication error */ }else if(errcode == Errors::ERROR_RPC_INTERNAL_ERROR && message.size() == 18){ this->code = errcode; - this->msg = "Failed to authenticate successfully"; + this->msg = "Failed to authenticate successfully. " + message; /* Miscellaneous error */ }else{ this->code = parseCode(message); diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index c672c02..9cfca1b 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -242,6 +242,39 @@ int confirmations; }; + #ifdef _OMNI_SUPPORT_ + + struct omni_transaction_t { + std::string txid; + std::string sendingaddress; + std::string referenceaddress; + bool ismine; + int confirmations; + double amount; + std::string blockhash; + unsigned int block; + double fee; + unsigned int blocktime; + bool valid; + unsigned int positioninblock; + int version; + int type_int; + std::string type; + }; + + struct omni_balance_t { + double balance; + double reserved; + double frozen; + }; + + struct omni_detailed_balance_t: omni_balance_t{ + int propertyid; + std::string name; + }; + + #endif + /* === Unused yet === */ struct blockinfo_t{ From 903c4ddeb37e050874ef540efd126ea9e39c3412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Sat, 3 Nov 2018 17:58:27 +0300 Subject: [PATCH 06/18] Added omni_send and omni_funded_sendall functions --- src/bitcoinapi/bitcoinapi.cpp | 28 ++++++++++++++++++++++++++++ src/bitcoinapi/bitcoinapi.h | 20 ++------------------ 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index b27a624..0bf5651 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1386,6 +1386,34 @@ utxosetinfo_t BitcoinAPI::gettxoutsetinfo() { #ifdef _OMNI_SUPPORT_ +std::string BitcoinAPI::omni_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount) +{ + string command = "omni_send"; + Value params, result; + + params.append(fromaddress); + params.append(toaddress); + params.append(propertyid); + params.append(amount); + + result = sendcommand(command, params); + return result.asString(); +} + +std::string BitcoinAPI::omni_funded_sendall(const std::string& fromaddress, const std::string& toaddress, int ecosystem, const std::string& feeaddress) +{ + string command = "omni_funded_sendall"; + Value params, result; + + params.append(fromaddress); + params.append(toaddress); + params.append(ecosystem); + params.append(feeaddress); + + result = sendcommand(command, params); + return result.asString(); +} + std::vector BitcoinAPI::omni_getwalletbalances(bool includewatchonly) { string command = "omni_getwalletbalances"; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index 0cb6a8f..b8c293c 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -32,24 +32,8 @@ class BitcoinAPI ~BitcoinAPI(); #ifdef _OMNI_SUPPORT_ - /* - virtual double estimatesmartfee(int requestedBlockCount) = 0; - virtual bool settxfee(double fee) = 0; - virtual std::string getnewaddress(const std::string& account = "") = 0; - virtual void walletpassphrase(const std::string& password, int timeout) = 0; - virtual void walletlock() = 0; - virtual std::string sendfrom(const std::string& fromaccount, const std::string& tobitcoinaddress, double amount) = 0; - virtual std::string sendmany(const std::string& fromaccount, const std::map& amounts) = 0; - -*/ -/* - void omni_funded_send(); - void omni_funded_sendall(); - void omni_send(); - */ - - void omni_funded_sendall(); - + std::string omni_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount); + std::string omni_funded_sendall(const std::string& fromaddress, const std::string& toaddress, int ecosystem, const std::string& feeaddress); std::vector omni_getwalletbalances(bool includewatchonly); omni_balance_t omni_getbalance(const std::string& address, int propertyid); std::vector omni_listtransactions(const std::string& txid = "*", int count = 10, int skip = 0, int startblock = 0, int endblock = 999999999); From deebe12d4bc24b4956e553e375ffe51dd1845706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Thu, 8 Nov 2018 00:03:48 +0300 Subject: [PATCH 07/18] Fixed string to double conversions on omni calls --- src/bitcoinapi/bitcoinapi.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 0bf5651..59b1372 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1427,9 +1427,9 @@ std::vector BitcoinAPI::omni_getwalletbalances(bool inc omni_detailed_balance_t tmp; Value val = (*it); - tmp.balance = val["balance"].asDouble(); - tmp.reserved = val["reserved"].asDouble(); - tmp.propertyid = val["propertyid"].asDouble(); + tmp.balance = stod(val["balance"].asString()); + tmp.reserved = stod(val["reserved"].asString()); + tmp.frozen = stod(val["frozen"].asString()); tmp.name = val["name"].asString(); tmp.propertyid = val["propertyid"].asInt(); @@ -1450,9 +1450,9 @@ omni_balance_t BitcoinAPI::omni_getbalance(const std::string& address, int prope result = sendcommand(command, params); - ret.balance = result["balance"].asDouble(); - ret.reserved = result["reserved"].asDouble(); - ret.frozen = result["frozen"].asDouble(); + ret.balance = stod(result["balance"].asString()); + ret.reserved = stod(result["reserved"].asString()); + ret.frozen = stod(result["frozen"].asString()); return ret; } @@ -1478,14 +1478,16 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str tmp.referenceaddress = val["referenceaddress"].asString(); tmp.ismine = val["ismine"].asBool(); tmp.confirmations = val["confirmations"].asInt(); - tmp.fee = val["fee"].asDouble(); + + tmp.fee = stod(val["fee"].asString()); tmp.blocktime = val["blocktime"].asUInt(); tmp.valid = val["valid"].asBool(); tmp.positioninblock = val["positioninblock"].asUInt(); tmp.version = val["version"].asInt(); tmp.type_int = val["type_int"].asInt(); tmp.type = val["type"].asString(); - tmp.amount = val["amount"].asDouble(); + + tmp.amount = stod(val["amount"].asString()); tmp.blockhash = val["blockhash"].asString(); tmp.block = val["block"].asUInt(); From f7568901a3e157e0cace64f751740fabeb610363 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Fri, 9 Nov 2018 22:50:06 +0300 Subject: [PATCH 08/18] Added omni_funded_send command --- src/bitcoinapi/bitcoinapi.cpp | 15 +++++++++++++++ src/bitcoinapi/bitcoinapi.h | 1 + 2 files changed, 16 insertions(+) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 59b1372..5cfcd7c 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1400,6 +1400,21 @@ std::string BitcoinAPI::omni_send(const std::string& fromaddress, const std::str return result.asString(); } +std::string BitcoinAPI::omni_funded_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount, const std::string& feeaddress) +{ + string command = "omni_funded_send"; + Value params, result; + + params.append(fromaddress); + params.append(toaddress); + params.append(propertyid); + params.append(amount); + params.append(feeaddress); + + result = sendcommand(command, params); + return result.asString(); +} + std::string BitcoinAPI::omni_funded_sendall(const std::string& fromaddress, const std::string& toaddress, int ecosystem, const std::string& feeaddress) { string command = "omni_funded_sendall"; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index b8c293c..daa2809 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -34,6 +34,7 @@ class BitcoinAPI #ifdef _OMNI_SUPPORT_ std::string omni_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount); std::string omni_funded_sendall(const std::string& fromaddress, const std::string& toaddress, int ecosystem, const std::string& feeaddress); + std::string omni_funded_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount, const std::string& feeaddress); std::vector omni_getwalletbalances(bool includewatchonly); omni_balance_t omni_getbalance(const std::string& address, int propertyid); std::vector omni_listtransactions(const std::string& txid = "*", int count = 10, int skip = 0, int startblock = 0, int endblock = 999999999); From da2728105d8f6bfd848e2d9737bcee618b7b5db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Tue, 20 Nov 2018 16:36:17 +0300 Subject: [PATCH 09/18] Added omni_listpendingtransactions function, updated listunspent --- src/bitcoinapi/bitcoinapi.cpp | 54 ++++++++++++++++++++++++++++++++--- src/bitcoinapi/bitcoinapi.h | 2 ++ src/bitcoinapi/types.h | 2 ++ 3 files changed, 54 insertions(+), 4 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 5cfcd7c..1298a73 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -854,13 +854,22 @@ string BitcoinAPI::sendmany(const string& fromaccount, const map& return result.asString(); } -vector BitcoinAPI::listunspent(int minconf, int maxconf) { +vector BitcoinAPI::listunspent(int minconf, int maxconf, const vector& addresses) { + string command = "listunspent"; Value params, result; vector ret; params.append(minconf); params.append(maxconf); + if (addresses.size() > 0) { + Value addressesParam(Json::arrayValue); + for(vector::const_iterator it = addresses.begin(); it != addresses.end(); it++){ + Value val; + addressesParam.append((*it)); + } + params.append(addressesParam); + } result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ @@ -881,6 +890,11 @@ vector BitcoinAPI::listunspent(int minconf, int maxconf) { return ret; } +vector BitcoinAPI::listunspent(int minconf, int maxconf) { + std::vector addresses; + return this->listunspent(minconf, maxconf, addresses); +} + vector BitcoinAPI::listlockunspent() { string command = "listlockunspent"; Value params, result; @@ -1037,6 +1051,7 @@ txsinceblock_t BitcoinAPI::listsinceblock(const string& blockhash, int target_co Value val = (*it); transactioninfo_t tmp; + tmp.involvesWatchonly = val["involvesWatchonly"].asBool(); tmp.account = val["account"].asString(); tmp.address = val["address"].asString(); tmp.category = val["category"].asString(); @@ -1394,7 +1409,7 @@ std::string BitcoinAPI::omni_send(const std::string& fromaddress, const std::str params.append(fromaddress); params.append(toaddress); params.append(propertyid); - params.append(amount); + params.append(std::to_string(amount)); result = sendcommand(command, params); return result.asString(); @@ -1408,7 +1423,7 @@ std::string BitcoinAPI::omni_funded_send(const std::string& fromaddress, const s params.append(fromaddress); params.append(toaddress); params.append(propertyid); - params.append(amount); + params.append(std::to_string(amount)); params.append(feeaddress); result = sendcommand(command, params); @@ -1493,7 +1508,7 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str tmp.referenceaddress = val["referenceaddress"].asString(); tmp.ismine = val["ismine"].asBool(); tmp.confirmations = val["confirmations"].asInt(); - + tmp.propertyid = val["propertyid"].asInt(); tmp.fee = stod(val["fee"].asString()); tmp.blocktime = val["blocktime"].asUInt(); tmp.valid = val["valid"].asBool(); @@ -1510,7 +1525,38 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str } return ret; +} +std::vector BitcoinAPI::omni_listpendingtransactions(const std::string& address) +{ + string command = "omni_listpendingtransactions"; + Value params, result; + vector ret; + + params.append(address); + result = sendcommand(command, params); + + for(ValueIterator it = result.begin(); it != result.end(); it++) { + omni_transaction_t tmp; + Value val = (*it); + tmp.txid = val["txid"].asString(); + tmp.sendingaddress = val["sendingaddress"].asString(); + tmp.referenceaddress = val["referenceaddress"].asString(); + tmp.ismine = val["ismine"].asBool(); + tmp.confirmations = val["confirmations"].asInt(); + tmp.propertyid = val["propertyid"].asInt(); + tmp.fee = stod(val["fee"].asString()); + tmp.blocktime = val["blocktime"].asUInt(); + tmp.version = val["version"].asInt(); + tmp.type_int = val["type_int"].asInt(); + tmp.type = val["type"].asString(); + + tmp.amount = stod(val["amount"].asString()); + + ret.push_back(tmp); + } + + return ret; } #endif diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index daa2809..e2cc1d3 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -38,6 +38,7 @@ class BitcoinAPI std::vector omni_getwalletbalances(bool includewatchonly); omni_balance_t omni_getbalance(const std::string& address, int propertyid); std::vector omni_listtransactions(const std::string& txid = "*", int count = 10, int skip = 0, int startblock = 0, int endblock = 999999999); + std::vector omni_listpendingtransactions(const std::string& address = ""); #endif @@ -127,6 +128,7 @@ class BitcoinAPI utxosetinfo_t gettxoutsetinfo(); std::vector listunspent(int minconf = 1, int maxconf = 999999); + std::vector listunspent(int minconf, int maxconf, const std::vector& addresses); std::vector listlockunspent(); bool lockunspent(bool unlock, const std::vector& outputs); diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index 9cfca1b..6a06a19 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -77,6 +77,7 @@ }; struct transactioninfo_t: accountinfo_t{ + bool involvesWatchonly; std::string address; std::string category; std::string blockhash; @@ -248,6 +249,7 @@ std::string txid; std::string sendingaddress; std::string referenceaddress; + int propertyid; bool ismine; int confirmations; double amount; From 716c51a79f67eca082f1476b0215405d2edd333b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Wed, 16 Jan 2019 23:31:26 +0300 Subject: [PATCH 10/18] Added iswatchonly to validateaddress response --- src/bitcoinapi/bitcoinapi.cpp | 1 + src/bitcoinapi/types.h | 1 + 2 files changed, 2 insertions(+) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 1298a73..8c47780 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -380,6 +380,7 @@ validateaddress_t BitcoinAPI::validateaddress(const string& bitcoinaddress) { ret.isscript = result["isscript"].asBool(); ret.pubkey = result["pubkey"].asString(); ret.iscompressed = result["iscompressed"].asBool(); + ret.iswatchonly = result["iswatchonly"].asBool(); return ret; } diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index 6a06a19..8f7b191 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -103,6 +103,7 @@ std::string pubkey; bool iscompressed; std::string account; + bool iswatchonly; }; struct addressgrouping_t{ From f5be9508adeda1de99a6c1fa62494ee019aab5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Sat, 19 Jan 2019 10:54:04 +0300 Subject: [PATCH 11/18] Added omni_getwalletaddressbalances function --- src/bitcoinapi/bitcoinapi.cpp | 33 +++++++++++++++++++++++++++++++++ src/bitcoinapi/bitcoinapi.h | 2 ++ src/bitcoinapi/types.h | 5 +++++ 3 files changed, 40 insertions(+) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 1298a73..25ceab6 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1444,6 +1444,39 @@ std::string BitcoinAPI::omni_funded_sendall(const std::string& fromaddress, cons return result.asString(); } +std::vector BitcoinAPI::omni_getwalletaddressbalances(bool includewatchonly) +{ + string command = "omni_getwalletaddressbalances"; + Value params, result; + vector ret; + + params.append(includewatchonly); + result = sendcommand(command, params); + + for(ValueIterator it = result.begin(); it != result.end(); it++){ + omni_address_balance_t tmp; + Value val = (*it); + tmp.address = val["address"].asString(); + + for(ValueIterator it2 = val["balances"].begin(); it2 != val["balances"].end(); it2++){ + omni_detailed_balance_t tmp2; + Value val = (*it2); + + tmp2.balance = stod(val["balance"].asString()); + tmp2.reserved = stod(val["reserved"].asString()); + tmp2.frozen = stod(val["frozen"].asString()); + tmp2.name = val["name"].asString(); + tmp2.propertyid = val["propertyid"].asInt(); + + tmp.balances.push_back(tmp2); + } + ret.push_back(tmp); + } + + return ret; +} + + std::vector BitcoinAPI::omni_getwalletbalances(bool includewatchonly) { string command = "omni_getwalletbalances"; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index e2cc1d3..2be2662 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -36,6 +36,8 @@ class BitcoinAPI std::string omni_funded_sendall(const std::string& fromaddress, const std::string& toaddress, int ecosystem, const std::string& feeaddress); std::string omni_funded_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount, const std::string& feeaddress); std::vector omni_getwalletbalances(bool includewatchonly); + std::vector omni_getwalletaddressbalances(bool includewatchonly); + omni_balance_t omni_getbalance(const std::string& address, int propertyid); std::vector omni_listtransactions(const std::string& txid = "*", int count = 10, int skip = 0, int startblock = 0, int endblock = 999999999); std::vector omni_listpendingtransactions(const std::string& address = ""); diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index 6a06a19..55818a6 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -275,6 +275,11 @@ std::string name; }; + struct omni_address_balance_t{ + std::string address; + std::vector balances; + }; + #endif From 8d06585f54f67492de3464abdaa6a9513361a490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Wed, 23 Jan 2019 21:27:51 +0300 Subject: [PATCH 12/18] Added getaddressinfo function --- src/bitcoinapi/bitcoinapi.cpp | 18 ++++++++++++++++++ src/bitcoinapi/bitcoinapi.h | 1 + src/bitcoinapi/types.h | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 8c47780..2ec8c2b 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -366,6 +366,24 @@ string BitcoinAPI::getnewaddress(const string& account) { return result.asString(); } +getaddressinfo_t BitcoinAPI::getaddressinfo(const string& bitcoinaddress) { + string command = "getaddressinfo"; + Value params, result; + getaddressinfo_t ret; + + params.append(bitcoinaddress); + result = sendcommand(command, params); + + ret.address = result["address"].asString(); + ret.scriptPubKey = result["scriptPubKey"].asString(); + ret.ismine = result["ismine"].asBool(); + ret.isscript = result["isscript"].asBool(); + ret.iswatchonly = result["iswatchonly"].asBool(); + ret.iswitness = result["iswitness"].asBool(); + + return ret; +} + validateaddress_t BitcoinAPI::validateaddress(const string& bitcoinaddress) { string command = "validateaddress"; Value params, result; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index e2cc1d3..39b6370 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -74,6 +74,7 @@ class BitcoinAPI multisig_t createmultisig(int nrequired, const std::vector& keys); std::string getnewaddress(const std::string& account = ""); validateaddress_t validateaddress(const std::string& bitcoinaddress); + getaddressinfo_t getaddressinfo(const std::string& bitcoinaddress); void keypoolrefill(); bool settxfee(double amount); diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index 8f7b191..dbe3f94 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -106,6 +106,39 @@ bool iswatchonly; }; + struct getaddressinfo_t { + std::string address; + std::string scriptPubKey; + bool ismine; + bool iswatchonly; + bool isscript; + bool iswitness; + /* + double witness_version; + std::string witness_program; + std::string script; + std::string hex; + std::vector pubkeys; + double sigsrequired; + std::string pubkey; + "embedded" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all getaddressinfo output fields for the embedded address, excluding metadata ("timestamp", "hdkeypath", "hdseedid") and relation to the wallet ("ismine", "iswatchonly", "account"). + "iscompressed" : true|false, (boolean) If the address is compressed + "label" : "label" (string) The label associated with the address, "" is the default account + "account" : "account" (string) DEPRECATED. This field will be removed in V0.18. To see this deprecated field, start bitcoind with -deprecatedrpc=accounts. The account associated with the address, "" is the default account + "timestamp" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT) + "hdkeypath" : "keypath" (string, optional) The HD keypath if the key is HD and available + "hdseedid" : "" (string, optional) The Hash160 of the HD seed + "hdmasterkeyid" : "" (string, optional) alias for hdseedid maintained for backwards compatibility. Will be removed in V0.18. + "labels" (object) Array of labels associated with the address. + [ + { (json object of label data) + "name": "labelname" (string) The label + "purpose": "string" (string) Purpose of address ("send" for sending address, "receive" for receiving address) + },... + ] + */ + }; + struct addressgrouping_t{ std::string address; double balance; From ddf4c55541142d33fccb73e0d9d8d79ab4c73bda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Sat, 26 Jan 2019 10:50:15 +0300 Subject: [PATCH 13/18] Added omni_gettransaction method --- src/bitcoinapi/bitcoinapi.cpp | 32 +++++++++++++++++++++++++++++++- src/bitcoinapi/bitcoinapi.h | 1 + 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 8576253..9fcf29a 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -373,7 +373,7 @@ getaddressinfo_t BitcoinAPI::getaddressinfo(const string& bitcoinaddress) { params.append(bitcoinaddress); result = sendcommand(command, params); - + ret.address = result["address"].asString(); ret.scriptPubKey = result["scriptPubKey"].asString(); ret.ismine = result["ismine"].asBool(); @@ -1420,6 +1420,36 @@ utxosetinfo_t BitcoinAPI::gettxoutsetinfo() { #ifdef _OMNI_SUPPORT_ +omni_transaction_t BitcoinAPI::omni_gettransaction(const std::string& txid) +{ + string command = "omni_gettransaction"; + Value params, result; + omni_transaction_t ret; + + params.append(txid); + + result = sendcommand(command, params); + + ret.txid = result["txid"].asString(); + ret.sendingaddress = result["sendingaddress"].asString(); + ret.referenceaddress = result["referenceaddress"].asString(); + ret.ismine = result["ismine"].asBool(); + ret.confirmations = result["confirmations"].asInt(); + ret.fee = stod(result["fee"].asString()); + ret.blocktime = result["blocktime"].asUInt(); + ret.valid = result["valid"].asBool(); + ret.positioninblock = result["positioninblock"].asUInt(); + ret.version = result["version"].asInt(); + ret.type_int = result["type_int"].asInt(); + ret.type = result["type"].asString(); + + ret.amount = stod(result["amount"].asString()); + ret.blockhash = result["blockhash"].asString(); + ret.block = result["block"].asUInt(); + + return ret; +} + std::string BitcoinAPI::omni_send(const std::string& fromaddress, const std::string& toaddress, int propertyid, double amount) { string command = "omni_send"; diff --git a/src/bitcoinapi/bitcoinapi.h b/src/bitcoinapi/bitcoinapi.h index 5d3bbb5..610eb9b 100644 --- a/src/bitcoinapi/bitcoinapi.h +++ b/src/bitcoinapi/bitcoinapi.h @@ -39,6 +39,7 @@ class BitcoinAPI std::vector omni_getwalletaddressbalances(bool includewatchonly); omni_balance_t omni_getbalance(const std::string& address, int propertyid); + omni_transaction_t omni_gettransaction(const std::string& txid); std::vector omni_listtransactions(const std::string& txid = "*", int count = 10, int skip = 0, int startblock = 0, int endblock = 999999999); std::vector omni_listpendingtransactions(const std::string& address = ""); From 8cabcdd0c834f1c773bb1dcacfe0700a3bde1f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Mon, 4 Feb 2019 17:20:12 +0300 Subject: [PATCH 14/18] Updated omni_transaction struct --- src/bitcoinapi/bitcoinapi.cpp | 83 ++++++++++++++++++++++++++++++----- src/bitcoinapi/types.h | 10 +++++ 2 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 9fcf29a..d85796d 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -30,6 +30,11 @@ using std::map; using std::string; using std::vector; +#ifdef _OMNI_SUPPORT_ +#define OMNI_TYPE_SIMPLE_SEND 0 +#define OMNI_TYPE_SEND_ALL 4 +#endif + BitcoinAPI::BitcoinAPI(const string& user, const string& password, const string& host, int port, int httpTimeout) : httpClient(new HttpClient("http://" + user + ":" + password + "@" + host + ":" + IntegerToString(port))), @@ -902,6 +907,7 @@ vector BitcoinAPI::listunspent(int minconf, int maxconf, const v tmp.scriptPubKey = val["scriptPubKey"].asString(); tmp.amount = val["amount"].asDouble(); tmp.confirmations = val["confirmations"].asInt(); + tmp.spendable = val["spendable"].asBool(); ret.push_back(tmp); } @@ -1442,11 +1448,38 @@ omni_transaction_t BitcoinAPI::omni_gettransaction(const std::string& txid) ret.version = result["version"].asInt(); ret.type_int = result["type_int"].asInt(); ret.type = result["type"].asString(); - - ret.amount = stod(result["amount"].asString()); ret.blockhash = result["blockhash"].asString(); ret.block = result["block"].asUInt(); + if(ret.type_int == OMNI_TYPE_SIMPLE_SEND) + { + ret.propertyid = result["propertyid"].asInt(); + ret.amount = stod(result["amount"].asString()); + } + else if (ret.type_int == OMNI_TYPE_SEND_ALL) + { + for(ValueIterator it2 = result["subsends"].begin(); it2 != result["subsends"].end(); it2++) + { + omni_subsend_t tmp2; + Value val2 = (*it2); + tmp2.propertyid = val2["propertyid"].asInt(); + tmp2.divisible = val2["divisible"].asBool(); + tmp2.amount = stod(val2["amount"].asString()); + ret.subsends.push_back(tmp2); + } + } + else + { + ret.propertyid = result["propertyid"].asInt(); + // let's just try to parse + try{ + ret.amount = stod(result["amount"].asString()); + } + catch (std::invalid_argument e) { + ret.amount = 0; + } + } + return ret; } @@ -1509,13 +1542,13 @@ std::vector BitcoinAPI::omni_getwalletaddressbalances(bo for(ValueIterator it2 = val["balances"].begin(); it2 != val["balances"].end(); it2++){ omni_detailed_balance_t tmp2; - Value val = (*it2); + Value val2 = (*it2); - tmp2.balance = stod(val["balance"].asString()); - tmp2.reserved = stod(val["reserved"].asString()); - tmp2.frozen = stod(val["frozen"].asString()); - tmp2.name = val["name"].asString(); - tmp2.propertyid = val["propertyid"].asInt(); + tmp2.balance = stod(val2["balance"].asString()); + tmp2.reserved = stod(val2["reserved"].asString()); + tmp2.frozen = stod(val2["frozen"].asString()); + tmp2.name = val2["name"].asString(); + tmp2.propertyid = val2["propertyid"].asInt(); tmp.balances.push_back(tmp2); } @@ -1590,7 +1623,6 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str tmp.referenceaddress = val["referenceaddress"].asString(); tmp.ismine = val["ismine"].asBool(); tmp.confirmations = val["confirmations"].asInt(); - tmp.propertyid = val["propertyid"].asInt(); tmp.fee = stod(val["fee"].asString()); tmp.blocktime = val["blocktime"].asUInt(); tmp.valid = val["valid"].asBool(); @@ -1598,11 +1630,40 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str tmp.version = val["version"].asInt(); tmp.type_int = val["type_int"].asInt(); tmp.type = val["type"].asString(); - - tmp.amount = stod(val["amount"].asString()); tmp.blockhash = val["blockhash"].asString(); tmp.block = val["block"].asUInt(); + if(tmp.type_int == OMNI_TYPE_SIMPLE_SEND) + { + tmp.propertyid = val["propertyid"].asInt(); + tmp.amount = stod(val["amount"].asString()); + } + else if (tmp.type_int == OMNI_TYPE_SEND_ALL) + { + for(ValueIterator it2 = val["subsends"].begin(); it2 != val["subsends"].end(); it2++) + { + omni_subsend_t tmp2; + Value val2 = (*it2); + tmp2.propertyid = val2["propertyid"].asInt(); + tmp2.divisible = val2["divisible"].asBool(); + tmp2.amount = stod(val2["amount"].asString()); + tmp.subsends.push_back(tmp2); + } + } + else + { + tmp.propertyid = val["propertyid"].asInt(); + // let's just try to parse + try{ + + tmp.amount = stod(val["amount"].asString()); + } + catch (std::invalid_argument e) { + tmp.amount = 0; + } + + } + ret.push_back(tmp); } diff --git a/src/bitcoinapi/types.h b/src/bitcoinapi/types.h index ad35278..c7650b9 100644 --- a/src/bitcoinapi/types.h +++ b/src/bitcoinapi/types.h @@ -273,12 +273,19 @@ std::string address; std::string account; std::string scriptPubKey; + bool spendable; double amount; int confirmations; }; #ifdef _OMNI_SUPPORT_ + struct omni_subsend_t { + int propertyid; + bool divisible; + double amount; + }; + struct omni_transaction_t { std::string txid; std::string sendingaddress; @@ -296,8 +303,11 @@ int version; int type_int; std::string type; + std::vector subsends; }; + + struct omni_balance_t { double balance; double reserved; From 2fa4f7ff3cbef762228b3f9b579453120aa7d22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Wed, 6 Feb 2019 23:53:42 +0300 Subject: [PATCH 15/18] Used JsonValue references instead of copying --- src/bitcoinapi/bitcoinapi.cpp | 55 +++++++++++++++++------------------ 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index d85796d..7f06706 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -142,7 +142,7 @@ vector BitcoinAPI::getaddednodeinfo(bool dns) { result = sendcommand(command, params); for (ValueIterator it1 = result.begin(); it1 != result.end(); it1++) { - Value val1 = (*it1); + Value &val1 = (*it1); nodeinfo_t node; node.addednode = val1["addednode"].asString(); @@ -151,7 +151,7 @@ vector BitcoinAPI::getaddednodeinfo(bool dns) { node.connected = val1["connected"].asBool(); for (ValueIterator it2 = val1["addresses"].begin(); it2 != val1["addresses"].end(); it2++) { - Value val2 = (*it2); + Value &val2 = (*it2); netaddress_t net; net.address = val2["address"].asString(); @@ -178,7 +178,7 @@ vector BitcoinAPI::getaddednodeinfo(bool dns, const std::string& nod result = sendcommand(command, params); for (ValueIterator it1 = result.begin(); it1 != result.end(); it1++) { - Value val1 = (*it1); + Value &val1 = (*it1); nodeinfo_t node; node.addednode = val1["addednode"].asString(); @@ -187,7 +187,7 @@ vector BitcoinAPI::getaddednodeinfo(bool dns, const std::string& nod node.connected = val1["connected"].asBool(); for (ValueIterator it2 = val1["addresses"].begin(); it2 != val1["addresses"].end(); it2++) { - Value val2 = (*it2); + Value &val2 = (*it2); netaddress_t net; net.address = val2["address"].asString(); @@ -218,7 +218,7 @@ vector BitcoinAPI::getpeerinfo() { result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - Value val = (*it); + Value &val = (*it); peerinfo_t peer; peer.addr = val["addr"].asString(); @@ -518,7 +518,7 @@ vector BitcoinAPI::listreceivedbyaccount(int minconf, bool includ result = sendcommand(command, params); for (ValueIterator it = result.begin(); it != result.end(); it++) { - Value val = (*it); + Value &val = (*it); accountinfo_t acct; acct.account = val["account"].asString(); acct.amount = val["amount"].asDouble(); @@ -583,7 +583,7 @@ gettransaction_t BitcoinAPI::gettransaction(const string& tx, bool watch) { for (ValueIterator it = result["details"].begin(); it != result["details"].end(); it++) { - Value val = (*it); + Value &val = (*it); transactiondetails_t tmp; tmp.account = val["account"].asString(); tmp.address = val["address"].asString(); @@ -608,7 +608,7 @@ vector BitcoinAPI::listtransactions() { result = sendcommand(command, params); for (ValueIterator it = result.begin(); it != result.end(); it++) { - Value val = (*it); + Value &val = (*it); transactioninfo_t tmp; tmp.account = val["account"].asString(); @@ -647,7 +647,7 @@ vector BitcoinAPI::listtransactions(const string& account, in result = sendcommand(command, params); for (ValueIterator it = result.begin(); it != result.end(); it++) { - Value val = (*it); + Value &val = (*it); transactioninfo_t tmp; tmp.account = val["account"].asString(); @@ -717,7 +717,7 @@ map BitcoinAPI::listaccounts(int minconf) { result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - Value val = (*it); + Value &val = (*it); std::pair tmp; tmp.first = it.key().asString(); @@ -735,11 +735,11 @@ vector< vector > BitcoinAPI::listaddressgroupings() { result = sendcommand(command, params); for(ValueIterator it1 = result.begin(); it1 != result.end(); it1++){ - Value val1 = (*it1); + Value &val1 = (*it1); vector tmp1; for(ValueIterator it2 = val1.begin(); it2 != val1.end(); it2++){ - Value val2 = (*it2); + Value &val2 = (*it2); addressgrouping_t tmp2; tmp2.address = val2.operator []((uint)0).asString(); @@ -897,7 +897,7 @@ vector BitcoinAPI::listunspent(int minconf, int maxconf, const v result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - Value val = (*it); + Value &val = (*it); unspenttxout_t tmp; tmp.txid = val["txid"].asString(); @@ -927,7 +927,7 @@ vector BitcoinAPI::listlockunspent() { result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - Value val = (*it); + Value &val = (*it); txout_t tmp; tmp.txid = val["txid"].asString(); @@ -1073,7 +1073,7 @@ txsinceblock_t BitcoinAPI::listsinceblock(const string& blockhash, int target_co result = sendcommand(command, params); for(ValueIterator it = result["transactions"].begin(); it != result["transactions"].end(); it++){ - Value val = (*it); + Value &val = (*it); transactioninfo_t tmp; tmp.involvesWatchonly = val["involvesWatchonly"].asBool(); @@ -1123,7 +1123,7 @@ getrawtransaction_t BitcoinAPI::getrawtransaction(const string& txid, int verbos ret.locktime = result["locktime"].asInt(); for (ValueIterator it = result["vin"].begin(); it != result["vin"].end(); it++) { - Value val = (*it); + Value &val = (*it); vin_t input; input.txid = val["txid"].asString(); input.n = val["vout"].asUInt(); @@ -1135,7 +1135,7 @@ getrawtransaction_t BitcoinAPI::getrawtransaction(const string& txid, int verbos for (ValueIterator it = result["vout"].begin(); it != result["vout"].end(); it++) { - Value val = (*it); + Value &val = (*it); vout_t output; output.value = val["value"].asDouble(); @@ -1174,7 +1174,7 @@ decodescript_t BitcoinAPI::decodescript(const std::string& hexString) { ret.p2sh = result["p2sh"].asString(); for (ValueIterator it = result["addresses"].begin(); it != result["addresses"].end(); it++) { - Value val = (*it); + Value &val = (*it); ret.addresses.push_back(val.asString()); } @@ -1194,7 +1194,7 @@ decoderawtransaction_t BitcoinAPI::decoderawtransaction(const string& hexString) ret.locktime = result["locktime"].asInt(); for (ValueIterator it = result["vin"].begin(); it != result["vin"].end(); it++) { - Value val = (*it); + Value &val = (*it); vin_t input; input.txid = val["txid"].asString(); input.n = val["vout"].asUInt(); @@ -1206,7 +1206,7 @@ decoderawtransaction_t BitcoinAPI::decoderawtransaction(const string& hexString) for (ValueIterator it = result["vout"].begin(); it != result["vout"].end(); it++) { - Value val = (*it); + Value &val = (*it); vout_t output; output.value = val["value"].asDouble(); @@ -1461,7 +1461,7 @@ omni_transaction_t BitcoinAPI::omni_gettransaction(const std::string& txid) for(ValueIterator it2 = result["subsends"].begin(); it2 != result["subsends"].end(); it2++) { omni_subsend_t tmp2; - Value val2 = (*it2); + Value &val2 = (*it2); tmp2.propertyid = val2["propertyid"].asInt(); tmp2.divisible = val2["divisible"].asBool(); tmp2.amount = stod(val2["amount"].asString()); @@ -1537,12 +1537,12 @@ std::vector BitcoinAPI::omni_getwalletaddressbalances(bo for(ValueIterator it = result.begin(); it != result.end(); it++){ omni_address_balance_t tmp; - Value val = (*it); + Value &val = (*it); tmp.address = val["address"].asString(); for(ValueIterator it2 = val["balances"].begin(); it2 != val["balances"].end(); it2++){ omni_detailed_balance_t tmp2; - Value val2 = (*it2); + Value &val2 = (*it2); tmp2.balance = stod(val2["balance"].asString()); tmp2.reserved = stod(val2["reserved"].asString()); @@ -1570,7 +1570,7 @@ std::vector BitcoinAPI::omni_getwalletbalances(bool inc for(ValueIterator it = result.begin(); it != result.end(); it++){ omni_detailed_balance_t tmp; - Value val = (*it); + Value &val = (*it); tmp.balance = stod(val["balance"].asString()); tmp.reserved = stod(val["reserved"].asString()); @@ -1617,7 +1617,7 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str for(ValueIterator it = result.begin(); it != result.end(); it++){ omni_transaction_t tmp; - Value val = (*it); + Value &val = (*it); tmp.txid = val["txid"].asString(); tmp.sendingaddress = val["sendingaddress"].asString(); tmp.referenceaddress = val["referenceaddress"].asString(); @@ -1643,7 +1643,7 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str for(ValueIterator it2 = val["subsends"].begin(); it2 != val["subsends"].end(); it2++) { omni_subsend_t tmp2; - Value val2 = (*it2); + Value &val2 = (*it2); tmp2.propertyid = val2["propertyid"].asInt(); tmp2.divisible = val2["divisible"].asBool(); tmp2.amount = stod(val2["amount"].asString()); @@ -1655,7 +1655,6 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str tmp.propertyid = val["propertyid"].asInt(); // let's just try to parse try{ - tmp.amount = stod(val["amount"].asString()); } catch (std::invalid_argument e) { @@ -1681,7 +1680,7 @@ std::vector BitcoinAPI::omni_listpendingtransactions(const s for(ValueIterator it = result.begin(); it != result.end(); it++) { omni_transaction_t tmp; - Value val = (*it); + Value &val = (*it); tmp.txid = val["txid"].asString(); tmp.sendingaddress = val["sendingaddress"].asString(); tmp.referenceaddress = val["referenceaddress"].asString(); From 62eb42c8036915cbb6ff6cee10c2db21c7799cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Wed, 6 Feb 2019 23:54:59 +0300 Subject: [PATCH 16/18] Removed unused variable --- src/bitcoinapi/bitcoinapi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 7f06706..7c54519 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -717,7 +717,7 @@ map BitcoinAPI::listaccounts(int minconf) { result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - Value &val = (*it); + // Value &val = (*it); std::pair tmp; tmp.first = it.key().asString(); From fa0248fdf9eac5ee7824f48d209f331ace4234e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Tue, 26 Feb 2019 01:28:52 +0300 Subject: [PATCH 17/18] Fixed omni_listpendingtransactions deserialization bug --- src/bitcoinapi/bitcoinapi.cpp | 39 +++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 7c54519..0676965 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1678,7 +1678,7 @@ std::vector BitcoinAPI::omni_listpendingtransactions(const s params.append(address); result = sendcommand(command, params); - for(ValueIterator it = result.begin(); it != result.end(); it++) { + for(ValueIterator it = result.begin(); it != result.end(); it++){ omni_transaction_t tmp; Value &val = (*it); tmp.txid = val["txid"].asString(); @@ -1686,15 +1686,46 @@ std::vector BitcoinAPI::omni_listpendingtransactions(const s tmp.referenceaddress = val["referenceaddress"].asString(); tmp.ismine = val["ismine"].asBool(); tmp.confirmations = val["confirmations"].asInt(); - tmp.propertyid = val["propertyid"].asInt(); tmp.fee = stod(val["fee"].asString()); tmp.blocktime = val["blocktime"].asUInt(); + tmp.valid = val["valid"].asBool(); + tmp.positioninblock = val["positioninblock"].asUInt(); tmp.version = val["version"].asInt(); tmp.type_int = val["type_int"].asInt(); tmp.type = val["type"].asString(); + tmp.blockhash = val["blockhash"].asString(); + tmp.block = val["block"].asUInt(); - tmp.amount = stod(val["amount"].asString()); - + if(tmp.type_int == OMNI_TYPE_SIMPLE_SEND) + { + tmp.propertyid = val["propertyid"].asInt(); + tmp.amount = stod(val["amount"].asString()); + } + else if (tmp.type_int == OMNI_TYPE_SEND_ALL) + { + for(ValueIterator it2 = val["subsends"].begin(); it2 != val["subsends"].end(); it2++) + { + omni_subsend_t tmp2; + Value &val2 = (*it2); + tmp2.propertyid = val2["propertyid"].asInt(); + tmp2.divisible = val2["divisible"].asBool(); + tmp2.amount = stod(val2["amount"].asString()); + tmp.subsends.push_back(tmp2); + } + } + else + { + tmp.propertyid = val["propertyid"].asInt(); + // let's just try to parse + try{ + tmp.amount = stod(val["amount"].asString()); + } + catch (std::invalid_argument e) { + tmp.amount = 0; + } + + } + ret.push_back(tmp); } From 2273e6063d7912847653c813f910180dc12420d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bahad=C4=B1r=20Bozda=C4=9F?= Date: Thu, 28 Feb 2019 00:06:11 +0300 Subject: [PATCH 18/18] Fixed omni_transaction parsing bug. added type checks --- src/bitcoinapi/bitcoinapi.cpp | 149 +++++++++++++--------------------- 1 file changed, 55 insertions(+), 94 deletions(-) diff --git a/src/bitcoinapi/bitcoinapi.cpp b/src/bitcoinapi/bitcoinapi.cpp index 0676965..71b7c8f 100644 --- a/src/bitcoinapi/bitcoinapi.cpp +++ b/src/bitcoinapi/bitcoinapi.cpp @@ -1602,6 +1602,58 @@ omni_balance_t BitcoinAPI::omni_getbalance(const std::string& address, int prope return ret; } +omni_transaction_t omni_parsetransaction(const ValueIterator& it) +{ + omni_transaction_t tmp; + Value &val = (*it); + tmp.txid = val["txid"].asString(); + tmp.sendingaddress = val["sendingaddress"].asString(); + tmp.referenceaddress = val["referenceaddress"].asString(); + tmp.ismine = val["ismine"].asBool(); + tmp.fee = stod(val["fee"].asString()); + tmp.version = val["version"].asInt(); + tmp.type_int = val["type_int"].asInt(); + tmp.type = val["type"].asString(); + + tmp.confirmations = val["confirmations"].isInt() ? val["confirmations"].asInt() : 0; + tmp.blocktime = val["blocktime"].isUInt() ? val["blocktime"].asUInt() : 0; + tmp.valid = val["valid"].isBool() ? val["valid"].asBool() : false; + tmp.positioninblock = val["positioninblock"].isUInt() ? val["positioninblock"].asUInt() : 0; + tmp.blockhash = val["blockhash"].isString() ? val["blockhash"].asString() : ""; + tmp.block = val["block"].isUInt() ? val["block"].asUInt() : 0; + + if(tmp.type_int == OMNI_TYPE_SIMPLE_SEND) + { + tmp.propertyid = val["propertyid"].isInt() ? val["propertyid"].asInt() : 0; + tmp.amount = val["amount"].isString() ? stod(val["amount"].asString()) : 0; + } + else if (tmp.type_int == OMNI_TYPE_SEND_ALL) + { + for(ValueIterator it2 = val["subsends"].begin(); it2 != val["subsends"].end(); it2++) + { + omni_subsend_t tmp2; + Value &val2 = (*it2); + tmp2.propertyid = val2["propertyid"].isInt() ? val2["propertyid"].asInt() : 0; + tmp2.divisible = val2["divisible"].isBool() ? val2["divisible"].asBool() : false; + tmp2.amount = val2["amount"].isString() ? stod(val2["amount"].asString()) : 0; + tmp.subsends.push_back(tmp2); + } + } + else + { + tmp.propertyid = val["propertyid"].isInt() ? val["propertyid"].asInt() : 0; + // let's just try to parse + try{ + tmp.amount = stod(val["amount"].asString()); + } + catch (std::invalid_argument e) { + tmp.amount = 0; + } + } + + return tmp; +} + std::vector BitcoinAPI::omni_listtransactions(const std::string& txid, int count, int skip, int startblock, int endblock) { string command = "omni_listtransactions"; @@ -1616,59 +1668,14 @@ std::vector BitcoinAPI::omni_listtransactions(const std::str result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - omni_transaction_t tmp; - Value &val = (*it); - tmp.txid = val["txid"].asString(); - tmp.sendingaddress = val["sendingaddress"].asString(); - tmp.referenceaddress = val["referenceaddress"].asString(); - tmp.ismine = val["ismine"].asBool(); - tmp.confirmations = val["confirmations"].asInt(); - tmp.fee = stod(val["fee"].asString()); - tmp.blocktime = val["blocktime"].asUInt(); - tmp.valid = val["valid"].asBool(); - tmp.positioninblock = val["positioninblock"].asUInt(); - tmp.version = val["version"].asInt(); - tmp.type_int = val["type_int"].asInt(); - tmp.type = val["type"].asString(); - tmp.blockhash = val["blockhash"].asString(); - tmp.block = val["block"].asUInt(); - - if(tmp.type_int == OMNI_TYPE_SIMPLE_SEND) - { - tmp.propertyid = val["propertyid"].asInt(); - tmp.amount = stod(val["amount"].asString()); - } - else if (tmp.type_int == OMNI_TYPE_SEND_ALL) - { - for(ValueIterator it2 = val["subsends"].begin(); it2 != val["subsends"].end(); it2++) - { - omni_subsend_t tmp2; - Value &val2 = (*it2); - tmp2.propertyid = val2["propertyid"].asInt(); - tmp2.divisible = val2["divisible"].asBool(); - tmp2.amount = stod(val2["amount"].asString()); - tmp.subsends.push_back(tmp2); - } - } - else - { - tmp.propertyid = val["propertyid"].asInt(); - // let's just try to parse - try{ - tmp.amount = stod(val["amount"].asString()); - } - catch (std::invalid_argument e) { - tmp.amount = 0; - } - - } - + omni_transaction_t tmp = omni_parsetransaction(it); ret.push_back(tmp); } return ret; } + std::vector BitcoinAPI::omni_listpendingtransactions(const std::string& address) { string command = "omni_listpendingtransactions"; @@ -1679,53 +1686,7 @@ std::vector BitcoinAPI::omni_listpendingtransactions(const s result = sendcommand(command, params); for(ValueIterator it = result.begin(); it != result.end(); it++){ - omni_transaction_t tmp; - Value &val = (*it); - tmp.txid = val["txid"].asString(); - tmp.sendingaddress = val["sendingaddress"].asString(); - tmp.referenceaddress = val["referenceaddress"].asString(); - tmp.ismine = val["ismine"].asBool(); - tmp.confirmations = val["confirmations"].asInt(); - tmp.fee = stod(val["fee"].asString()); - tmp.blocktime = val["blocktime"].asUInt(); - tmp.valid = val["valid"].asBool(); - tmp.positioninblock = val["positioninblock"].asUInt(); - tmp.version = val["version"].asInt(); - tmp.type_int = val["type_int"].asInt(); - tmp.type = val["type"].asString(); - tmp.blockhash = val["blockhash"].asString(); - tmp.block = val["block"].asUInt(); - - if(tmp.type_int == OMNI_TYPE_SIMPLE_SEND) - { - tmp.propertyid = val["propertyid"].asInt(); - tmp.amount = stod(val["amount"].asString()); - } - else if (tmp.type_int == OMNI_TYPE_SEND_ALL) - { - for(ValueIterator it2 = val["subsends"].begin(); it2 != val["subsends"].end(); it2++) - { - omni_subsend_t tmp2; - Value &val2 = (*it2); - tmp2.propertyid = val2["propertyid"].asInt(); - tmp2.divisible = val2["divisible"].asBool(); - tmp2.amount = stod(val2["amount"].asString()); - tmp.subsends.push_back(tmp2); - } - } - else - { - tmp.propertyid = val["propertyid"].asInt(); - // let's just try to parse - try{ - tmp.amount = stod(val["amount"].asString()); - } - catch (std::invalid_argument e) { - tmp.amount = 0; - } - - } - + omni_transaction_t tmp = omni_parsetransaction(it); ret.push_back(tmp); }