From e3d1956ba39fb9db4b24550a3ba7ba42dbdd4f38 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Thu, 11 Apr 2024 14:29:03 +0200 Subject: [PATCH] implemented RPC API for assets deployment --- src/wallet/wallet_public_structs_defs.h | 68 +++++++++++++++++++++++++ src/wallet/wallet_rpc_server.cpp | 65 ++++++++++++++++++++++- src/wallet/wallet_rpc_server.h | 9 ++++ 3 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/wallet/wallet_public_structs_defs.h b/src/wallet/wallet_public_structs_defs.h index 00cbc3de..2d8a3685 100644 --- a/src/wallet/wallet_public_structs_defs.h +++ b/src/wallet/wallet_public_structs_defs.h @@ -1954,16 +1954,84 @@ namespace wallet_public + struct COMMAND_ASSETS_DEPLOY + { + DOC_COMMAND("Deploy new asset in the system."); + + struct request + { + std::list destinations; + currency::asset_descriptor_base asset_descriptor; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in destinations should be set to 0000000000000000000000000000000000000000000000000000000000000000") DOC_EXMP_AUTO(1) DOC_END + KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor that holds all information about asset - ticker, emission, description etc") DOC_END + END_KV_SERIALIZE_MAP() + }; + struct response + { + crypto::hash result_tx; + crypto::public_key new_asset_id; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx) DOC_DSCR("Id of transaction that carries asset registration command, asset would be registered as soon as transaction got confirmed") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + KV_SERIALIZE_POD_AS_HEX_STRING(new_asset_id) DOC_DSCR("Issued asset id") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + END_KV_SERIALIZE_MAP() + }; + }; + + struct COMMAND_ASSETS_EMIT + { + DOC_COMMAND("Emmit new coins of the the asset, that is controlled by this wallet."); + + struct request + { + crypto::public_key asset_id; + std::list destinations; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Id of the asset to emit more coins") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(destinations) DOC_DSCR("Addresses where to receive emitted coins. Asset id in destinations should be set to 0000000000000000000000000000000000000000000000000000000000000000") DOC_EXMP_AUTO(1) DOC_END + END_KV_SERIALIZE_MAP() + }; + struct response + { + crypto::hash result_tx; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx) DOC_DSCR("Id of transaction that carries asset registration command, asset would be registered as soon as transaction got confirmed") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_ASSETS_UPDATE + { + DOC_COMMAND("Update asset descriptor(you can change only owner so far)"); + struct request + { + crypto::public_key asset_id; + currency::asset_descriptor_base asset_descriptor; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(asset_id) DOC_DSCR("Id of the asset to update") DOC_EXMP("40fa6db923728b38962718c61b4dc3af1acaa1967479c73703e260dc3609c58d") DOC_END + KV_SERIALIZE(asset_descriptor) DOC_DSCR("Descriptor that holds all information about asset that need to be updated (only owner could be updated)") DOC_END + END_KV_SERIALIZE_MAP() + }; + struct response + { + crypto::hash result_tx; + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE_POD_AS_HEX_STRING(result_tx) DOC_DSCR("Id of transaction that carries asset registration command, asset would be registered as soon as transaction got confirmed") DOC_EXMP("f74bb56a5b4fa562e679ccaadd697463498a66de4f1760b2cd40f11c3a00a7a8") DOC_END + END_KV_SERIALIZE_MAP() + }; + }; } // namespace wallet_rpc diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 4428ee3a..10d2a399 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -50,7 +50,7 @@ POP_VS_WARNINGS catch (const tools::error::wallet_error& e) \ { \ er.code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR; \ - er.message = std::string("WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR") + e.error_code(); \ + er.message = e.error_code(); \ return false; \ } \ catch (const std::exception& e) \ @@ -66,6 +66,10 @@ POP_VS_WARNINGS return false; \ } + +void exception_handler() +{} + namespace tools { //----------------------------------------------------------------------------------- @@ -421,7 +425,7 @@ namespace tools return true; WALLET_RPC_CATCH_TRY_ENTRY(); } - //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_transfer(const wallet_public::COMMAND_RPC_TRANSFER::request& req, wallet_public::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); @@ -453,6 +457,7 @@ namespace tools } bool wrap = false; std::vector& dsts = ctp.dsts; + for (auto it = req.destinations.begin(); it != req.destinations.end(); it++) { currency::tx_destination_entry de; @@ -1230,6 +1235,62 @@ namespace tools WALLET_RPC_CATCH_TRY_ENTRY(); } //------------------------------------------------------------------------------------------------------------------------------ + void wallet_rpc_server::rpc_destinations_to_currency_destination(const std::list& rpc_destinations, std::vector& currency_destinations) + { + GET_WALLET(); + std::vector& dsts = currency_destinations; + for (auto it = rpc_destinations.begin(); it != rpc_destinations.end(); it++) + { + currency::tx_destination_entry de; + de.addr.resize(1); + std::string embedded_payment_id; + //check if address looks like wrapped address + WLT_THROW_IF_FALSE_WITH_CODE(!currency::is_address_like_wrapped(it->address), "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"); + WLT_THROW_IF_FALSE_WITH_CODE(!w.get_wallet()->get_transfer_address(it->address, de.addr.back(), embedded_payment_id), "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"); + WLT_THROW_IF_FALSE_WITH_CODE(embedded_payment_id.size() == 0, "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS", "WALLET_RPC_ERROR_CODE_WRONG_ADDRESS"); + de.amount = it->amount; + de.asset_id = it->asset_id; + dsts.push_back(de); + } + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_deploy(const wallet_public::COMMAND_ASSETS_DEPLOY::request& req, wallet_public::COMMAND_ASSETS_DEPLOY::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + currency::transaction result_tx; + std::vector currency_destinations; + rpc_destinations_to_currency_destination(req.destinations, currency_destinations); + w.get_wallet()->deploy_new_asset(req.asset_descriptor, currency_destinations, result_tx, res.new_asset_id); + res.result_tx = currency::get_transaction_hash(result_tx); + return true; + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_emit(const wallet_public::COMMAND_ASSETS_EMIT::request& req, wallet_public::COMMAND_ASSETS_EMIT::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + currency::transaction result_tx; + std::vector currency_destinations; + rpc_destinations_to_currency_destination(req.destinations, currency_destinations); + + w.get_wallet()->emit_asset(req.asset_id, currency_destinations, result_tx); + res.result_tx = currency::get_transaction_hash(result_tx); + return true; + + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ + bool wallet_rpc_server::on_assets_update(const wallet_public::COMMAND_ASSETS_UPDATE::request& req, wallet_public::COMMAND_ASSETS_UPDATE::response& res, epee::json_rpc::error& er, connection_context& cntx) + { + WALLET_RPC_BEGIN_TRY_ENTRY(); + currency::transaction result_tx; + w.get_wallet()->update_asset(req.asset_id, req.asset_descriptor, result_tx); + res.result_tx = currency::get_transaction_hash(result_tx); + return true; + + WALLET_RPC_CATCH_TRY_ENTRY(); + } + //------------------------------------------------------------------------------------------------------------------------------ bool wallet_rpc_server::on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx) { WALLET_RPC_BEGIN_TRY_ENTRY(); diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index e5451a37..86a0039a 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -143,6 +143,10 @@ namespace tools MAP_JON_RPC_WE("assets_whitelist_get", on_assets_whitelist_get, wallet_public::COMMAND_ASSETS_WHITELIST_GET) MAP_JON_RPC_WE("assets_whitelist_add", on_assets_whitelist_add, wallet_public::COMMAND_ASSETS_WHITELIST_ADD) MAP_JON_RPC_WE("assets_whitelist_remove", on_assets_whitelist_remove, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE) + + MAP_JON_RPC_WE("deploy_asset", on_assets_deploy, wallet_public::COMMAND_ASSETS_DEPLOY) + MAP_JON_RPC_WE("emit_asset", on_assets_emit, wallet_public::COMMAND_ASSETS_EMIT) + MAP_JON_RPC_WE("update_asset", on_assets_update, wallet_public::COMMAND_ASSETS_UPDATE) //MULTIWALLET APIs MAP_JON_RPC_WE("mw_get_wallets", on_mw_get_wallets, wallet_public::COMMAND_MW_GET_WALLETS) @@ -208,6 +212,10 @@ namespace tools bool on_assets_whitelist_get(const wallet_public::COMMAND_ASSETS_WHITELIST_GET::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_GET::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_assets_whitelist_add(const wallet_public::COMMAND_ASSETS_WHITELIST_ADD::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_ADD::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_assets_whitelist_remove(const wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::request& req, wallet_public::COMMAND_ASSETS_WHITELIST_REMOVE::response& res, epee::json_rpc::error& er, connection_context& cntx); + + bool on_assets_deploy(const wallet_public::COMMAND_ASSETS_DEPLOY::request& req, wallet_public::COMMAND_ASSETS_DEPLOY::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_emit(const wallet_public::COMMAND_ASSETS_EMIT::request& req, wallet_public::COMMAND_ASSETS_EMIT::response& res, epee::json_rpc::error& er, connection_context& cntx); + bool on_assets_update(const wallet_public::COMMAND_ASSETS_UPDATE::request& req, wallet_public::COMMAND_ASSETS_UPDATE::response& res, epee::json_rpc::error& er, connection_context& cntx); bool on_mw_get_wallets(const wallet_public::COMMAND_MW_GET_WALLETS::request& req, wallet_public::COMMAND_MW_GET_WALLETS::response& res, epee::json_rpc::error& er, connection_context& cntx); @@ -225,6 +233,7 @@ namespace tools //bool reset_active_wallet(std::shared_ptr w); bool handle_command_line(const boost::program_options::variables_map& vm); + void rpc_destinations_to_currency_destination(const std::list& rpc_destinations, std::vector& currency_destinations); private: std::shared_ptr m_pwallet_provider_sh_ptr;