PSBT functionlalies equals raw transactions functionalities
This commit is contained in:
parent
f5442a50d1
commit
fd3ac1766c
2 changed files with 182 additions and 83 deletions
|
|
@ -100,8 +100,18 @@ private:
|
||||||
std::unique_ptr<bitcoin_rpc_client> bitcoin_client;
|
std::unique_ptr<bitcoin_rpc_client> bitcoin_client;
|
||||||
std::unique_ptr<zmq_listener> listener;
|
std::unique_ptr<zmq_listener> listener;
|
||||||
|
|
||||||
std::string sign_and_send_transaction_with_wallet(const std::string &tx_json);
|
std::string create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs);
|
||||||
std::string processpsbt(const std::string &tx_psbt);
|
std::string sign_transaction(const std::string &tx);
|
||||||
|
void send_transaction(const std::string &tx);
|
||||||
|
|
||||||
|
std::string create_transaction_raw(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs);
|
||||||
|
std::string create_transaction_psbt(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs);
|
||||||
|
std::string create_transaction_standalone(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs);
|
||||||
|
|
||||||
|
std::string sign_transaction_raw(const std::string &tx);
|
||||||
|
std::string sign_transaction_psbt(const std::string &tx);
|
||||||
|
std::string sign_transaction_standalone(const std::string &tx);
|
||||||
|
|
||||||
std::string transfer_all_btc(const std::string &from_address, const std::string &to_address);
|
std::string transfer_all_btc(const std::string &from_address, const std::string &to_address);
|
||||||
std::string transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo);
|
std::string transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo);
|
||||||
std::string transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo);
|
std::string transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo);
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,9 @@ std::string bitcoin_rpc_client::createpsbt(const std::vector<btc_txout> &ins, co
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
if (reply.status == 200) {
|
if (reply.status == 200) {
|
||||||
return json.get<std::string>("result");
|
if (json.find("result") != json.not_found()) {
|
||||||
|
return json.get<std::string>("result");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (json.count("error") && !json.get_child("error").empty()) {
|
if (json.count("error") && !json.get_child("error").empty()) {
|
||||||
|
|
@ -142,9 +144,12 @@ std::string bitcoin_rpc_client::createrawtransaction(const std::vector<btc_txout
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
if (reply.status == 200) {
|
if (reply.status == 200) {
|
||||||
if (json.count("result"))
|
if (json.find("result") != json.not_found()) {
|
||||||
return ss.str();
|
return json.get<std::string>("result");
|
||||||
} else if (json.count("error") && !json.get_child("error").empty()) {
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (json.count("error") && !json.get_child("error").empty()) {
|
||||||
wlog("Bitcoin RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body)("msg", ss.str()));
|
wlog("Bitcoin RPC call ${function} with body ${body} failed with reply '${msg}'", ("function", __FUNCTION__)("body", body)("msg", ss.str()));
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
|
|
@ -281,19 +286,15 @@ uint64_t bitcoin_rpc_client::estimatesmartfee() {
|
||||||
boost::property_tree::read_json(ss, json);
|
boost::property_tree::read_json(ss, json);
|
||||||
|
|
||||||
if (reply.status == 200) {
|
if (reply.status == 200) {
|
||||||
auto json_result_itr = json.find("result");
|
if (json.find("result") != json.not_found()) {
|
||||||
if (json_result_itr != json.not_found()) {
|
|
||||||
auto json_result = json.get_child("result");
|
auto json_result = json.get_child("result");
|
||||||
|
if (json_result.find("feerate") != json_result.not_found()) {
|
||||||
auto json_feerate_itr = json_result.find("feerate");
|
|
||||||
if (json_feerate_itr != json_result.not_found()) {
|
|
||||||
auto feerate_str = json_result.get<std::string>("feerate");
|
auto feerate_str = json_result.get<std::string>("feerate");
|
||||||
feerate_str.erase(std::remove(feerate_str.begin(), feerate_str.end(), '.'), feerate_str.end());
|
feerate_str.erase(std::remove(feerate_str.begin(), feerate_str.end(), '.'), feerate_str.end());
|
||||||
return std::stoll(feerate_str);
|
return std::stoll(feerate_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto json_errors_itr = json_result.find("errors");
|
if (json_result.find("errors") != json_result.not_found()) {
|
||||||
if (json_errors_itr != json_result.not_found()) {
|
|
||||||
wlog("Bitcoin RPC call ${function} with body ${body} executed with reply '${msg}'", ("function", __FUNCTION__)("body", body)("msg", ss.str()));
|
wlog("Bitcoin RPC call ${function} with body ${body} executed with reply '${msg}'", ("function", __FUNCTION__)("body", body)("msg", ss.str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -841,51 +842,143 @@ void sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw
|
||||||
transfer_withdrawal_from_primary_wallet(swwo);
|
transfer_withdrawal_from_primary_wallet(swwo);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::sign_and_send_transaction_with_wallet(const std::string &tx_json) {
|
// Creates transaction in any format
|
||||||
std::string reply_str = tx_json;
|
// Function to actually create transaction should return transaction string, or empty string in case of failure
|
||||||
|
std::string sidechain_net_handler_bitcoin::create_transaction(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs) {
|
||||||
std::stringstream ss_utx(reply_str);
|
std::string new_tx = "";
|
||||||
boost::property_tree::ptree pt;
|
//new_tx = create_transaction_raw(inputs, outputs);
|
||||||
boost::property_tree::read_json(ss_utx, pt);
|
new_tx = create_transaction_psbt(inputs, outputs);
|
||||||
|
//new_tx = create_transaction_standalone(inputs, outputs);
|
||||||
if (!(pt.count("error") && pt.get_child("error").empty()) || !pt.count("result")) {
|
return new_tx;
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wallet_password.empty()) {
|
|
||||||
bitcoin_client->walletpassphrase(wallet_password, 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string unsigned_tx_hex = pt.get<std::string>("result");
|
|
||||||
|
|
||||||
reply_str = bitcoin_client->signrawtransactionwithwallet(unsigned_tx_hex);
|
|
||||||
std::stringstream ss_stx(reply_str);
|
|
||||||
boost::property_tree::ptree stx_json;
|
|
||||||
boost::property_tree::read_json(ss_stx, stx_json);
|
|
||||||
|
|
||||||
//if (!wallet_password.empty()) {
|
|
||||||
// bitcoin_client->walletlock();
|
|
||||||
//}
|
|
||||||
|
|
||||||
if (!(stx_json.count("error") && stx_json.get_child("error").empty()) || !stx_json.count("result") || !stx_json.get_child("result").count("hex")) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string signed_tx_hex = stx_json.get<std::string>("result.hex");
|
|
||||||
|
|
||||||
bitcoin_client->sendrawtransaction(signed_tx_hex);
|
|
||||||
|
|
||||||
return reply_str;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::processpsbt(const std::string &tx_psbt) {
|
// Adds signature to transaction
|
||||||
ilog(tx_psbt);
|
// Function to actually add signature should return transaction with added signature string, or empty string in case of failure
|
||||||
|
std::string sidechain_net_handler_bitcoin::sign_transaction(const std::string &tx) {
|
||||||
|
std::string new_tx = "";
|
||||||
|
//new_tx = sign_transaction_raw(tx);
|
||||||
|
new_tx = sign_transaction_psbt(tx);
|
||||||
|
//new_tx = sign_transaction_standalone(tx);
|
||||||
|
return new_tx;
|
||||||
|
}
|
||||||
|
|
||||||
if (!wallet_password.empty()) {
|
void sidechain_net_handler_bitcoin::send_transaction(const std::string &tx) {
|
||||||
bitcoin_client->walletpassphrase(wallet_password, 60);
|
bitcoin_client->sendrawtransaction(tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sidechain_net_handler_bitcoin::create_transaction_raw(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs) {
|
||||||
|
return bitcoin_client->createrawtransaction(inputs, outputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sidechain_net_handler_bitcoin::create_transaction_psbt(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs) {
|
||||||
|
return bitcoin_client->createpsbt(inputs, outputs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sidechain_net_handler_bitcoin::create_transaction_standalone(const std::vector<btc_txout> &inputs, const fc::flat_map<std::string, double> outputs) {
|
||||||
|
// Examples
|
||||||
|
|
||||||
|
// Transaction with no inputs and outputs
|
||||||
|
//bitcoin-core.cli -rpcuser=1 -rpcpassword=1 -rpcwallet="" createrawtransaction '[]' '[]'
|
||||||
|
//02000000000000000000
|
||||||
|
//bitcoin-core.cli -rpcuser=1 -rpcpassword=1 -rpcwallet="" decoderawtransaction 02000000000000000000
|
||||||
|
//{
|
||||||
|
// "txid": "4ebd325a4b394cff8c57e8317ccf5a8d0e2bdf1b8526f8aad6c8e43d8240621a",
|
||||||
|
// "hash": "4ebd325a4b394cff8c57e8317ccf5a8d0e2bdf1b8526f8aad6c8e43d8240621a",
|
||||||
|
// "version": 2,
|
||||||
|
// "size": 10,
|
||||||
|
// "vsize": 10,
|
||||||
|
// "weight": 40,
|
||||||
|
// "locktime": 0,
|
||||||
|
// "vin": [
|
||||||
|
// ],
|
||||||
|
// "vout": [
|
||||||
|
// ]
|
||||||
|
//}
|
||||||
|
|
||||||
|
// Transaction with input and output
|
||||||
|
//{
|
||||||
|
// "txid": "ff60f48f767bbf70d79efc1347b5554b481f14fda68709839091286e035e669b",
|
||||||
|
// "hash": "ff60f48f767bbf70d79efc1347b5554b481f14fda68709839091286e035e669b",
|
||||||
|
// "version": 2,
|
||||||
|
// "size": 83,
|
||||||
|
// "vsize": 83,
|
||||||
|
// "weight": 332,
|
||||||
|
// "locktime": 0,
|
||||||
|
// "vin": [
|
||||||
|
// {
|
||||||
|
// "txid": "3d322dc2640239a2e68e182b254d19c88e5172a61947f94a105c3f57618092ff",
|
||||||
|
// "vout": 0,
|
||||||
|
// "scriptSig": {
|
||||||
|
// "asm": "",
|
||||||
|
// "hex": ""
|
||||||
|
// },
|
||||||
|
// "sequence": 4294967295
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// "vout": [
|
||||||
|
// {
|
||||||
|
// "value": 1.00000000,
|
||||||
|
// "n": 0,
|
||||||
|
// "scriptPubKey": {
|
||||||
|
// "asm": "OP_HASH160 b87c323018cae236eb03a1f63000c85b672270f6 OP_EQUAL",
|
||||||
|
// "hex": "a914b87c323018cae236eb03a1f63000c85b672270f687",
|
||||||
|
// "reqSigs": 1,
|
||||||
|
// "type": "scripthash",
|
||||||
|
// "addresses": [
|
||||||
|
// "2NA4h6sc9oZ4ogfNKU9Wp6fkqPZLZPqqpgf"
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
//}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sidechain_net_handler_bitcoin::sign_transaction_raw(const std::string &tx) {
|
||||||
|
if (tx.empty()) {
|
||||||
|
wlog("Signing failed, tx string is empty");
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string reply_str = bitcoin_client->walletprocesspsbt(tx_psbt);
|
if (!wallet_password.empty()) {
|
||||||
|
bitcoin_client->walletpassphrase(wallet_password, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string reply_str = bitcoin_client->signrawtransactionwithwallet(tx);
|
||||||
|
|
||||||
|
std::stringstream ss(reply_str);
|
||||||
|
boost::property_tree::ptree json;
|
||||||
|
boost::property_tree::read_json(ss, json);
|
||||||
|
boost::property_tree::ptree json_res = json.get_child("result");
|
||||||
|
|
||||||
|
if ((json_res.count("hex") == 0) || (json_res.count("complete") == 0)) {
|
||||||
|
wlog("Failed to process raw transaction ${tx}", ("tx", tx));
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string new_tx_raw = json_res.get<std::string>("hex");
|
||||||
|
bool complete_raw = json_res.get<bool>("complete");
|
||||||
|
|
||||||
|
if (complete_raw) {
|
||||||
|
std::string decoded_raw = bitcoin_client->decoderawtransaction(new_tx_raw);
|
||||||
|
send_transaction(new_tx_raw);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return new_tx_raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string sidechain_net_handler_bitcoin::sign_transaction_psbt(const std::string &tx) {
|
||||||
|
if (tx.empty()) {
|
||||||
|
wlog("Signing failed, tx string is empty");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wallet_password.empty()) {
|
||||||
|
bitcoin_client->walletpassphrase(wallet_password, 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string reply_str = bitcoin_client->walletprocesspsbt(tx);
|
||||||
|
|
||||||
std::stringstream ss(reply_str);
|
std::stringstream ss(reply_str);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
|
|
@ -893,12 +986,12 @@ std::string sidechain_net_handler_bitcoin::processpsbt(const std::string &tx_psb
|
||||||
boost::property_tree::ptree json_res = json.get_child("result");
|
boost::property_tree::ptree json_res = json.get_child("result");
|
||||||
|
|
||||||
if ((json_res.count("psbt") == 0) || (json_res.count("complete") == 0)) {
|
if ((json_res.count("psbt") == 0) || (json_res.count("complete") == 0)) {
|
||||||
wlog("Failed to process PSBT ${psbt}", ("psbt", tx_psbt));
|
wlog("Failed to process psbt transaction ${tx}", ("tx", tx));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string new_tx_psbt = json.get<std::string>("result.psbt");
|
std::string new_tx_psbt = json_res.get<std::string>("psbt");
|
||||||
bool complete_psbt = json.get<bool>("result.complete");
|
bool complete_psbt = json_res.get<bool>("complete");
|
||||||
|
|
||||||
if (complete_psbt) {
|
if (complete_psbt) {
|
||||||
std::string reply_str = bitcoin_client->finalizepsbt(new_tx_psbt);
|
std::string reply_str = bitcoin_client->finalizepsbt(new_tx_psbt);
|
||||||
|
|
@ -909,24 +1002,26 @@ std::string sidechain_net_handler_bitcoin::processpsbt(const std::string &tx_psb
|
||||||
boost::property_tree::ptree json_res = json.get_child("result");
|
boost::property_tree::ptree json_res = json.get_child("result");
|
||||||
|
|
||||||
if ((json_res.count("hex") == 0) || (json_res.count("complete") == 0)) {
|
if ((json_res.count("hex") == 0) || (json_res.count("complete") == 0)) {
|
||||||
wlog("Failed to finalize PSBT ${psbt}", ("psbt", tx_psbt));
|
wlog("Failed to finalize psbt transaction ${tx}", ("tx", tx));
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string new_tx_raw = json.get<std::string>("result.hex");
|
std::string new_tx_raw = json_res.get<std::string>("hex");
|
||||||
bool complete_raw = json.get<bool>("result.complete");
|
bool complete_raw = json_res.get<bool>("complete");
|
||||||
|
|
||||||
if (complete_raw) {
|
if (complete_raw) {
|
||||||
|
|
||||||
std::string decoded_raw = bitcoin_client->decoderawtransaction(new_tx_raw);
|
std::string decoded_raw = bitcoin_client->decoderawtransaction(new_tx_raw);
|
||||||
|
send_transaction(new_tx_raw);
|
||||||
bitcoin_client->sendrawtransaction(new_tx_raw);
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new_tx_psbt;
|
return new_tx_psbt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string sidechain_net_handler_bitcoin::sign_transaction_standalone(const std::string &tx) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::transfer_all_btc(const std::string &from_address, const std::string &to_address) {
|
std::string sidechain_net_handler_bitcoin::transfer_all_btc(const std::string &from_address, const std::string &to_address) {
|
||||||
uint64_t fee_rate = bitcoin_client->estimatesmartfee();
|
uint64_t fee_rate = bitcoin_client->estimatesmartfee();
|
||||||
uint64_t min_fee_rate = 1000;
|
uint64_t min_fee_rate = 1000;
|
||||||
|
|
@ -934,13 +1029,13 @@ std::string sidechain_net_handler_bitcoin::transfer_all_btc(const std::string &f
|
||||||
|
|
||||||
double min_amount = ((double)fee_rate / 100000000.0); // Account only for relay fee for now
|
double min_amount = ((double)fee_rate / 100000000.0); // Account only for relay fee for now
|
||||||
double total_amount = 0.0;
|
double total_amount = 0.0;
|
||||||
std::vector<btc_txout> unspent_utxo = bitcoin_client->listunspent_by_address_and_amount(from_address, 0);
|
std::vector<btc_txout> inputs = bitcoin_client->listunspent_by_address_and_amount(from_address, 0);
|
||||||
|
|
||||||
if (unspent_utxo.size() == 0) {
|
if (inputs.size() == 0) {
|
||||||
wlog("Failed to find UTXOs to spend for ${pw}", ("pw", from_address));
|
wlog("Failed to find UTXOs to spend for ${pw}", ("pw", from_address));
|
||||||
return "";
|
return "";
|
||||||
} else {
|
} else {
|
||||||
for (const auto &utx : unspent_utxo) {
|
for (const auto &utx : inputs) {
|
||||||
total_amount += utx.amount_;
|
total_amount += utx.amount_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -950,13 +1045,11 @@ std::string sidechain_net_handler_bitcoin::transfer_all_btc(const std::string &f
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fc::flat_map<std::string, double> outs;
|
fc::flat_map<std::string, double> outputs;
|
||||||
outs[to_address] = total_amount - min_amount;
|
outputs[to_address] = total_amount - min_amount;
|
||||||
|
|
||||||
//std::string reply_str = bitcoin_client->createrawtransaction(unspent_utxo, outs);
|
std::string tx = create_transaction(inputs, outputs);
|
||||||
//return sign_and_send_transaction_with_wallet(reply_str);
|
return sign_transaction(tx);
|
||||||
std::string reply_str = bitcoin_client->createpsbt(unspent_utxo, outs);
|
|
||||||
return processpsbt(reply_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo) {
|
std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(const son_wallet_deposit_object &swdo) {
|
||||||
|
|
@ -984,21 +1077,19 @@ std::string sidechain_net_handler_bitcoin::transfer_deposit_to_primary_wallet(co
|
||||||
deposit_amount -= fee_rate; // Deduct minimum relay fee
|
deposit_amount -= fee_rate; // Deduct minimum relay fee
|
||||||
double transfer_amount = (double)deposit_amount / 100000000.0;
|
double transfer_amount = (double)deposit_amount / 100000000.0;
|
||||||
|
|
||||||
std::vector<btc_txout> ins;
|
std::vector<btc_txout> inputs;
|
||||||
fc::flat_map<std::string, double> outs;
|
fc::flat_map<std::string, double> outputs;
|
||||||
|
|
||||||
btc_txout utxo;
|
btc_txout utxo;
|
||||||
utxo.txid_ = txid;
|
utxo.txid_ = txid;
|
||||||
utxo.out_num_ = std::stoul(nvout);
|
utxo.out_num_ = std::stoul(nvout);
|
||||||
|
|
||||||
ins.push_back(utxo);
|
inputs.push_back(utxo);
|
||||||
|
|
||||||
outs[pw_address] = transfer_amount;
|
outputs[pw_address] = transfer_amount;
|
||||||
|
|
||||||
//std::string reply_str = bitcoin_client->createrawtransaction(ins, outs);
|
std::string tx = create_transaction(inputs, outputs);
|
||||||
//return sign_and_send_transaction_with_wallet(reply_str);
|
return sign_transaction(tx);
|
||||||
std::string reply_str = bitcoin_client->createpsbt(ins, outs);
|
|
||||||
return processpsbt(reply_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo) {
|
std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wallet(const son_wallet_withdraw_object &swwo) {
|
||||||
|
|
@ -1044,10 +1135,8 @@ std::string sidechain_net_handler_bitcoin::transfer_withdrawal_from_primary_wall
|
||||||
outs[pw_address] = total_amount - min_amount;
|
outs[pw_address] = total_amount - min_amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
//std::string reply_str = bitcoin_client->createrawtransaction(unspent_utxo, outs);
|
std::string tx = create_transaction(unspent_utxo, outs);
|
||||||
//return sign_and_send_transaction_with_wallet(reply_str);
|
return sign_transaction(tx);
|
||||||
std::string reply_str = bitcoin_client->createpsbt(unspent_utxo, outs);
|
|
||||||
return processpsbt(reply_str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {
|
void sidechain_net_handler_bitcoin::handle_event(const std::string &event_data) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue