2020-01-14 23:27:49 +01:00
|
|
|
// Copyright (c) 2014-2020 Zano Project
|
|
|
|
|
// Distributed under the MIT/X11 software license, see the accompanying
|
|
|
|
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
|
|
|
|
|
|
|
|
|
|
2020-06-02 19:25:28 +02:00
|
|
|
#ifdef ANDROID_BUILD
|
2020-06-02 19:48:58 +02:00
|
|
|
#include <android/log.h>
|
2020-06-02 19:25:28 +02:00
|
|
|
#endif
|
2020-01-14 23:27:49 +01:00
|
|
|
#include "plain_wallet_api.h"
|
2020-04-06 22:17:18 +02:00
|
|
|
#include "plain_wallet_api_defs.h"
|
2020-01-28 18:23:09 +01:00
|
|
|
#include "currency_core/currency_config.h"
|
|
|
|
|
#include "version.h"
|
2020-02-27 21:45:46 +01:00
|
|
|
#include "string_tools.h"
|
2020-02-03 19:28:05 +01:00
|
|
|
#include "currency_core/currency_format_utils.h"
|
2020-02-11 01:14:28 +01:00
|
|
|
#include "wallets_manager.h"
|
2020-03-20 04:19:25 +01:00
|
|
|
#include "common/base58.h"
|
|
|
|
|
#include "common/config_encrypt_helper.h"
|
2020-05-17 21:38:36 +02:00
|
|
|
#include "static_helpers.h"
|
|
|
|
|
|
2020-01-14 23:27:49 +01:00
|
|
|
|
2020-02-21 19:29:46 +01:00
|
|
|
#define ANDROID_PACKAGE_NAME "com.zano_mobile"
|
2020-03-26 04:34:09 +01:00
|
|
|
|
|
|
|
|
#define LOGS_FOLDER "logs"
|
|
|
|
|
|
2020-02-10 22:47:06 +01:00
|
|
|
#define WALLETS_FOLDER_NAME "wallets"
|
2020-03-11 04:23:25 +01:00
|
|
|
#define APP_CONFIG_FOLDER "app_config"
|
2020-03-20 04:19:25 +01:00
|
|
|
#define APP_CONFIG_FILENAME "app_cfg.bin"
|
|
|
|
|
|
|
|
|
|
#define MOBILE_APP_DATA_FILE_BINARY_SIGNATURE 0x1000111201101011LL //Bender's nightmare
|
2020-01-28 00:47:44 +01:00
|
|
|
|
|
|
|
|
#define GENERAL_INTERNAL_ERRROR_INSTANCE "GENERAL_INTERNAL_ERROR: WALLET INSTNACE NOT FOUND"
|
2020-02-11 01:14:28 +01:00
|
|
|
#define GENERAL_INTERNAL_ERRROR_INIT "Failed to intialize library"
|
2020-01-28 00:47:44 +01:00
|
|
|
|
2020-03-26 04:34:09 +01:00
|
|
|
//TODO: global objects, subject to refactoring
|
2020-02-27 02:11:13 +01:00
|
|
|
|
2020-05-17 15:12:34 +02:00
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
struct plain_wallet_instance
|
|
|
|
|
{
|
|
|
|
|
plain_wallet_instance() :initialized(false), gjobs_counter(1)
|
|
|
|
|
{}
|
|
|
|
|
wallets_manager gwm;
|
|
|
|
|
std::atomic<bool> initialized;
|
|
|
|
|
|
|
|
|
|
std::atomic<uint64_t> gjobs_counter;
|
|
|
|
|
std::map<uint64_t, std::string> gjobs;
|
|
|
|
|
epee::critical_section gjobs_lock;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<plain_wallet_instance> ginstance_ptr;
|
|
|
|
|
|
2020-05-14 19:23:17 +02:00
|
|
|
#define GET_INSTANCE_PTR(ptr_name) \
|
|
|
|
|
auto ptr_name = std::atomic_load(&ginstance_ptr); \
|
|
|
|
|
if (!ptr_name) \
|
|
|
|
|
{ \
|
|
|
|
|
LOG_ERROR("Core already deinitialised or not initialized yet."); \
|
|
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response); \
|
|
|
|
|
ok_response.result.return_code = API_RETURN_CODE_UNINITIALIZED; \
|
|
|
|
|
return epee::serialization::store_t_to_json(ok_response); \
|
|
|
|
|
}
|
2020-05-14 20:05:52 +02:00
|
|
|
namespace plain_wallet
|
|
|
|
|
{
|
|
|
|
|
void deinit();
|
|
|
|
|
}
|
2020-05-17 15:12:34 +02:00
|
|
|
|
2020-05-17 21:38:36 +02:00
|
|
|
void static_destroy_handler()
|
|
|
|
|
{
|
2020-06-02 19:25:28 +02:00
|
|
|
LOG_PRINT_L0("[DESTROY CALLBACK HANDLER STARTED]: ");
|
2020-05-14 20:05:52 +02:00
|
|
|
plain_wallet::deinit();
|
2020-06-02 19:25:28 +02:00
|
|
|
LOG_PRINT_L0("[DESTROY CALLBACK HANDLER FINISHED]: ");
|
2020-05-17 15:12:34 +02:00
|
|
|
}
|
2020-05-17 21:38:36 +02:00
|
|
|
|
2020-01-15 22:06:49 +01:00
|
|
|
namespace plain_wallet
|
2020-01-14 23:27:49 +01:00
|
|
|
{
|
2020-02-11 01:14:28 +01:00
|
|
|
typedef epee::json_rpc::response<epee::json_rpc::dummy_result, error> error_response;
|
|
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
|
|
|
|
|
std::string get_set_working_dir(bool need_to_set = false, const std::string val = "")
|
|
|
|
|
{
|
2020-05-17 23:15:50 +02:00
|
|
|
DEFINE_SECURE_STATIC_VAR(std::string, working_dir);
|
2020-05-13 22:01:40 +02:00
|
|
|
if (need_to_set)
|
|
|
|
|
working_dir = val;
|
|
|
|
|
return working_dir;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-26 04:34:09 +01:00
|
|
|
std::string get_bundle_working_dir()
|
2020-01-28 18:23:09 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
return get_set_working_dir();
|
2020-03-26 04:34:09 +01:00
|
|
|
}
|
|
|
|
|
void set_bundle_working_dir(const std::string& dir)
|
|
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
get_set_working_dir(true, dir);
|
2020-01-28 21:56:17 +01:00
|
|
|
}
|
2020-02-01 19:43:57 +01:00
|
|
|
|
|
|
|
|
std::string get_wallets_folder()
|
|
|
|
|
{
|
2020-02-13 01:44:30 +01:00
|
|
|
#ifdef WIN32
|
|
|
|
|
return "";
|
2020-02-23 06:26:12 +01:00
|
|
|
#else
|
2020-03-26 04:34:09 +01:00
|
|
|
std::string path = get_bundle_working_dir() + "/" + WALLETS_FOLDER_NAME + "/";
|
2020-02-10 22:47:06 +01:00
|
|
|
return path;
|
2020-02-23 06:26:12 +01:00
|
|
|
#endif // WIN32
|
2020-02-01 19:43:57 +01:00
|
|
|
}
|
2020-01-28 21:56:17 +01:00
|
|
|
|
2020-03-11 04:23:25 +01:00
|
|
|
std::string get_app_config_folder()
|
|
|
|
|
{
|
|
|
|
|
#ifdef WIN32
|
|
|
|
|
return "";
|
|
|
|
|
#else
|
2020-03-26 04:34:09 +01:00
|
|
|
std::string path = get_bundle_working_dir() + "/" + APP_CONFIG_FOLDER + "/";
|
2020-03-11 04:23:25 +01:00
|
|
|
return path;
|
|
|
|
|
#endif // WIN32
|
|
|
|
|
}
|
2020-06-02 19:25:28 +02:00
|
|
|
#ifdef ANDROID_BUILD
|
|
|
|
|
class android_logger : public log_space::ibase_log_stream
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
int get_type() { return LOGGER_CONSOLE; }
|
|
|
|
|
virtual bool out_buffer(const char* buffer, int buffer_len, int log_level, int color, const char* plog_name = NULL)
|
|
|
|
|
{
|
|
|
|
|
__android_log_write(ANDROID_LOG_INFO, "[tag]", buffer);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
#endif
|
2020-03-11 04:23:25 +01:00
|
|
|
|
2020-03-11 02:08:33 +01:00
|
|
|
void initialize_logs(int log_level)
|
2020-02-03 19:28:05 +01:00
|
|
|
{
|
2020-03-26 04:34:09 +01:00
|
|
|
std::string log_dir = get_bundle_working_dir();
|
|
|
|
|
log_dir += "/" LOGS_FOLDER;
|
2020-03-15 06:14:08 +01:00
|
|
|
|
|
|
|
|
log_space::get_set_need_thread_id(true, true);
|
|
|
|
|
log_space::log_singletone::enable_channels("core,currency_protocol,tx_pool,p2p,wallet");
|
2020-03-11 02:08:33 +01:00
|
|
|
epee::log_space::get_set_log_detalisation_level(true, log_level);
|
2020-06-02 19:25:28 +02:00
|
|
|
#ifdef ANDROID_BUILD
|
|
|
|
|
epee::log_space::log_singletone::add_logger(new android_logger());
|
|
|
|
|
#else
|
2020-02-11 03:46:47 +01:00
|
|
|
epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
2020-06-02 19:25:28 +02:00
|
|
|
#endif
|
|
|
|
|
|
2020-02-11 03:46:47 +01:00
|
|
|
epee::log_space::log_singletone::add_logger(LOGGER_FILE, "plain_wallet.log", log_dir.c_str());
|
|
|
|
|
LOG_PRINT_L0("Plain wallet initialized: " << CURRENCY_NAME << " v" << PROJECT_VERSION_LONG << ", log location: " << log_dir + "/plain_wallet.log");
|
|
|
|
|
|
|
|
|
|
//glogs_initialized = true;
|
2020-02-03 19:28:05 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-11 02:08:33 +01:00
|
|
|
std::string set_log_level(int log_level)
|
|
|
|
|
{
|
|
|
|
|
epee::log_space::get_set_log_detalisation_level(true, log_level);
|
|
|
|
|
return "{}";
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
void deinit()
|
|
|
|
|
{
|
|
|
|
|
auto local_ptr = std::atomic_load(&ginstance_ptr);
|
|
|
|
|
if (local_ptr)
|
|
|
|
|
{
|
|
|
|
|
std::atomic_store(&ginstance_ptr, std::shared_ptr<plain_wallet_instance>());
|
|
|
|
|
//wait other callers finish
|
|
|
|
|
local_ptr->gjobs_lock.lock();
|
|
|
|
|
local_ptr->gjobs_lock.unlock();
|
2020-05-14 19:23:17 +02:00
|
|
|
bool r = local_ptr->gwm.quick_stop_no_save();
|
2020-06-02 19:25:28 +02:00
|
|
|
LOG_PRINT_L0("[QUICK_STOP_NO_SAVE] return " << r);
|
2020-05-14 19:23:17 +02:00
|
|
|
//let's prepare wallet manager for quick shutdown
|
2020-05-13 22:01:40 +02:00
|
|
|
local_ptr.reset();
|
2020-05-14 19:23:17 +02:00
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
}
|
|
|
|
|
}
|
2020-06-02 00:19:54 +02:00
|
|
|
|
|
|
|
|
std::string reset()
|
|
|
|
|
{
|
|
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
inst_ptr->gwm.quick_stop_no_save();
|
|
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
|
|
|
|
ok_response.result.return_code = API_RETURN_CODE_OK;
|
|
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
|
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
|
2020-03-26 04:34:09 +01:00
|
|
|
std::string init(const std::string& ip, const std::string& port, const std::string& working_dir, int log_level)
|
2020-02-11 01:14:28 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
auto local_ptr = std::atomic_load(&ginstance_ptr);
|
|
|
|
|
if (local_ptr)
|
2020-02-11 17:13:03 +01:00
|
|
|
{
|
|
|
|
|
LOG_ERROR("Double-initialization in plain_wallet detected.");
|
2020-03-20 01:20:27 +01:00
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
|
|
|
|
ok_response.result.return_code = API_RETURN_CODE_ALREADY_EXISTS;
|
|
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
2020-02-11 17:13:03 +01:00
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
|
2020-05-17 21:38:36 +02:00
|
|
|
epee::static_helpers::set_or_call_on_destruct(true, static_destroy_handler);
|
|
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
std::cout << "[INIT PLAIN_WALLET_INSTANCE]" << ENDL;
|
|
|
|
|
std::shared_ptr<plain_wallet_instance> ptr(new plain_wallet_instance());
|
|
|
|
|
|
2020-03-26 04:34:09 +01:00
|
|
|
set_bundle_working_dir(working_dir);
|
2020-02-11 17:13:03 +01:00
|
|
|
|
2020-03-11 02:08:33 +01:00
|
|
|
initialize_logs(log_level);
|
2020-02-12 20:36:54 +01:00
|
|
|
std::string argss_1 = std::string("--remote-node=") + ip + ":" + port;
|
2020-03-15 06:14:08 +01:00
|
|
|
std::string argss_2 = std::string("--disable-logs-init");
|
|
|
|
|
char * args[4];
|
2020-03-27 01:48:31 +03:00
|
|
|
static const char* arg0_stub = "stub";
|
|
|
|
|
args[0] = const_cast<char*>(arg0_stub);
|
2020-02-11 04:07:32 +01:00
|
|
|
args[1] = const_cast<char*>(argss_1.c_str());
|
2020-03-15 06:14:08 +01:00
|
|
|
args[2] = const_cast<char*>(argss_2.c_str());
|
|
|
|
|
args[3] = nullptr;
|
2020-05-13 22:01:40 +02:00
|
|
|
if (!ptr->gwm.init(3, args, nullptr))
|
2020-02-11 01:14:28 +01:00
|
|
|
{
|
|
|
|
|
LOG_ERROR("Failed to init wallets_manager");
|
|
|
|
|
return GENERAL_INTERNAL_ERRROR_INIT;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
if(!ptr->gwm.start())
|
2020-02-11 01:14:28 +01:00
|
|
|
{
|
|
|
|
|
LOG_ERROR("Failed to start wallets_manager");
|
|
|
|
|
return GENERAL_INTERNAL_ERRROR_INIT;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-11 04:55:09 +01:00
|
|
|
std::string wallets_folder = get_wallets_folder();
|
2020-03-11 04:23:25 +01:00
|
|
|
boost::system::error_code ec;
|
2020-03-11 04:55:09 +01:00
|
|
|
boost::filesystem::create_directories(wallets_folder, ec);
|
2020-03-14 03:02:47 +01:00
|
|
|
if (ec)
|
|
|
|
|
{
|
|
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
|
|
|
|
err_result.error.code = API_RETURN_CODE_INTERNAL_ERROR;
|
|
|
|
|
err_result.error.message = LOCATION_STR + " \nmessage:" + ec.message();
|
|
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
|
|
|
|
}
|
2020-03-11 04:23:25 +01:00
|
|
|
|
|
|
|
|
std::string app_config_folder = get_app_config_folder();
|
|
|
|
|
boost::filesystem::create_directories(app_config_folder, ec);
|
2020-03-14 03:02:47 +01:00
|
|
|
if (ec)
|
|
|
|
|
{
|
|
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
|
|
|
|
err_result.error.code = API_RETURN_CODE_INTERNAL_ERROR;
|
|
|
|
|
err_result.error.message = LOCATION_STR + " \nmessage:" + ec.message();
|
|
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
|
|
|
|
}
|
2020-03-11 04:23:25 +01:00
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
std::atomic_store(&ginstance_ptr, ptr);
|
2020-03-14 03:02:47 +01:00
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
|
|
|
|
ok_response.result.return_code = API_RETURN_CODE_OK;
|
|
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
2020-02-11 01:14:28 +01:00
|
|
|
}
|
|
|
|
|
|
2020-03-20 04:19:25 +01:00
|
|
|
std::string get_appconfig(const std::string& encryption_key)
|
2020-03-11 04:23:25 +01:00
|
|
|
{
|
2020-03-20 04:19:25 +01:00
|
|
|
std::string res_str;
|
2020-03-11 04:23:25 +01:00
|
|
|
std::string app_config_config_path = get_app_config_folder() + APP_CONFIG_FILENAME;
|
2020-03-20 04:19:25 +01:00
|
|
|
std::string ret_code = tools::load_encrypted_file(app_config_config_path, encryption_key, res_str, MOBILE_APP_DATA_FILE_BINARY_SIGNATURE);
|
|
|
|
|
if (ret_code != API_RETURN_CODE_OK)
|
|
|
|
|
{
|
|
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
|
|
|
|
err_result.error.code = ret_code;
|
|
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
|
|
|
|
}
|
2020-03-11 04:23:25 +01:00
|
|
|
return res_str;
|
|
|
|
|
}
|
2020-03-20 04:19:25 +01:00
|
|
|
std::string set_appconfig(const std::string& conf_str, const std::string& encryption_key)
|
2020-03-11 04:23:25 +01:00
|
|
|
{
|
|
|
|
|
std::string app_config_config_path = get_app_config_folder() + APP_CONFIG_FILENAME;
|
2020-03-20 04:19:25 +01:00
|
|
|
std::string ret_code = tools::store_encrypted_file(app_config_config_path, encryption_key, conf_str, MOBILE_APP_DATA_FILE_BINARY_SIGNATURE);
|
|
|
|
|
if (ret_code != API_RETURN_CODE_OK)
|
2020-03-11 04:23:25 +01:00
|
|
|
{
|
|
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
2020-03-20 04:19:25 +01:00
|
|
|
err_result.error.code = ret_code;
|
2020-03-11 04:23:25 +01:00
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
2020-03-11 04:40:10 +01:00
|
|
|
ok_response.result.return_code = API_RETURN_CODE_OK;
|
2020-03-11 04:23:25 +01:00
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
|
|
|
|
}
|
2020-03-20 04:19:25 +01:00
|
|
|
}
|
2020-03-11 04:23:25 +01:00
|
|
|
|
2020-03-20 04:19:25 +01:00
|
|
|
std::string generate_random_key(uint64_t lenght)
|
|
|
|
|
{
|
|
|
|
|
std::string buff;
|
|
|
|
|
buff.resize(lenght);
|
|
|
|
|
crypto::generate_random_bytes(lenght, const_cast<char*>(buff.data()));
|
|
|
|
|
return tools::base58::encode(buff);
|
2020-03-11 04:23:25 +01:00
|
|
|
}
|
2020-01-28 18:23:09 +01:00
|
|
|
|
2020-03-15 06:14:08 +01:00
|
|
|
std::string get_logs_buffer()
|
|
|
|
|
{
|
|
|
|
|
return epee::log_space::log_singletone::copy_logs_to_buffer();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string truncate_log()
|
|
|
|
|
{
|
|
|
|
|
epee::log_space::log_singletone::truncate_log_files();
|
|
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
|
|
|
|
ok_response.result.return_code = API_RETURN_CODE_OK;
|
|
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-06 22:17:18 +02:00
|
|
|
std::string get_connectivity_status()
|
|
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
|
|
|
|
|
return inst_ptr->gwm.get_connectivity_status();
|
2020-04-06 22:17:18 +02:00
|
|
|
}
|
2020-01-28 18:23:09 +01:00
|
|
|
|
2020-01-28 21:37:04 +01:00
|
|
|
std::string get_version()
|
|
|
|
|
{
|
|
|
|
|
return PROJECT_VERSION_LONG;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-28 21:56:17 +01:00
|
|
|
struct strings_list
|
|
|
|
|
{
|
|
|
|
|
std::list<std::string> items;
|
|
|
|
|
|
|
|
|
|
BEGIN_KV_SERIALIZE_MAP()
|
|
|
|
|
KV_SERIALIZE(items)
|
|
|
|
|
END_KV_SERIALIZE_MAP()
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
std::string get_wallet_files()
|
|
|
|
|
{
|
2020-02-01 19:43:57 +01:00
|
|
|
std::string wallet_files_path = get_wallets_folder();
|
2020-01-28 21:56:17 +01:00
|
|
|
strings_list sl = AUTO_VAL_INIT(sl);
|
|
|
|
|
epee::file_io_utils::get_folder_content(wallet_files_path, sl.items, true);
|
|
|
|
|
return epee::serialization::store_t_to_json(sl);
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-10 21:51:23 +02:00
|
|
|
std::string delete_wallet(const std::string& file_name)
|
|
|
|
|
{
|
|
|
|
|
std::string wallet_files_path = get_wallets_folder();
|
|
|
|
|
strings_list sl = AUTO_VAL_INIT(sl);
|
|
|
|
|
boost::system::error_code er;
|
|
|
|
|
boost::filesystem::remove(wallet_files_path + file_name, er);
|
|
|
|
|
epee::json_rpc::response<view::api_responce_return_code, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
|
|
|
|
ok_response.result.return_code = API_RETURN_CODE_OK;
|
|
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-11 01:14:28 +01:00
|
|
|
std::string open(const std::string& path, const std::string& password)
|
|
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
|
2020-02-13 01:44:30 +01:00
|
|
|
std::string full_path = get_wallets_folder() + path;
|
2020-02-11 01:14:28 +01:00
|
|
|
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
2020-05-13 22:01:40 +02:00
|
|
|
std::string rsp = inst_ptr->gwm.open_wallet(epee::string_encoding::convert_to_unicode(full_path), password, 20, ok_response.result);
|
2020-02-11 01:14:28 +01:00
|
|
|
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
2020-01-28 00:47:44 +01:00
|
|
|
{
|
2020-02-11 01:14:28 +01:00
|
|
|
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
|
|
|
|
{
|
|
|
|
|
ok_response.result.recovered = true;
|
|
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
2020-02-13 01:44:30 +01:00
|
|
|
|
2020-02-11 01:14:28 +01:00
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
2020-01-28 00:47:44 +01:00
|
|
|
}
|
2020-02-11 01:14:28 +01:00
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
|
|
|
|
err_result.error.code = rsp;
|
|
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
2020-01-14 23:27:49 +01:00
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
|
2020-02-11 01:14:28 +01:00
|
|
|
std::string restore(const std::string& seed, const std::string& path, const std::string& password)
|
2020-01-14 23:27:49 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
|
2020-02-13 01:44:30 +01:00
|
|
|
std::string full_path = get_wallets_folder() + path;
|
2020-02-11 01:14:28 +01:00
|
|
|
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
2020-05-27 23:49:34 +03:00
|
|
|
std::string rsp = inst_ptr->gwm.restore_wallet(epee::string_encoding::convert_to_unicode(full_path), password, seed, false, ok_response.result);
|
2020-02-11 01:14:28 +01:00
|
|
|
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
|
|
|
|
{
|
|
|
|
|
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
|
|
|
|
{
|
|
|
|
|
ok_response.result.recovered = true;
|
|
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
2020-02-11 01:14:28 +01:00
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
|
|
|
|
}
|
|
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
|
|
|
|
err_result.error.code = rsp;
|
|
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
2020-02-01 23:47:37 +01:00
|
|
|
}
|
2020-02-01 23:49:59 +01:00
|
|
|
|
2020-02-12 00:30:04 +01:00
|
|
|
std::string generate(const std::string& path, const std::string& password)
|
2020-01-15 22:06:49 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
|
2020-02-13 01:44:30 +01:00
|
|
|
std::string full_path = get_wallets_folder() + path;
|
2020-02-11 01:14:28 +01:00
|
|
|
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
2020-05-13 22:01:40 +02:00
|
|
|
std::string rsp = inst_ptr->gwm.generate_wallet(epee::string_encoding::convert_to_unicode(full_path), password, ok_response.result);
|
2020-02-11 01:14:28 +01:00
|
|
|
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
|
|
|
|
{
|
|
|
|
|
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
|
|
|
|
{
|
|
|
|
|
ok_response.result.recovered = true;
|
|
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
inst_ptr->gwm.run_wallet(ok_response.result.wallet_id);
|
2020-02-11 01:14:28 +01:00
|
|
|
return epee::serialization::store_t_to_json(ok_response);
|
|
|
|
|
}
|
|
|
|
|
error_response err_result = AUTO_VAL_INIT(err_result);
|
|
|
|
|
err_result.error.code = rsp;
|
|
|
|
|
return epee::serialization::store_t_to_json(err_result);
|
|
|
|
|
}
|
2020-02-11 17:06:14 +01:00
|
|
|
|
|
|
|
|
std::string close_wallet(hwallet h)
|
|
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
|
2020-02-28 11:20:02 +01:00
|
|
|
std::string r = "{\"response\": \"";
|
2020-05-13 22:01:40 +02:00
|
|
|
r += inst_ptr->gwm.close_wallet(h);
|
2020-02-28 11:20:02 +01:00
|
|
|
r += "\"}";
|
|
|
|
|
return r;
|
2020-02-11 17:06:14 +01:00
|
|
|
}
|
|
|
|
|
|
2020-02-11 03:10:27 +01:00
|
|
|
std::string get_wallet_status(hwallet h)
|
|
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
return inst_ptr->gwm.get_wallet_status(h);
|
2020-02-11 03:10:27 +01:00
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
|
2020-01-14 23:27:49 +01:00
|
|
|
std::string invoke(hwallet h, const std::string& params)
|
|
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
|
|
|
|
return inst_ptr->gwm.invoke(h, params);
|
2020-01-14 23:27:49 +01:00
|
|
|
}
|
2020-02-27 02:11:13 +01:00
|
|
|
|
2020-02-27 21:45:46 +01:00
|
|
|
void put_result(uint64_t job_id, const std::string& res)
|
2020-02-27 02:11:13 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
auto inst_ptr = std::atomic_load(&ginstance_ptr);
|
|
|
|
|
if (!inst_ptr)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
CRITICAL_REGION_LOCAL(inst_ptr->gjobs_lock);
|
|
|
|
|
inst_ptr->gjobs[job_id] = res;
|
2020-05-07 23:26:41 +02:00
|
|
|
LOG_PRINT_L2("[ASYNC_CALL]: Finished(result put), job id: " << job_id);
|
2020-02-27 02:11:13 +01:00
|
|
|
}
|
|
|
|
|
|
2020-02-28 07:38:40 +01:00
|
|
|
std::string async_call(const std::string& method_name, uint64_t instance_id, const std::string& params)
|
2020-02-27 02:11:13 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
GET_INSTANCE_PTR(inst_ptr);
|
2020-02-27 02:11:13 +01:00
|
|
|
std::function<void()> async_callback;
|
|
|
|
|
|
2020-05-13 22:01:40 +02:00
|
|
|
uint64_t job_id = inst_ptr->gjobs_counter++;
|
2020-02-28 12:28:00 +01:00
|
|
|
if (method_name == "close")
|
2020-02-27 02:11:13 +01:00
|
|
|
{
|
2020-02-27 21:45:46 +01:00
|
|
|
async_callback = [job_id, instance_id]()
|
2020-02-27 02:12:42 +01:00
|
|
|
{
|
2020-02-27 21:45:46 +01:00
|
|
|
close_wallet(instance_id);
|
|
|
|
|
view::api_responce_return_code rc = AUTO_VAL_INIT(rc);
|
|
|
|
|
rc.return_code = API_RETURN_CODE_OK;
|
|
|
|
|
put_result(job_id, epee::serialization::store_t_to_json(rc));
|
2020-02-27 02:11:13 +01:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
else if (method_name == "open")
|
|
|
|
|
{
|
2020-02-27 21:45:46 +01:00
|
|
|
view::open_wallet_request owr = AUTO_VAL_INIT(owr);
|
|
|
|
|
if (!epee::serialization::load_t_from_json(owr, params))
|
|
|
|
|
{
|
|
|
|
|
view::api_response ar = AUTO_VAL_INIT(ar);
|
|
|
|
|
ar.error_code = "Wrong parameter";
|
|
|
|
|
put_result(job_id, epee::serialization::store_t_to_json(ar));
|
|
|
|
|
}
|
|
|
|
|
async_callback = [job_id, owr]()
|
|
|
|
|
{
|
|
|
|
|
std::string res = open(owr.path, owr.pass);
|
|
|
|
|
put_result(job_id, res);
|
|
|
|
|
};
|
2020-02-27 02:11:13 +01:00
|
|
|
}
|
2020-02-27 21:45:46 +01:00
|
|
|
else if (method_name == "restore")
|
|
|
|
|
{
|
|
|
|
|
view::restore_wallet_request rwr = AUTO_VAL_INIT(rwr);
|
|
|
|
|
if (!epee::serialization::load_t_from_json(rwr, params))
|
|
|
|
|
{
|
|
|
|
|
view::api_response ar = AUTO_VAL_INIT(ar);
|
|
|
|
|
ar.error_code = "Wrong parameter";
|
|
|
|
|
put_result(job_id, epee::serialization::store_t_to_json(ar));
|
|
|
|
|
}
|
|
|
|
|
async_callback = [job_id, rwr]()
|
|
|
|
|
{
|
|
|
|
|
std::string res = restore(rwr.restore_key, rwr.path, rwr.pass);
|
|
|
|
|
put_result(job_id, res);
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
else if (method_name == "invoke")
|
|
|
|
|
{
|
2020-02-28 12:28:00 +01:00
|
|
|
std::string local_params = params;
|
2020-02-27 21:45:46 +01:00
|
|
|
async_callback = [job_id, local_params, instance_id]()
|
|
|
|
|
{
|
|
|
|
|
std::string res = invoke(instance_id, local_params);
|
|
|
|
|
put_result(job_id, res);
|
|
|
|
|
};
|
|
|
|
|
}
|
2020-04-02 22:26:14 +02:00
|
|
|
else if (method_name == "get_wallet_status")
|
|
|
|
|
{
|
|
|
|
|
std::string local_params = params;
|
|
|
|
|
async_callback = [job_id, local_params, instance_id]()
|
|
|
|
|
{
|
|
|
|
|
std::string res = get_wallet_status(instance_id);
|
|
|
|
|
put_result(job_id, res);
|
|
|
|
|
};
|
|
|
|
|
}else
|
2020-02-28 12:28:00 +01:00
|
|
|
{
|
|
|
|
|
view::api_response ar = AUTO_VAL_INIT(ar);
|
|
|
|
|
ar.error_code = "UNKNOWN METHOD";
|
|
|
|
|
put_result(job_id, epee::serialization::store_t_to_json(ar));
|
2020-02-28 12:32:05 +01:00
|
|
|
return std::string("{ \"job_id\": ") + std::to_string(job_id) + "}";;
|
2020-02-28 12:28:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2020-02-28 05:37:53 +01:00
|
|
|
std::thread t([async_callback]() {async_callback(); });
|
|
|
|
|
t.detach();
|
2020-05-07 23:26:41 +02:00
|
|
|
LOG_PRINT_L2("[ASYNC_CALL]: started " << method_name << ", job id: " << job_id);
|
2020-02-28 07:38:40 +01:00
|
|
|
return std::string("{ \"job_id\": ") + std::to_string(job_id) + "}";
|
2020-02-27 02:11:13 +01:00
|
|
|
}
|
2020-02-28 12:28:00 +01:00
|
|
|
|
2020-02-27 21:45:46 +01:00
|
|
|
std::string try_pull_result(uint64_t job_id)
|
2020-02-27 02:11:13 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
auto inst_ptr = std::atomic_load(&ginstance_ptr);
|
|
|
|
|
if (!inst_ptr)
|
|
|
|
|
{
|
|
|
|
|
return "{\"status\": \"canceled\"}";
|
|
|
|
|
}
|
2020-02-27 21:45:46 +01:00
|
|
|
//TODO: need refactoring
|
2020-05-13 22:01:40 +02:00
|
|
|
CRITICAL_REGION_LOCAL(inst_ptr->gjobs_lock);
|
|
|
|
|
auto it = inst_ptr->gjobs.find(job_id);
|
|
|
|
|
if (it == inst_ptr->gjobs.end())
|
2020-02-27 21:45:46 +01:00
|
|
|
{
|
2020-05-13 22:01:40 +02:00
|
|
|
return "{\"status\": \"idle\"}";
|
2020-02-27 21:45:46 +01:00
|
|
|
}
|
2020-05-13 22:01:40 +02:00
|
|
|
std::string res = "{\"status\": \"delivered\", \"result\": ";
|
2020-02-27 21:45:46 +01:00
|
|
|
res += it->second;
|
|
|
|
|
res += " }";
|
2020-05-13 22:01:40 +02:00
|
|
|
inst_ptr->gjobs.erase(it);
|
2020-02-27 21:45:46 +01:00
|
|
|
return res;
|
2020-02-27 02:11:13 +01:00
|
|
|
}
|
|
|
|
|
|
2020-01-14 23:27:49 +01:00
|
|
|
}
|