#define CROW_ENABLE_SSL #include "ext/crow/crow.h" #include "src/CmdLineOptions.h" #include "src/MicroCore.h" #include "src/page.h" #include "ext/member_checker.h" #include using boost::filesystem::path; using namespace std; int main(int ac, const char* av[]) { // get command line options xmreg::CmdLineOptions opts {ac, av}; auto help_opt = opts.get_option("help"); auto testnet_opt = opts.get_option("testnet"); auto enable_pusher_opt = opts.get_option("enable-pusher"); // if help was chosen, display help text and finish if (*help_opt) { return EXIT_SUCCESS; } bool testnet {*testnet_opt}; bool enable_pusher {*enable_pusher_opt}; auto port_opt = opts.get_option("port"); auto bc_path_opt = opts.get_option("bc-path"); auto custom_db_path_opt = opts.get_option("custom-db-path"); auto deamon_url_opt = opts.get_option("deamon-url"); auto ssl_crt_file_opt = opts.get_option("ssl-crt-file"); auto ssl_key_file_opt = opts.get_option("ssl-key-file"); // set monero log output level uint32_t log_level = 0; mlog_configure("", true); //cast port number in string to uint16 uint16_t app_port = boost::lexical_cast(*port_opt); bool use_ssl {false}; string ssl_crt_file; string ssl_key_file; // check if ssl enabled and files exist if (ssl_crt_file_opt and ssl_key_file_opt) { if (!boost::filesystem::exists(boost::filesystem::path(*ssl_crt_file_opt))) { cerr << "ssl_crt_file path: " << *ssl_crt_file_opt << "does not exist!" << endl; return EXIT_FAILURE; } if (!boost::filesystem::exists(boost::filesystem::path(*ssl_key_file_opt))) { cerr << "ssl_key_file path: " << *ssl_key_file_opt << "does not exist!" << endl; return EXIT_FAILURE; } ssl_crt_file = *ssl_crt_file_opt; ssl_key_file = *ssl_key_file_opt; use_ssl = true; } // get blockchain path path blockchain_path; if (!xmreg::get_blockchain_path(bc_path_opt, blockchain_path, testnet)) { cerr << "Error getting blockchain path." << endl; return EXIT_FAILURE; } cout << blockchain_path << endl; // create instance of our MicroCore // and make pointer to the Blockchain xmreg::MicroCore mcore; cryptonote::Blockchain* core_storage; // initialize mcore and core_storage if (!xmreg::init_blockchain(blockchain_path.string(), mcore, core_storage)) { cerr << "Error accessing blockchain." << endl; return EXIT_FAILURE; } // check if we have path to lmdb2 (i.e., custom db) // and if it exists string custom_db_path_str; if (custom_db_path_opt) { if (boost::filesystem::exists(boost::filesystem::path(*custom_db_path_opt))) { custom_db_path_str = *custom_db_path_opt; } else { cerr << "Custom db path: " << *custom_db_path_opt << "does not exist" << endl; return EXIT_FAILURE; } } else { // if not given assume it is located in ~./bitmonero/lmdb2 folder // or ~./bitmonero/testnet/lmdb2 for testnet network custom_db_path_str = blockchain_path.parent_path().string() + string("/lmdb2"); } custom_db_path_str = xmreg::remove_trailing_path_separator(custom_db_path_str); string deamon_url {*deamon_url_opt}; if (testnet && deamon_url == "http:://127.0.0.1:18081") deamon_url = "http:://127.0.0.1:28081"; // create instance of page class which // contains logic for the website xmreg::page xmrblocks(&mcore, core_storage, deamon_url, custom_db_path_str, testnet, enable_pusher); // crow instance crow::SimpleApp app; CROW_ROUTE(app, "/") ([&](const crow::request& req) { return crow::response(xmrblocks.index2()); }); CROW_ROUTE(app, "/page/") ([&](size_t page_no) { return xmrblocks.index2(page_no); }); CROW_ROUTE(app, "/block/") ([&](const crow::request& req, size_t block_height) { return crow::response(xmrblocks.show_block(block_height)); }); CROW_ROUTE(app, "/block/") ([&](const crow::request& req, string block_hash) { return crow::response(xmrblocks.show_block(block_hash)); }); CROW_ROUTE(app, "/tx/") ([&](const crow::request& req, string tx_hash) { return crow::response(xmrblocks.show_tx(tx_hash)); }); CROW_ROUTE(app, "/tx//") ([&](string tx_hash, uint16_t with_ring_signatures) { return xmrblocks.show_tx(tx_hash, with_ring_signatures); }); CROW_ROUTE(app, "/myoutputs").methods("POST"_method) ([&](const crow::request& req) { map post_body = xmreg::parse_crow_post_data(req.body); if (post_body.count("xmr_address") == 0 || post_body.count("viewkey") == 0 || post_body.count("tx_hash") == 0) { return string("xmr address, viewkey or tx hash not provided"); } string tx_hash = post_body["tx_hash"]; string xmr_address = post_body["xmr_address"]; string viewkey = post_body["viewkey"]; // this will be only not empty when checking raw tx data // using tx pusher string raw_tx_data = post_body["raw_tx_data"]; return xmrblocks.show_my_outputs(tx_hash, xmr_address, viewkey, raw_tx_data); }); CROW_ROUTE(app, "/prove").methods("POST"_method) ([&](const crow::request& req) { map post_body = xmreg::parse_crow_post_data(req.body); if (post_body.count("xmraddress") == 0 || post_body.count("txprvkey") == 0 || post_body.count("txhash") == 0) { return string("xmr address, tx private key or tx hash not provided"); } string tx_hash = post_body["txhash"];; string tx_prv_key = post_body["txprvkey"];; string xmr_address = post_body["xmraddress"];; return xmrblocks.show_prove(tx_hash, xmr_address, tx_prv_key); }); CROW_ROUTE(app, "/rawtx") ([&](const crow::request& req) { return xmrblocks.show_rawtx(); }); CROW_ROUTE(app, "/checkandpush").methods("POST"_method) ([&](const crow::request& req) { map post_body = xmreg::parse_crow_post_data(req.body); if (post_body.count("rawtxdata") == 0 || post_body.count("action") == 0) { return string("Raw tx data or action not provided"); } string raw_tx_data = post_body["rawtxdata"]; string action = post_body["action"]; if (action == "check") return xmrblocks.show_checkrawtx(raw_tx_data, action); else if (action == "push") return xmrblocks.show_pushrawtx(raw_tx_data, action); }); CROW_ROUTE(app, "/rawkeyimgs") ([&](const crow::request& req) { return xmrblocks.show_rawkeyimgs(); }); CROW_ROUTE(app, "/checkrawkeyimgs").methods("POST"_method) ([&](const crow::request& req) { map post_body = xmreg::parse_crow_post_data(req.body); if (post_body.count("rawkeyimgsdata") == 0) { return string("Raw key images data not given"); } if (post_body.count("viewkey") == 0) { return string("Viewkey not provided. Cant decrypt key image file without it"); } string raw_data = post_body["rawkeyimgsdata"]; string viewkey = post_body["viewkey"]; return xmrblocks.show_checkrawkeyimgs(raw_data, viewkey); }); CROW_ROUTE(app, "/rawoutputkeys") ([&](const crow::request& req) { return xmrblocks.show_rawoutputkeys(); }); CROW_ROUTE(app, "/checkrawoutputkeys").methods("POST"_method) ([&](const crow::request& req) { map post_body = xmreg::parse_crow_post_data(req.body); if (post_body.count("rawoutputkeysdata") == 0) { return string("Raw output keys data not given"); } if (post_body.count("viewkey") == 0) { return string("Viewkey not provided. Cant decrypt key image file without it"); } string raw_data = post_body["rawoutputkeysdata"]; string viewkey = post_body["viewkey"]; return xmrblocks.show_checkcheckrawoutput(raw_data, viewkey); }); CROW_ROUTE(app, "/search").methods("GET"_method) ([&](const crow::request& req) { return xmrblocks.search(string(req.url_params.get("value"))); }); CROW_ROUTE(app, "/mempool") ([&](const crow::request& req) { return xmrblocks.mempool(true); }); CROW_ROUTE(app, "/robots.txt") ([&]() { string text = "User-agent: *\n" "Disallow: "; return text; }); CROW_ROUTE(app, "/autorefresh") ([&]() { uint64_t page_no {0}; bool refresh_page {true}; return xmrblocks.index2(page_no, refresh_page); }); // run the crow http server if (use_ssl) { cout << "Staring in ssl mode" << endl; app.port(app_port).ssl_file(ssl_crt_file, ssl_key_file).multithreaded().run(); } else { cout << "Staring in non-ssl mode" << endl; app.port(app_port).multithreaded().run(); } return EXIT_SUCCESS; }