#include #include "subscription.h" using namespace std; using namespace CryptoPP; int main() { Json::Value root = coinbase::GetSubscribeMsg(); Json::StyledStreamWriter writer; writer.write(cout,root); Json::FastWriter fastWriter; string buf = fastWriter.write(root); cout << buf << endl; Json::Value responseRoot; string response = R"({"type":"error","message":"authentication failure"})"; Json::Reader reader; reader.parse(response, responseRoot); writer.write(cout, responseRoot); if (responseRoot["type"] == "error") cout << "error: " << responseRoot["message"] << endl; // CryptoPP tests //------------------------------------------------------------------------------ string digest; string secret = "s146NOJtMeGgZ6SbIRblSJCWIcMUCauX"; string signature = "1673628642level2BTC-USD"; try { CryptoPP::HMAC< CryptoPP::SHA256 > hmac((const unsigned char*)secret.c_str(), secret.size()); CryptoPP::StringSource ss2(signature, true, new CryptoPP::HashFilter(hmac, new CryptoPP::StringSink(digest))); } catch(const CryptoPP::Exception& e) { std::cerr << e.what() << std::endl; exit(1); } std::string hex; CryptoPP::StringSource ss5(digest, true, new CryptoPP::HexEncoder( new CryptoPP::StringSink(hex))); std::transform(hex.begin(), hex.end(), hex.begin(), [](unsigned char c){ return std::tolower(c); }); cout << "signature: " << signature << endl; cout << "secret: " << secret << endl; cout << "hex: " << hex << endl; // Json parse tests //--------------------------------------------------------------------------------------------- { using clock = std::chrono::system_clock; std::time_t now = clock::to_time_t(clock::now()); cout << "now: " << now << endl; } string update = R"({ "type": "update", "product_id": "BTC-USD", "updates": [ { "side" : "bid", "new_quantity" : "10101.80000000", "price_level" : "0.162567", "event_time" : "2023-01-14T20:42:27.265Z" }, { "side": "ask", "new_quantity" : "20202.90000000", "price_level" : "0.174567", "event_time" : "2023-01-14T20:42:27.265Z" } ] })"; Json::Value r; cout << "update:\n" << update << endl; reader.parse(update, r); cout << "update:" << endl; Json::StyledStreamWriter writer1; writer1.write(cout, r); cout << "--- updates ----" << endl; Json::Value updates = r["updates"]; cout << "updates isArray(): " << updates.isArray() << endl; cout << "updates array size: " << updates.size() << endl; for (auto i: updates) // updates is array of obj { // iterator references an obj writer1.write(cout, i); cout << "side: " << i["side"] << endl; cout << "px : " << i["price_level"] << endl; cout << "qty : " << i["new_quantity"] << endl; } // coinbase ISO timestamp parsing //--------------------------------------------------------------- cout << "------ Timestamp tests ---------" << endl; string timestamp = "2023-01-17T14:55:43.782908368Z"; size_t pos = timestamp.find_first_of('.'); string YMD_HMS = timestamp.substr(0, pos); string microsStr = timestamp.substr(pos + 1); microsStr.erase(microsStr.size() - 1); cout << timestamp << endl << YMD_HMS << endl << "micros: " << microsStr << "\n------" << endl; std::tm t = {}; std::istringstream ss(YMD_HMS); ss >> std::get_time(&t, "%Y-%m-%dT%H:%M:%S"); time_t secondsSinceEpoch = mktime(&t); if (ss.fail()) std::cout << "Parse failed\n"; else { std::cout << "parsed time: " << std::put_time(&t, "%c") << '\n'; } int64_t micros = atol(microsStr.c_str()); int64_t nanos = micros * 1000; int64_t secondsInNanos = secondsSinceEpoch * 1E9; int64_t secondsInMicros = secondsSinceEpoch * 1E6; int64_t nanosSinceEpoch = secondsInNanos + nanos; int64_t microsSinceEpoch = secondsInMicros + micros; cout << "secondsSinceEpoch from mktime: " << secondsSinceEpoch << endl; cout << "secondsSinceEpochInNanos: " << secondsInNanos << endl; cout << "micros part of timestamp: " << micros << endl; cout << "nanos part of timestamp: " << nanos << endl; cout << "microsSinceEpoch: " << microsSinceEpoch << endl; cout << " nanosSinceEpoch: " << nanosSinceEpoch << endl; cout << " INT64_MAX: " << INT64_MAX << endl; }