mirror of https://github.com/oxen-io/oxen-core.git
Add standalone LNS signature generator for CLI/RPC wallet
This commit is contained in:
parent
5dd5723332
commit
68782a76df
|
@ -273,6 +273,9 @@ namespace
|
|||
|
||||
const char* USAGE_LNS_BUY_MAPPING("lns_buy_mapping [index=<N1>[,<N2>,...]] [<priority>] [owner=] [backup_owner=] \"<name>\" <value>");
|
||||
const char* USAGE_LNS_UPDATE_MAPPING("lns_update_mapping [index=<N1>[,<N2>,...]] [<priority>] \"<name>\" <value> [<signature>]");
|
||||
|
||||
// TODO(loki): Currently defaults to session, in future allow specifying Lokinet and Wallet when they are enabled
|
||||
const char* USAGE_LNS_MAKE_UPDATE_MAPPING_SIGNATURE("lns_make_update_mapping_signature \"<name>\" <new_value>");
|
||||
const char* USAGE_LNS_PRINT_OWNERS_TO_NAMES("lns_print_owners_to_names [<64 hex character ed25519 public key>]");
|
||||
const char* USAGE_LNS_PRINT_NAME_TO_OWNERS("lns_print_name_to_owners [type=<N1|all>[,<N2>...]] \"name\"");
|
||||
|
||||
|
@ -6542,6 +6545,37 @@ bool simple_wallet::lns_update_mapping(const std::vector<std::string>& args)
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::lns_make_updating_mapping_signature(const std::vector<std::string> &args)
|
||||
{
|
||||
if (!try_connect_to_daemon())
|
||||
return true;
|
||||
|
||||
if (args.size() < 3)
|
||||
{
|
||||
PRINT_USAGE(USAGE_LNS_MAKE_UPDATE_MAPPING_SIGNATURE);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string const &new_value = args[args.size() - 1];
|
||||
std::string name;
|
||||
if (!parse_lns_name_string(args, 0, (args.size() - 2), name))
|
||||
{
|
||||
PRINT_USAGE(USAGE_LNS_MAKE_UPDATE_MAPPING_SIGNATURE);
|
||||
fail_msg_writer() << "lns name didn't start or end with quotation marks (\")";
|
||||
return true;
|
||||
}
|
||||
|
||||
SCOPED_WALLET_UNLOCK();
|
||||
crypto::generic_signature signature;
|
||||
std::string reason;
|
||||
if (m_wallet->lns_make_update_mapping_signature(lns::mapping_type::session, name, new_value, signature, &reason))
|
||||
tools::success_msg_writer() << "signature=" << epee::string_tools::pod_to_hex(signature);
|
||||
else
|
||||
fail_msg_writer() << reason;
|
||||
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
static char constexpr NULL_KEY_STR[] = "0000000000000000000000000000000000000000000000000000000000000000";
|
||||
bool simple_wallet::lns_print_name_to_owners(const std::vector<std::string>& args)
|
||||
{
|
||||
|
|
|
@ -176,6 +176,7 @@ namespace cryptonote
|
|||
bool query_locked_stakes(bool print_result);
|
||||
bool lns_buy_mapping(const std::vector<std::string> &args);
|
||||
bool lns_update_mapping(const std::vector<std::string> &args);
|
||||
bool lns_make_updating_mapping_signature(const std::vector<std::string> &args);
|
||||
bool lns_print_owners_to_names(const std::vector<std::string> &args);
|
||||
bool lns_print_name_to_owners(const std::vector<std::string> &args);
|
||||
|
||||
|
|
|
@ -8692,6 +8692,45 @@ bool wallet2::unlock_keys_file()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool wallet2::lns_make_update_mapping_signature(lns::mapping_type type, std::string const &name, std::string const &value, crypto::generic_signature &signature, std::string *reason)
|
||||
{
|
||||
cryptonote::COMMAND_RPC_LNS_NAMES_TO_OWNERS::request request = {};
|
||||
request.entries.push_back({name, {static_cast<uint16_t>(type)}});
|
||||
|
||||
if (!lns::validate_lns_name(type, name, reason))
|
||||
return false;
|
||||
|
||||
lns::lns_value value_blob;
|
||||
if (!lns::validate_lns_value(nettype(), type, value, &value_blob, reason))
|
||||
return false;
|
||||
|
||||
boost::optional<std::string> failed;
|
||||
std::vector<cryptonote::COMMAND_RPC_LNS_NAMES_TO_OWNERS::response_entry> response = lns_names_to_owners(request, failed);
|
||||
if (failed)
|
||||
{
|
||||
if (reason) *reason = *failed;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.empty())
|
||||
{
|
||||
if (reason) *reason = "name=\"" + name + std::string("\" does not have a corresponding LNS record, the mapping is available for purchase, update signature is not required.");
|
||||
return false;
|
||||
}
|
||||
|
||||
cryptonote::COMMAND_RPC_LNS_NAMES_TO_OWNERS::response_entry const &record = response[0];
|
||||
crypto::hash prev_txid;
|
||||
if (epee::string_tools::hex_to_pod(response[0].prev_txid, prev_txid))
|
||||
{
|
||||
if (reason) *reason = "Failed to convert=" + response[0].prev_txid + std::string(" to a transaction ID.");
|
||||
return false;
|
||||
}
|
||||
|
||||
crypto::hash hash = lns::tx_extra_signature_hash(epee::span<const uint8_t>(value_blob.buffer.data(), value_blob.len), prev_txid);
|
||||
crypto::generate_signature(hash, get_account().get_keys().m_account_address.m_spend_public_key, get_account().get_keys().m_spend_secret_key, signature.monero);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wallet2::is_keys_file_locked() const
|
||||
{
|
||||
return m_keys_file_locker->locked();
|
||||
|
@ -8763,7 +8802,7 @@ void wallet2::light_wallet_get_outs(std::vector<std::vector<tools::wallet2::get_
|
|||
amount_ss << ask_amount;
|
||||
oreq.amounts.push_back(amount_ss.str());
|
||||
}
|
||||
|
||||
|
||||
oreq.count = light_wallet_requested_outputs_count;
|
||||
m_daemon_rpc_mutex.lock();
|
||||
bool r = invoke_http_json("/get_random_outs", oreq, ores, rpc_timeout, "POST");
|
||||
|
|
|
@ -1546,6 +1546,9 @@ private:
|
|||
std::vector<wallet2::pending_tx> lns_create_update_mapping_tx(lns::mapping_type type, std::string const &name, std::string const &value, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
|
||||
std::vector<wallet2::pending_tx> lns_create_update_mapping_tx(std::string const &type, std::string const &name, std::string const &value, std::string const *signature, std::string *reason, uint32_t priority = 0, uint32_t account_index = 0, std::set<uint32_t> subaddr_indices = {});
|
||||
|
||||
// Generate just the signature required for putting into lns_update_mapping command in the wallet
|
||||
bool lns_make_update_mapping_signature(lns::mapping_type type, std::string const &name, std::string const &value, crypto::generic_signature &signature, std::string *reason = nullptr);
|
||||
|
||||
void freeze(size_t idx);
|
||||
void thaw(size_t idx);
|
||||
bool frozen(size_t idx) const;
|
||||
|
|
|
@ -55,6 +55,7 @@ using namespace epee;
|
|||
#include "rpc/core_rpc_server_commands_defs.h"
|
||||
#include "rpc/core_rpc_server.h"
|
||||
#include "daemonizer/daemonizer.h"
|
||||
#include "cryptonote_core/loki_name_system.h"
|
||||
|
||||
#undef LOKI_DEFAULT_LOG_CATEGORY
|
||||
#define LOKI_DEFAULT_LOG_CATEGORY "wallet.rpc"
|
||||
|
@ -4367,6 +4368,37 @@ namespace tools
|
|||
res.tx_metadata,
|
||||
er);
|
||||
}
|
||||
|
||||
bool wallet_rpc_server::on_lns_make_update_mapping_signature(const wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::request& req, wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
if (m_restricted)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_DENIED;
|
||||
er.message = "Generating the lns update signature is unavailable in restricted mode.";
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string reason;
|
||||
lns::mapping_type type;
|
||||
if (!lns::validate_mapping_type(req.type, &type, &reason))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_LNS_TYPE;
|
||||
er.message = "Wrong lns type given=" + reason;
|
||||
return false;
|
||||
}
|
||||
|
||||
crypto::generic_signature signature;
|
||||
if (!m_wallet->lns_make_update_mapping_signature(type, req.name, req.value, signature, &reason))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_TX_NOT_POSSIBLE;
|
||||
er.message = "Failed to create signature for LNS update transaction: " + reason;
|
||||
return false;
|
||||
}
|
||||
|
||||
res.signature = epee::string_tools::pod_to_hex(signature);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class t_daemon
|
||||
|
|
|
@ -166,6 +166,7 @@ namespace tools
|
|||
MAP_JON_RPC_WE("request_stake_unlock", on_request_stake_unlock, wallet_rpc::COMMAND_RPC_REQUEST_STAKE_UNLOCK)
|
||||
MAP_JON_RPC_WE("lns_buy_mapping", on_lns_buy_mapping, wallet_rpc::COMMAND_RPC_LNS_BUY_MAPPING)
|
||||
MAP_JON_RPC_WE("lns_update_mapping", on_lns_update_mapping, wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING)
|
||||
MAP_JON_RPC_WE("lns_make_update_mapping_signature", on_lns_make_update_mapping_signature, wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE)
|
||||
END_JSON_RPC_MAP()
|
||||
END_URI_MAP2()
|
||||
|
||||
|
@ -258,6 +259,7 @@ namespace tools
|
|||
bool on_request_stake_unlock(const wallet_rpc::COMMAND_RPC_REQUEST_STAKE_UNLOCK::request& req, wallet_rpc::COMMAND_RPC_REQUEST_STAKE_UNLOCK::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_lns_buy_mapping(const wallet_rpc::COMMAND_RPC_LNS_BUY_MAPPING::request& req, wallet_rpc::COMMAND_RPC_LNS_BUY_MAPPING::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_lns_update_mapping(const wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING::request& req, wallet_rpc::COMMAND_RPC_LNS_UPDATE_MAPPING::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_lns_make_update_mapping_signature(const wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::request& req, wallet_rpc::COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
|
||||
//json rpc v2
|
||||
bool on_query_key(const wallet_rpc::COMMAND_RPC_QUERY_KEY::request& req, wallet_rpc::COMMAND_RPC_QUERY_KEY::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
|
|
|
@ -3038,5 +3038,38 @@ transaction, the open wallet is assumed the owner and it's spend key will automa
|
|||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
LOKI_RPC_DOC_INTROSPECT
|
||||
// Generate the signature necessary for updating the requested record using the wallet's spend key. The signature is
|
||||
// only valid if the queried wallet is one of the owners of the LNS record.
|
||||
|
||||
// This command is only required if the open wallet is one of the owners of a LNS record but want the update
|
||||
// transaction to occur via another non-owning wallet. By default, if no signature is specified to the update
|
||||
// transaction, the open wallet is assumed the owner and it's spend key will automatically be used.
|
||||
struct COMMAND_RPC_LNS_MAKE_UPDATE_SIGNATURE
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
std::string type; // The mapping type, currently we only support "session". In future "lokinet" and "blockchain" mappings will be available.
|
||||
std::string name; // The desired name to update via Loki Name Service
|
||||
std::string value; // The new value that the name will be updated to via Loki Name Service.
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(type);
|
||||
KV_SERIALIZE(name);
|
||||
KV_SERIALIZE(value);
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
{
|
||||
std::string signature; // A signature valid for using in LNS to update an underlying mapping.
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(signature)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,3 +79,4 @@
|
|||
// Loki:
|
||||
#define WALLET_RPC_ERROR_CODE_BLINK_FAILED -1000
|
||||
#define WALLET_RPC_ERROR_CODE_HF_QUERY_FAILED -1001
|
||||
#define WALLET_RPC_ERROR_CODE_WRONG_LNS_TYPE -1002
|
||||
|
|
Loading…
Reference in New Issue