BitShares-Core  6.0.1
BitShares blockchain implementation and command-line interface software
wallet.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include <algorithm>
25 #include <cctype>
26 #include <iomanip>
27 #include <iostream>
28 #include <iterator>
29 #include <sstream>
30 #include <string>
31 #include <list>
32 
33 #include <boost/version.hpp>
34 #include <boost/lexical_cast.hpp>
35 #include <boost/algorithm/string/replace.hpp>
36 
37 #include <boost/range/adaptor/map.hpp>
38 #include <boost/range/algorithm_ext/erase.hpp>
39 #include <boost/range/algorithm/unique.hpp>
40 #include <boost/range/algorithm/sort.hpp>
41 
42 #include <boost/multi_index_container.hpp>
43 #include <boost/multi_index/ordered_index.hpp>
44 #include <boost/multi_index/mem_fun.hpp>
45 #include <boost/multi_index/member.hpp>
46 #include <boost/multi_index/random_access_index.hpp>
47 #include <boost/multi_index/tag.hpp>
48 #include <boost/multi_index/sequenced_index.hpp>
49 #include <boost/multi_index/hashed_index.hpp>
50 
51 #include <fc/git_revision.hpp>
52 #include <fc/io/fstream.hpp>
53 #include <fc/io/json.hpp>
54 #include <fc/io/stdio.hpp>
56 #include <fc/rpc/cli.hpp>
57 #include <fc/rpc/websocket_api.hpp>
58 #include <fc/crypto/hex.hpp>
59 #include <fc/thread/mutex.hpp>
61 #include <fc/crypto/base58.hpp>
62 #include <fc/crypto/aes.hpp>
63 
64 #include <graphene/app/api.hpp>
65 #include <graphene/app/util.hpp>
69 #include <graphene/chain/hardfork.hpp>
75 #include "wallet_api_impl.hpp"
77 
78 #include "operation_printer.hpp"
80 
81 #define BRAIN_KEY_WORD_COUNT 16
82 #define RANGE_PROOF_MANTISSA 49 // Minimum mantissa bits to "hide" in the range proof.
83  // If this number is set too low, then for large value
84  // commitments the length of the range proof will hint
85  // strongly at the value amount that is being hidden.
86 
87 namespace graphene { namespace wallet {
89  {
90  fc::stringstream to_sign;
91  to_sign << message << '\n';
92  to_sign << "account=" << meta.account << '\n';
93  to_sign << "memokey=" << std::string( meta.memo_key ) << '\n';
94  to_sign << "block=" << meta.block << '\n';
95  to_sign << "timestamp=" << meta.time;
96 
97  return fc::sha256::hash( to_sign.str() );
98  }
99  vector<brain_key_info> utility::derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys)
100  {
101  // Safety-check
102  FC_ASSERT( number_of_desired_keys >= 1 );
103 
104  // Create as many derived owner keys as requested
105  vector<brain_key_info> results;
106  for (int i = 0; i < number_of_desired_keys; ++i) {
108 
109  brain_key_info result;
110  result.brain_priv_key = brain_key;
111  result.wif_priv_key = key_to_wif( priv_key );
112  result.pub_key = priv_key.get_public_key();
113 
114  results.push_back(result);
115  }
116 
117  return results;
118  }
119 
121  {
122  brain_key_info result;
123  // create a private key for secure entropy
126  fc::bigint entropy1(sha_entropy1.data(), sha_entropy1.data_size());
127  fc::bigint entropy2(sha_entropy2.data(), sha_entropy2.data_size());
128  fc::bigint entropy(entropy1);
129  entropy <<= 8 * sha_entropy1.data_size();
130  entropy += entropy2;
131  string brain_key = "";
132 
133  for (int i = 0; i < BRAIN_KEY_WORD_COUNT; i++)
134  {
135  fc::bigint choice = entropy % graphene::words::word_list_size;
137  if (i > 0)
138  brain_key += " ";
139  brain_key += graphene::words::word_list[choice.to_int64()];
140  }
141 
142  brain_key = detail::normalize_brain_key(brain_key);
143  fc::ecc::private_key priv_key = detail::derive_private_key(brain_key, 0);
144  result.brain_priv_key = brain_key;
145  result.wif_priv_key = key_to_wif(priv_key);
146  result.pub_key = priv_key.get_public_key();
147  return result;
148  }
149 }}
150 
151 namespace graphene { namespace wallet {
152 
154  : my( std::make_unique<detail::wallet_api_impl>(*this, initial_data, rapi) )
155 {
156 }
157 
159 {
160 }
161 
162 bool wallet_api::copy_wallet_file(string destination_filename)
163 {
164  return my->copy_wallet_file(destination_filename);
165 }
166 
167 optional<signed_block_with_info> wallet_api::get_block(uint32_t num)
168 {
169  return my->_remote_db->get_block(num);
170 }
171 
173 {
174  return my->_remote_db->get_account_count();
175 }
176 
177 vector<account_object> wallet_api::list_my_accounts()
178 {
179  return vector<account_object>(my->_wallet.my_accounts.begin(), my->_wallet.my_accounts.end());
180 }
181 
182 map<string,account_id_type> wallet_api::list_accounts(const string& lowerbound, uint32_t limit)
183 {
184  return my->_remote_db->lookup_accounts(lowerbound, limit, {});
185 }
186 
187 vector<asset> wallet_api::list_account_balances(const string& id)
188 {
189  return my->_remote_db->get_account_balances(id, flat_set<asset_id_type>());
190 }
191 
192 vector<extended_asset_object> wallet_api::list_assets(const string& lowerbound, uint32_t limit)const
193 {
194  return my->_remote_db->list_assets( lowerbound, limit );
195 }
196 
198 {
199  return my->_remote_db->get_asset_count();
200 }
201 
202 signed_transaction wallet_api::htlc_create( string source, string destination, string amount, string asset_symbol,
203  string hash_algorithm, const std::string& preimage_hash, uint32_t preimage_size,
204  const uint32_t claim_period_seconds, const std::string& memo, bool broadcast)
205 {
206  return my->htlc_create(source, destination, amount, asset_symbol, hash_algorithm, preimage_hash, preimage_size,
207  claim_period_seconds, memo, broadcast);
208 }
209 
211 {
212  fc::optional<htlc_object> optional_obj = my->get_htlc(htlc_id);
213  if ( optional_obj.valid() )
214  {
215  const htlc_object& obj = *optional_obj;
216  // convert to formatted variant
218  const auto& from = my->get_account( obj.transfer.from );
219  transfer["from"] = from.name;
220  const auto& to = my->get_account( obj.transfer.to );
221  transfer["to"] = to.name;
222  const auto& asset = my->get_asset( obj.transfer.asset_id );
223  transfer["asset"] = asset.symbol;
224  transfer["amount"] = graphene::app::uint128_amount_to_string( obj.transfer.amount.value, asset.precision );
225  if (obj.memo.valid())
226  transfer["memo"] = my->read_memo( *obj.memo );
227  class htlc_hash_to_variant_visitor
228  {
229  public:
231 
232  result_type operator()(const fc::ripemd160& obj)const
233  { return convert("RIPEMD160", obj.str()); }
234  result_type operator()(const fc::sha1& obj)const
235  { return convert("SHA1", obj.str()); }
236  result_type operator()(const fc::sha256& obj)const
237  { return convert("SHA256", obj.str()); }
238  result_type operator()(const fc::hash160& obj)const
239  { return convert("HASH160", obj.str()); }
240  private:
241  result_type convert(const std::string& type, const std::string& hash)const
242  {
244  ret_val["hash_algo"] = type;
245  ret_val["preimage_hash"] = hash;
246  return ret_val;
247  }
248  };
249  static htlc_hash_to_variant_visitor hash_visitor;
250  fc::mutable_variant_object htlc_lock = obj.conditions.hash_lock.preimage_hash.visit(hash_visitor);
251  htlc_lock["preimage_size"] = obj.conditions.hash_lock.preimage_size;
252  fc::mutable_variant_object time_lock;
253  time_lock["expiration"] = obj.conditions.time_lock.expiration;
255  fc::mutable_variant_object conditions;
256  conditions["htlc_lock"] = htlc_lock;
257  conditions["time_lock"] = time_lock;
259  result["transfer"] = transfer;
260  result["conditions"] = conditions;
261  return fc::optional<fc::variant>(result);
262  }
263  return fc::optional<fc::variant>();
264 }
265 
266 signed_transaction wallet_api::htlc_redeem( std::string htlc_id, std::string issuer, const std::string& preimage,
267  bool broadcast)
268 {
269 
270  return my->htlc_redeem(htlc_id, issuer, std::vector<char>(preimage.begin(), preimage.end()), broadcast);
271 }
272 
273 signed_transaction wallet_api::htlc_extend ( std::string htlc_id, std::string issuer, const uint32_t seconds_to_add,
274  bool broadcast)
275 {
276  return my->htlc_extend(htlc_id, issuer, seconds_to_add, broadcast);
277 }
278 
279 vector<operation_detail> wallet_api::get_account_history(const string& name, uint32_t limit)const
280 {
281  vector<operation_detail> result;
282 
283  while( limit > 0 )
284  {
285  bool skip_first_row = false;
286  operation_history_id_type start;
287  if( result.size() )
288  {
289  start = result.back().op.id;
290  if( start == operation_history_id_type() ) // no more data
291  break;
292  start = start + (-1);
293  if( start == operation_history_id_type() ) // will return most recent history if
294  // directly call remote API with this
295  {
296  start = start + 1;
297  skip_first_row = true;
298  }
299  }
300 
301  uint32_t default_page_size = 100;
302  uint32_t page_limit = skip_first_row ? std::min<uint32_t>( default_page_size, limit + 1 )
303  : std::min<uint32_t>( default_page_size, limit );
304 
305  vector<operation_history_object> current = my->_remote_hist->get_account_history(
306  name,
307  operation_history_id_type(),
308  page_limit,
309  start );
310  bool first_row = true;
311  for( auto& o : current )
312  {
313  if( first_row )
314  {
315  first_row = false;
316  if( skip_first_row )
317  {
318  continue;
319  }
320  }
321  std::stringstream ss;
322  auto memo = o.op.visit(detail::operation_printer(ss, *my, o));
323  result.push_back( operation_detail{ memo, ss.str(), o } );
324  }
325 
326  if( current.size() < page_limit )
327  break;
328 
329  limit -= current.size();
330  if( skip_first_row )
331  ++limit;
332  }
333 
334  return result;
335 }
336 
338  const string& name,
339  uint32_t stop,
340  uint32_t limit,
341  uint32_t start)const
342 {
343  vector<operation_detail> result;
344  auto account_id = get_account(name).get_id();
345 
346  const account_object& account = my->get_account(account_id);
347  const account_statistics_object& stats = my->get_object(account.statistics);
348 
349  if(start == 0)
350  start = stats.total_ops;
351  else
352  start = std::min<uint32_t>(start, stats.total_ops);
353 
354  uint32_t default_page_size = 100;
355  while( limit > 0 )
356  {
357  uint32_t page_size = std::min<uint32_t>(default_page_size, limit);
358  vector <operation_history_object> current = my->_remote_hist->get_relative_account_history(
359  name,
360  stop,
361  page_size,
362  start);
363  for (auto &o : current) {
364  std::stringstream ss;
365  auto memo = o.op.visit(detail::operation_printer(ss, *my, o));
366  result.push_back(operation_detail{memo, ss.str(), o});
367  }
368  if (current.size() < page_size)
369  break;
370  limit -= page_size;
371  start -= page_size;
372  if( start == 0 ) break;
373  }
374  return result;
375 }
376 
378  const string& name,
379  const flat_set<uint16_t>& operation_types,
380  uint32_t start,
381  uint32_t limit)
382 {
384 
385  const auto& account = my->get_account(name);
386  const auto& stats = my->get_object(account.statistics);
387 
388  // sequence of account_transaction_history_object start with 1
389  start = start == 0 ? 1 : start;
390 
391  if (start <= stats.removed_ops) {
392  start = stats.removed_ops;
393  result.total_count =stats.removed_ops;
394  }
395 
396  uint32_t default_page_size = 100;
397  while (limit > 0 && start <= stats.total_ops) {
398  uint32_t min_limit = std::min(default_page_size, limit);
399  auto current = my->_remote_hist->get_account_history_by_operations(name, operation_types, start, min_limit);
400  auto his_rend = current.operation_history_objs.rend();
401  for( auto it = current.operation_history_objs.rbegin(); it != his_rend; ++it )
402  {
403  auto& obj = *it;
404  std::stringstream ss;
405  auto memo = obj.op.visit(detail::operation_printer(ss, *my, obj));
406 
407  transaction_id_type transaction_id;
408  auto block = get_block(obj.block_num);
409  if (block.valid() && obj.trx_in_block < block->transaction_ids.size()) {
410  transaction_id = block->transaction_ids[obj.trx_in_block];
411  }
412  result.details.push_back(operation_detail_ex{memo, ss.str(), obj, transaction_id});
413  }
414  result.result_count += current.operation_history_objs.size();
415  result.total_count += current.total_count;
416 
417  start += current.total_count > 0 ? current.total_count : min_limit;
418  limit -= current.operation_history_objs.size();
419  }
420 
421  return result;
422 }
423 
424 full_account wallet_api::get_full_account( const string& name_or_id)
425 {
426  return my->_remote_db->get_full_accounts({name_or_id}, false)[name_or_id];
427 }
428 
429 vector<bucket_object> wallet_api::get_market_history(
430  string symbol1,
431  string symbol2,
432  uint32_t bucket,
433  fc::time_point_sec start,
434  fc::time_point_sec end )const
435 {
436  return my->_remote_hist->get_market_history( symbol1, symbol2, bucket, start, end );
437 }
438 
439 vector<limit_order_object> wallet_api::get_account_limit_orders(
440  const string& name_or_id,
441  const string &base,
442  const string &quote,
443  uint32_t limit,
444  optional<limit_order_id_type> ostart_id,
445  optional<price> ostart_price)
446 {
447  return my->_remote_db->get_account_limit_orders(name_or_id, base, quote, limit, ostart_id, ostart_price);
448 }
449 
450 vector<limit_order_object> wallet_api::get_limit_orders(std::string a, std::string b, uint32_t limit)const
451 {
452  return my->_remote_db->get_limit_orders(a, b, limit);
453 }
454 
455 vector<call_order_object> wallet_api::get_call_orders(std::string a, uint32_t limit)const
456 {
457  return my->_remote_db->get_call_orders(a, limit);
458 }
459 
460 vector<force_settlement_object> wallet_api::get_settle_orders(std::string a, uint32_t limit)const
461 {
462  return my->_remote_db->get_settle_orders(a, limit);
463 }
464 
465 vector<collateral_bid_object> wallet_api::get_collateral_bids(std::string asset, uint32_t limit, uint32_t start)const
466 {
467  return my->_remote_db->get_collateral_bids(asset, limit, start);
468 }
469 
471 {
473 }
474 
476  string brain_key,
477  int number_of_desired_keys) const
478 {
479  return graphene::wallet::utility::derive_owner_keys_from_brain_key(brain_key, number_of_desired_keys);
480 }
481 
483 {
484  bool is_known = my->_remote_db->is_public_key_registered(public_key);
485  return is_known;
486 }
487 
488 
489 string wallet_api::serialize_transaction( signed_transaction tx )const
490 {
491  return fc::to_hex(fc::raw::pack(tx));
492 }
493 
494 variant wallet_api::get_object( object_id_type id ) const
495 {
496  return my->_remote_db->get_objects({id}, {});
497 }
498 
500 {
501  return my->get_wallet_filename();
502 }
503 
505 {
506  return my->begin_builder_transaction();
507 }
508 
510  transaction_handle_type transaction_handle,
511  const operation& op)
512 {
513  my->add_operation_to_builder_transaction(transaction_handle, op);
514 }
515 
518  unsigned operation_index,
519  const operation& new_op)
520 {
521  my->replace_operation_in_builder_transaction(handle, operation_index, new_op);
522 }
523 
525 {
526  return my->set_fees_on_builder_transaction(handle, fee_asset);
527 }
528 
530 {
531  return my->preview_builder_transaction(handle);
532 }
533 
534 signed_transaction wallet_api::sign_builder_transaction(transaction_handle_type transaction_handle, bool broadcast)
535 {
536  return my->sign_builder_transaction(transaction_handle, broadcast);
537 }
538 
540  const vector<public_key_type>& explicit_keys,
541  bool broadcast)
542 {
543  return my->sign_builder_transaction2(transaction_handle, explicit_keys, broadcast);
544 }
545 
546 pair<transaction_id_type,signed_transaction> wallet_api::broadcast_transaction(signed_transaction tx)
547 {
548  return my->broadcast_transaction(tx);
549 }
550 
553  time_point_sec expiration,
554  uint32_t review_period_seconds,
555  bool broadcast)
556 {
557  return my->propose_builder_transaction(handle, expiration, review_period_seconds, broadcast);
558 }
559 
562  string account_name_or_id,
563  time_point_sec expiration,
564  uint32_t review_period_seconds,
565  bool broadcast)
566 {
567  return my->propose_builder_transaction2(handle, account_name_or_id, expiration, review_period_seconds, broadcast);
568 }
569 
571 {
572  return my->remove_builder_transaction(handle);
573 }
574 
575 account_object wallet_api::get_account(string account_name_or_id) const
576 {
577  return my->get_account(account_name_or_id);
578 }
579 
580 extended_asset_object wallet_api::get_asset(string asset_name_or_id) const
581 {
582  auto found_asset = my->find_asset(asset_name_or_id);
583  FC_ASSERT( found_asset, "Unable to find asset '${a}'", ("a",asset_name_or_id) );
584  return *found_asset;
585 }
586 
588 {
589  auto asset = get_asset(asset_name_or_id);
590  FC_ASSERT(asset.is_market_issued() && asset.bitasset_data_id);
591  return my->get_object(*asset.bitasset_data_id);
592 }
593 
594 account_id_type wallet_api::get_account_id(string account_name_or_id) const
595 {
596  return my->get_account_id(account_name_or_id);
597 }
598 
599 asset_id_type wallet_api::get_asset_id(const string& asset_symbol_or_id) const
600 {
601  return my->get_asset_id(asset_symbol_or_id);
602 }
603 
604 bool wallet_api::import_key(string account_name_or_id, string wif_key)
605 {
606  FC_ASSERT(!is_locked());
607  // backup wallet
608  fc::optional<fc::ecc::private_key> optional_private_key = wif_to_key(wif_key);
609  if (!optional_private_key)
610  FC_THROW("Invalid private key");
611  string shorthash = detail::address_to_shorthash(optional_private_key->get_public_key());
612  copy_wallet_file( "before-import-key-" + shorthash );
613 
614  if( my->import_key(account_name_or_id, wif_key) )
615  {
617  copy_wallet_file( "after-import-key-" + shorthash );
618  return true;
619  }
620  return false;
621 }
622 
623 map<string, bool> wallet_api::import_accounts( string filename, string password )
624 {
625  FC_ASSERT( !is_locked() );
626  FC_ASSERT( fc::exists( filename ) );
627 
628  const auto imported_keys = fc::json::from_file<exported_keys>( filename );
629 
630  const auto password_hash = fc::sha512::hash( password );
631  FC_ASSERT( fc::sha512::hash( password_hash ) == imported_keys.password_checksum );
632 
633  map<string, bool> result;
634  for( const auto& item : imported_keys.account_keys )
635  {
636  const auto import_this_account = [ & ]() -> bool
637  {
638  try
639  {
640  const account_object account = get_account( item.account_name );
641  const auto& owner_keys = account.owner.get_keys();
642  const auto& active_keys = account.active.get_keys();
643 
644  for( const auto& public_key : item.public_keys )
645  {
646  if( std::find( owner_keys.begin(), owner_keys.end(), public_key ) != owner_keys.end() )
647  return true;
648 
649  if( std::find( active_keys.begin(), active_keys.end(), public_key ) != active_keys.end() )
650  return true;
651  }
652  }
653  catch( ... )
654  {
655  }
656 
657  return false;
658  };
659 
660  const auto should_proceed = import_this_account();
661  result[ item.account_name ] = should_proceed;
662 
663  if( should_proceed )
664  {
665  uint32_t import_successes = 0;
666  uint32_t import_failures = 0;
667  // TODO: First check that all private keys match public keys
668  for( const auto& encrypted_key : item.encrypted_private_keys )
669  {
670  try
671  {
672  const auto plain_text = fc::aes_decrypt( password_hash, encrypted_key );
673  const auto private_key = fc::raw::unpack<private_key_type>( plain_text );
674 
675  import_key( item.account_name, string( graphene::utilities::key_to_wif( private_key ) ) );
676  ++import_successes;
677  }
678  catch( const fc::exception& e )
679  {
680  elog( "Couldn't import key due to exception ${e}", ("e", e.to_detail_string()) );
681  ++import_failures;
682  }
683  }
684  ilog( "successfully imported ${n} keys for account ${name}",
685  ("n", import_successes)("name", item.account_name) );
686  if( import_failures > 0 )
687  elog( "failed to import ${n} keys for account ${name}",
688  ("n", import_failures)("name", item.account_name) );
689  }
690  }
691 
692  return result;
693 }
694 
696  string filename,
697  string password,
698  string src_account_name,
699  string dest_account_name )
700 {
701  FC_ASSERT( !is_locked() );
702  FC_ASSERT( fc::exists( filename ) );
703 
704  bool is_my_account = false;
705  const auto accounts = list_my_accounts();
706  for( const auto& account : accounts )
707  {
708  if( account.name == dest_account_name )
709  {
710  is_my_account = true;
711  break;
712  }
713  }
714  FC_ASSERT( is_my_account );
715 
716  const auto imported_keys = fc::json::from_file<exported_keys>( filename );
717 
718  const auto password_hash = fc::sha512::hash( password );
719  FC_ASSERT( fc::sha512::hash( password_hash ) == imported_keys.password_checksum );
720 
721  bool found_account = false;
722  for( const auto& item : imported_keys.account_keys )
723  {
724  if( item.account_name != src_account_name )
725  continue;
726 
727  found_account = true;
728 
729  for( const auto& encrypted_key : item.encrypted_private_keys )
730  {
731  const auto plain_text = fc::aes_decrypt( password_hash, encrypted_key );
732  const auto private_key = fc::raw::unpack<private_key_type>( plain_text );
733 
734  my->import_key( dest_account_name, string( graphene::utilities::key_to_wif( private_key ) ) );
735  }
736 
737  return true;
738  }
740 
741  FC_ASSERT( found_account );
742 
743  return false;
744 }
745 
746 string wallet_api::normalize_brain_key(string s) const
747 {
748  return detail::normalize_brain_key( s );
749 }
750 
752 {
753  return my->info();
754 }
755 
756 variant_object wallet_api::about() const
757 {
758  return my->about();
759 }
760 
761 fc::ecc::private_key wallet_api::derive_private_key(const std::string& prefix_string, int sequence_number) const
762 {
763  return detail::derive_private_key( prefix_string, sequence_number );
764 }
765 
766 signed_transaction wallet_api::register_account(string name,
767  public_key_type owner_pubkey,
768  public_key_type active_pubkey,
769  string registrar_account,
770  string referrer_account,
771  uint32_t referrer_percent,
772  bool broadcast)
773 {
774  return my->register_account( name, owner_pubkey, active_pubkey,
775  registrar_account, referrer_account, referrer_percent, broadcast );
776 }
777 signed_transaction wallet_api::create_account_with_brain_key(string brain_key, string account_name,
778  string registrar_account, string referrer_account,
779  bool broadcast /* = false */)
780 {
781  return my->create_account_with_brain_key(
782  brain_key, account_name, registrar_account,
783  referrer_account, broadcast
784  );
785 }
786 signed_transaction wallet_api::issue_asset(string to_account, string amount, string symbol,
787  string memo, bool broadcast)
788 {
789  return my->issue_asset(to_account, amount, symbol, memo, broadcast);
790 }
791 
792 signed_transaction wallet_api::transfer(string from, string to, string amount,
793  string asset_symbol, string memo, bool broadcast /* = false */)
794 {
795  return my->transfer(from, to, amount, asset_symbol, memo, broadcast);
796 }
797 signed_transaction wallet_api::create_asset(string issuer,
798  string symbol,
799  uint8_t precision,
800  asset_options common,
801  fc::optional<bitasset_options> bitasset_opts,
802  bool broadcast)
803 
804 {
805  return my->create_asset(issuer, symbol, precision, common, bitasset_opts, broadcast);
806 }
807 
808 signed_transaction wallet_api::update_asset(string symbol,
809  optional<string> new_issuer,
810  asset_options new_options,
811  bool broadcast /* = false */)
812 {
813  return my->update_asset(symbol, new_issuer, new_options, broadcast);
814 }
815 
816 signed_transaction wallet_api::update_asset_issuer(string symbol,
817  string new_issuer,
818  bool broadcast /* = false */)
819 {
820  return my->update_asset_issuer(symbol, new_issuer, broadcast);
821 }
822 
823 signed_transaction wallet_api::update_bitasset(string symbol,
824  bitasset_options new_options,
825  bool broadcast /* = false */)
826 {
827  return my->update_bitasset(symbol, new_options, broadcast);
828 }
829 
830 signed_transaction wallet_api::update_asset_feed_producers(string symbol,
831  flat_set<string> new_feed_producers,
832  bool broadcast /* = false */)
833 {
834  return my->update_asset_feed_producers(symbol, new_feed_producers, broadcast);
835 }
836 
837 signed_transaction wallet_api::publish_asset_feed(string publishing_account,
838  string symbol,
839  price_feed feed,
840  bool broadcast /* = false */)
841 {
842  return my->publish_asset_feed(publishing_account, symbol, feed, broadcast);
843 }
844 
845 signed_transaction wallet_api::fund_asset_fee_pool(string from,
846  string symbol,
847  string amount,
848  bool broadcast /* = false */)
849 {
850  return my->fund_asset_fee_pool(from, symbol, amount, broadcast);
851 }
852 
853 signed_transaction wallet_api::claim_asset_fee_pool(string symbol,
854  string amount,
855  bool broadcast /* = false */)
856 {
857  return my->claim_asset_fee_pool(symbol, amount, broadcast);
858 }
859 
860 signed_transaction wallet_api::reserve_asset(string from,
861  string amount,
862  string symbol,
863  bool broadcast /* = false */)
864 {
865  return my->reserve_asset(from, amount, symbol, broadcast);
866 }
867 
868 signed_transaction wallet_api::global_settle_asset(string symbol,
869  price settle_price,
870  bool broadcast /* = false */)
871 {
872  return my->global_settle_asset(symbol, settle_price, broadcast);
873 }
874 
875 signed_transaction wallet_api::settle_asset(string account_to_settle,
876  string amount_to_settle,
877  string symbol,
878  bool broadcast /* = false */)
879 {
880  return my->settle_asset(account_to_settle, amount_to_settle, symbol, broadcast);
881 }
882 
883 signed_transaction wallet_api::bid_collateral(string bidder_name,
884  string debt_amount, string debt_symbol,
885  string additional_collateral,
886  bool broadcast )
887 {
888  return my->bid_collateral(bidder_name, debt_amount, debt_symbol, additional_collateral, broadcast);
889 }
890 
891 signed_transaction wallet_api::whitelist_account(string authorizing_account,
892  string account_to_list,
893  account_whitelist_operation::account_listing new_listing_status,
894  bool broadcast /* = false */)
895 {
896  return my->whitelist_account(authorizing_account, account_to_list, new_listing_status, broadcast);
897 }
898 
899 signed_transaction wallet_api::create_committee_member(string owner_account, string url,
900  bool broadcast /* = false */)
901 {
902  return my->create_committee_member(owner_account, url, broadcast);
903 }
904 
905 map<string,witness_id_type> wallet_api::list_witnesses(const string& lowerbound, uint32_t limit)
906 {
907  return my->_remote_db->lookup_witness_accounts(lowerbound, limit);
908 }
909 
910 map<string,committee_member_id_type> wallet_api::list_committee_members(const string& lowerbound, uint32_t limit)
911 {
912  return my->_remote_db->lookup_committee_member_accounts(lowerbound, limit);
913 }
914 
916 {
917  return my->get_witness(owner_account);
918 }
919 
921 {
922  return my->get_committee_member(owner_account);
923 }
924 
925 signed_transaction wallet_api::create_witness(string owner_account,
926  string url,
927  bool broadcast /* = false */)
928 {
929  return my->create_witness(owner_account, url, broadcast);
930 }
931 
932 signed_transaction wallet_api::create_worker(
933  string owner_account,
934  time_point_sec work_begin_date,
935  time_point_sec work_end_date,
936  share_type daily_pay,
937  string name,
938  string url,
939  variant worker_settings,
940  bool broadcast /* = false */)
941 {
942  return my->create_worker( owner_account, work_begin_date, work_end_date,
943  daily_pay, name, url, worker_settings, broadcast );
944 }
945 
947  string owner_account,
948  worker_vote_delta delta,
949  bool broadcast /* = false */)
950 {
951  return my->update_worker_votes( owner_account, delta, broadcast );
952 }
953 
954 signed_transaction wallet_api::update_witness(
955  string witness_name,
956  string url,
957  string block_signing_key,
958  bool broadcast /* = false */)
959 {
960  return my->update_witness(witness_name, url, block_signing_key, broadcast);
961 }
962 
963 vector< vesting_balance_object_with_info > wallet_api::get_vesting_balances( string account_name )
964 {
965  return my->get_vesting_balances( account_name );
966 }
967 
968 signed_transaction wallet_api::withdraw_vesting(
969  string witness_name,
970  string amount,
971  string asset_symbol,
972  bool broadcast /* = false */)
973 {
974  return my->withdraw_vesting( witness_name, amount, asset_symbol, broadcast );
975 }
976 
977 signed_transaction wallet_api::vote_for_committee_member(string voting_account,
978  string witness,
979  bool approve,
980  bool broadcast /* = false */)
981 {
982  return my->vote_for_committee_member(voting_account, witness, approve, broadcast);
983 }
984 
985 signed_transaction wallet_api::vote_for_witness(string voting_account,
986  string witness,
987  bool approve,
988  bool broadcast /* = false */)
989 {
990  return my->vote_for_witness(voting_account, witness, approve, broadcast);
991 }
992 
993 signed_transaction wallet_api::set_voting_proxy(string account_to_modify,
994  optional<string> voting_account,
995  bool broadcast /* = false */)
996 {
997  return my->set_voting_proxy(account_to_modify, voting_account, broadcast);
998 }
999 
1000 signed_transaction wallet_api::set_desired_witness_and_committee_member_count(string account_to_modify,
1001  uint16_t desired_number_of_witnesses,
1002  uint16_t desired_number_of_committee_members,
1003  bool broadcast /* = false */)
1004 {
1005  return my->set_desired_witness_and_committee_member_count(account_to_modify, desired_number_of_witnesses,
1006  desired_number_of_committee_members, broadcast);
1007 }
1008 
1009 void wallet_api::set_wallet_filename(string wallet_filename)
1010 {
1011  my->_wallet_filename = wallet_filename;
1012 }
1013 
1014 signed_transaction wallet_api::sign_transaction(signed_transaction tx, bool broadcast /* = false */)
1015 { try {
1016  return my->sign_transaction( tx, broadcast);
1017 } FC_CAPTURE_AND_RETHROW( (tx) ) }
1018 
1019 signed_transaction wallet_api::sign_transaction2(signed_transaction tx, const vector<public_key_type>& signing_keys,
1020  bool broadcast /* = false */)
1021 { try {
1022  return my->sign_transaction2( tx, signing_keys, broadcast);
1023 } FC_CAPTURE_AND_RETHROW( (tx) ) }
1024 
1025 flat_set<public_key_type> wallet_api::get_transaction_signers(const signed_transaction &tx) const
1026 { try {
1027  return my->get_transaction_signers(tx);
1028 } FC_CAPTURE_AND_RETHROW( (tx) ) }
1029 
1030 vector<flat_set<account_id_type>> wallet_api::get_key_references(const vector<public_key_type> &keys) const
1031 { try {
1032  return my->get_key_references(keys);
1033 } FC_CAPTURE_AND_RETHROW( (keys) ) }
1034 
1036 {
1037  return my->get_prototype_operation( operation_name );
1038 }
1039 
1040 void wallet_api::dbg_make_uia(string creator, string symbol)
1041 {
1042  FC_ASSERT(!is_locked());
1043  my->dbg_make_uia(creator, symbol);
1044 }
1045 
1046 void wallet_api::dbg_make_mia(string creator, string symbol)
1047 {
1048  FC_ASSERT(!is_locked());
1049  my->dbg_make_mia(creator, symbol);
1050 }
1051 
1052 void wallet_api::dbg_push_blocks( std::string src_filename, uint32_t count )
1053 {
1054  my->dbg_push_blocks( src_filename, count );
1055 }
1056 
1057 void wallet_api::dbg_generate_blocks( std::string debug_wif_key, uint32_t count )
1058 {
1059  my->dbg_generate_blocks( debug_wif_key, count );
1060 }
1061 
1062 void wallet_api::dbg_stream_json_objects( const std::string& filename )
1063 {
1064  my->dbg_stream_json_objects( filename );
1065 }
1066 
1068 {
1069  my->dbg_update_object( update );
1070 }
1071 
1072 void wallet_api::network_add_nodes( const vector<string>& nodes )
1073 {
1074  my->network_add_nodes( nodes );
1075 }
1076 
1078 {
1079  return my->network_get_connected_peers();
1080 }
1081 
1082 void wallet_api::flood_network(string prefix, uint32_t number_of_transactions)
1083 {
1084  FC_ASSERT(!is_locked());
1085  my->flood_network(prefix, number_of_transactions);
1086 }
1087 
1089  const string& proposing_account,
1090  fc::time_point_sec expiration_time,
1091  const variant_object& changed_values,
1092  bool broadcast /* = false */
1093  )
1094 {
1095  return my->propose_parameter_change( proposing_account, expiration_time, changed_values, broadcast );
1096 }
1097 
1099  const string& proposing_account,
1100  fc::time_point_sec expiration_time,
1101  const variant_object& changed_fees,
1102  bool broadcast /* = false */
1103  )
1104 {
1105  return my->propose_fee_change( proposing_account, expiration_time, changed_fees, broadcast );
1106 }
1107 
1108 signed_transaction wallet_api::approve_proposal(
1109  const string& fee_paying_account,
1110  const string& proposal_id,
1111  const approval_delta& delta,
1112  bool broadcast /* = false */
1113  )
1114 {
1115  return my->approve_proposal( fee_paying_account, proposal_id, delta, broadcast );
1116 }
1117 
1119 {
1120  return my->get_global_properties();
1121 }
1122 
1124 {
1125  return my->get_dynamic_global_properties();
1126 }
1127 
1128 signed_transaction wallet_api::add_transaction_signature( signed_transaction tx,
1129  bool broadcast )
1130 {
1131  return my->add_transaction_signature( tx, broadcast );
1132 }
1133 
1134 string wallet_api::help()const
1135 {
1136  std::vector<std::string> method_names = my->method_documentation.get_method_names();
1137  std::stringstream ss;
1138  for (const std::string& method_name : method_names)
1139  {
1140  try
1141  {
1142  ss << my->method_documentation.get_brief_description(method_name);
1143  }
1144  catch (const fc::key_not_found_exception&)
1145  {
1146  ss << method_name << " (no help available)\n";
1147  }
1148  }
1149  return ss.str();
1150 }
1151 
1152 string wallet_api::gethelp(const string& method)const
1153 {
1154  fc::api<wallet_api> tmp;
1155  std::stringstream ss;
1156  ss << "\n";
1157 
1158  std::string doxygenHelpString = my->method_documentation.get_detailed_description(method);
1159  if (!doxygenHelpString.empty())
1160  ss << doxygenHelpString << "\n";
1161 
1162  if( method == "import_key" )
1163  {
1164  ss << "usage: import_key ACCOUNT_NAME_OR_ID WIF_PRIVATE_KEY\n\n";
1165  ss << "example: import_key \"1.3.11\" 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\n";
1166  ss << "example: import_key \"usera\" 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3\n";
1167  }
1168  else if( method == "transfer" )
1169  {
1170  ss << "usage: transfer FROM TO AMOUNT SYMBOL \"memo\" BROADCAST\n\n";
1171  ss << "example: transfer \"1.3.11\" \"1.3.4\" 1000.03 CORE \"memo\" true\n";
1172  ss << "example: transfer \"usera\" \"userb\" 1000.123 CORE \"memo\" true\n";
1173  }
1174  else if( method == "create_account_with_brain_key" )
1175  {
1176  ss << "usage: create_account_with_brain_key BRAIN_KEY ACCOUNT_NAME REGISTRAR REFERRER BROADCAST\n\n";
1177  ss << "example: create_account_with_brain_key "
1178  << "\"my really long brain key\" \"newaccount\" \"1.3.11\" \"1.3.11\" true\n";
1179  ss << "example: create_account_with_brain_key "
1180  << "\"my really long brain key\" \"newaccount\" \"someaccount\" \"otheraccount\" true\n";
1181  ss << "\n";
1182  ss << "This method should be used if you would like the wallet to generate new keys derived from the "
1183  << "brain key.\n";
1184  ss << "The BRAIN_KEY will be used as the owner key, and the active key will be derived from the BRAIN_KEY. "
1185  << "Use\n";
1186  ss << "register_account if you already know the keys you know the public keys that you would like to "
1187  << "register.\n";
1188 
1189  }
1190  else if( method == "register_account" )
1191  {
1192  ss << "usage: register_account ACCOUNT_NAME OWNER_PUBLIC_KEY ACTIVE_PUBLIC_KEY REGISTRAR "
1193  << "REFERRER REFERRER_PERCENT BROADCAST\n\n";
1194  ss << "example: register_account \"newaccount\" \"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" "
1195  << "\"CORE6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV\" \"1.3.11\" \"1.3.11\" 50 true\n";
1196  ss << "\n";
1197  ss << "Use this method to register an account for which you do not know the private keys.";
1198  }
1199  else if( method == "create_asset" )
1200  {
1201  ss << "usage: ISSUER SYMBOL PRECISION_DIGITS OPTIONS BITASSET_OPTIONS BROADCAST\n\n";
1202  ss << "PRECISION_DIGITS: the number of digits after the decimal point\n\n";
1203  ss << "Example value of OPTIONS: \n";
1205  ss << "\nExample value of BITASSET_OPTIONS: \n";
1207  ss << "\nBITASSET_OPTIONS may be null\n";
1208  }
1209  else if (doxygenHelpString.empty())
1210  ss << "No help defined for method " << method << "\n";
1211 
1212  return ss.str();
1213 }
1214 
1215 bool wallet_api::load_wallet_file( string wallet_filename )
1216 {
1217  return my->load_wallet_file( wallet_filename );
1218 }
1219 
1221 {
1222  my->quit();
1223 }
1224 
1225 void wallet_api::save_wallet_file( string wallet_filename )
1226 {
1227  my->save_wallet_file( wallet_filename );
1228 }
1229 
1230 std::map<string,std::function<string(fc::variant,const fc::variants&)> >
1232 {
1233  return my->get_result_formatters();
1234 }
1235 
1237 {
1238  return my->is_locked();
1239 }
1241 {
1242  return my->_wallet.cipher_keys.size() == 0;
1243 }
1244 
1246 {
1247  my->encrypt_keys();
1248 }
1249 
1251 { try {
1252  FC_ASSERT( !is_locked() );
1253  encrypt_keys();
1254  for( auto key : my->_keys )
1255  key.second = key_to_wif(fc::ecc::private_key());
1256  my->_keys.clear();
1257  my->_checksum = fc::sha512();
1258  my->self.lock_changed(true);
1260 
1261 void wallet_api::unlock(string password)
1262 { try {
1263  FC_ASSERT(password.size() > 0);
1264  auto pw = fc::sha512::hash(password.c_str(), password.size());
1265  vector<char> decrypted = fc::aes_decrypt(pw, my->_wallet.cipher_keys);
1266  auto pk = fc::raw::unpack<plain_keys>(decrypted);
1267  FC_ASSERT(pk.checksum == pw);
1268  my->_keys = std::move(pk.keys);
1269  my->_checksum = pk.checksum;
1270  my->self.lock_changed(false);
1272 
1273 void wallet_api::set_password( string password )
1274 {
1275  if( !is_new() )
1276  FC_ASSERT( !is_locked(), "The wallet must be unlocked before the password can be set" );
1277  my->_checksum = fc::sha512::hash( password.c_str(), password.size() );
1278  lock();
1279 }
1280 
1281 vector< signed_transaction > wallet_api::import_balance(
1282  string name_or_id,
1283  const vector<string>& wif_keys,
1284  bool broadcast )
1285 {
1286  return my->import_balance( name_or_id, wif_keys, broadcast );
1287 }
1288 
1289 map<public_key_type, string> wallet_api::dump_private_keys()
1290 {
1291  FC_ASSERT(!is_locked());
1292  return my->_keys;
1293 }
1294 
1295 signed_transaction wallet_api::upgrade_account( string name, bool broadcast )
1296 {
1297  return my->upgrade_account(name,broadcast);
1298 }
1299 
1300 signed_transaction wallet_api::sell_asset(string seller_account,
1301  string amount_to_sell,
1302  string symbol_to_sell,
1303  string min_to_receive,
1304  string symbol_to_receive,
1305  uint32_t expiration,
1306  bool fill_or_kill,
1307  bool broadcast)
1308 {
1309  return my->sell_asset(seller_account, amount_to_sell, symbol_to_sell, min_to_receive,
1310  symbol_to_receive, expiration, fill_or_kill, broadcast);
1311 }
1312 
1313 signed_transaction wallet_api::borrow_asset(string seller_name, string amount_to_sell,
1314  string asset_symbol, string amount_of_collateral, bool broadcast)
1315 {
1316  FC_ASSERT(!is_locked());
1317  return my->borrow_asset(seller_name, amount_to_sell, asset_symbol, amount_of_collateral, broadcast);
1318 }
1319 
1320 signed_transaction wallet_api::borrow_asset_ext( string seller_name, string amount_to_sell,
1321  string asset_symbol, string amount_of_collateral,
1323  bool broadcast)
1324 {
1325  FC_ASSERT(!is_locked());
1326  return my->borrow_asset_ext(seller_name, amount_to_sell, asset_symbol,
1327  amount_of_collateral, extensions, broadcast);
1328 }
1329 
1330 signed_transaction wallet_api::cancel_order(object_id_type order_id, bool broadcast)
1331 {
1332  FC_ASSERT(!is_locked());
1333  return my->cancel_order(order_id, broadcast);
1334 }
1335 
1336 memo_data wallet_api::sign_memo(string from, string to, string memo)
1337 {
1338  FC_ASSERT(!is_locked());
1339  return my->sign_memo(from, to, memo);
1340 }
1341 
1342 string wallet_api::read_memo(const memo_data& memo)
1343 {
1344  FC_ASSERT(!is_locked());
1345  return my->read_memo(memo);
1346 }
1347 
1349 {
1350  FC_ASSERT(!is_locked());
1351  return my->sign_message(signer, message);
1352 }
1353 
1354 bool wallet_api::verify_message( string message, string account, int block, const string& time, compact_signature sig )
1355 {
1356  return my->verify_message( message, account, block, time, sig );
1357 }
1358 
1365 {
1366  return my->verify_signed_message( message );
1367 }
1368 
1375 {
1376  return my->verify_encapsulated_message( message );
1377 }
1378 
1379 
1380 string wallet_api::get_key_label( public_key_type key )const
1381 {
1382  auto key_itr = my->_wallet.labeled_keys.get<by_key>().find(key);
1383  if( key_itr != my->_wallet.labeled_keys.get<by_key>().end() )
1384  return key_itr->label;
1385  return string();
1386 }
1387 
1388 string wallet_api::get_private_key( public_key_type pubkey )const
1389 {
1390  return key_to_wif( my->get_private_key( pubkey ) );
1391 }
1392 
1393 public_key_type wallet_api::get_public_key( string label )const
1394 {
1395  try { return fc::variant(label, 1).as<public_key_type>( 1 ); } catch ( ... ){}
1396 
1397  auto key_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
1398  if( key_itr != my->_wallet.labeled_keys.get<by_label>().end() )
1399  return key_itr->key;
1400  return public_key_type();
1401 }
1402 
1403 bool wallet_api::set_key_label( public_key_type key, string label )
1404 {
1405  auto result = my->_wallet.labeled_keys.insert( key_label{label,key} );
1406  if( result.second ) return true;
1407 
1408  auto key_itr = my->_wallet.labeled_keys.get<by_key>().find(key);
1409  auto label_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
1410  if( label_itr == my->_wallet.labeled_keys.get<by_label>().end() )
1411  {
1412  if( key_itr != my->_wallet.labeled_keys.get<by_key>().end() )
1413  return my->_wallet.labeled_keys.get<by_key>().modify( key_itr, [&]( key_label& obj ){ obj.label = label; } );
1414  }
1415  return false;
1416 }
1417 map<string,public_key_type> wallet_api::get_blind_accounts()const
1418 {
1419  map<string,public_key_type> result;
1420  for( const auto& item : my->_wallet.labeled_keys )
1421  result[item.label] = item.key;
1422  return result;
1423 }
1424 map<string,public_key_type> wallet_api::get_my_blind_accounts()const
1425 {
1426  FC_ASSERT( !is_locked() );
1427  map<string,public_key_type> result;
1428  for( const auto& item : my->_wallet.labeled_keys )
1429  {
1430  if( my->_keys.find(item.key) != my->_keys.end() )
1431  result[item.label] = item.key;
1432  }
1433  return result;
1434 }
1435 
1436 public_key_type wallet_api::create_blind_account( string label, string brain_key )
1437 {
1438  FC_ASSERT( !is_locked() );
1439 
1440  auto label_itr = my->_wallet.labeled_keys.get<by_label>().find(label);
1441  if( label_itr != my->_wallet.labeled_keys.get<by_label>().end() )
1442  FC_ASSERT( !"Key with label already exists" );
1443  brain_key = fc::trim_and_normalize_spaces( brain_key );
1444  auto secret = fc::sha256::hash( brain_key.c_str(), brain_key.size() );
1445  auto priv_key = fc::ecc::private_key::regenerate( secret );
1446  public_key_type pub_key = priv_key.get_public_key();
1447 
1448  FC_ASSERT( set_key_label( pub_key, label ) );
1449 
1450  my->_keys[pub_key] = graphene::utilities::key_to_wif( priv_key );
1451 
1452  save_wallet_file();
1453  return pub_key;
1454 }
1455 
1456 vector<asset> wallet_api::get_blind_balances( string key_or_label )
1457 {
1458  vector<asset> result;
1459  map<asset_id_type, share_type> balances;
1460 
1461  vector<commitment_type> used;
1462 
1463  auto pub_key = get_public_key( key_or_label );
1464  auto& to_asset_used_idx = my->_wallet.blind_receipts.get<by_to_asset_used>();
1465  auto start = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(0),false) );
1466  auto end = to_asset_used_idx.lower_bound( std::make_tuple(pub_key,asset_id_type(uint32_t(0xffffffff)),true) );
1467  while( start != end )
1468  {
1469  if( !start->used )
1470  {
1471  auto answer = my->_remote_db->get_blinded_balances( {start->commitment()} );
1472  if( answer.size() )
1473  balances[start->amount.asset_id] += start->amount.amount;
1474  else
1475  used.push_back( start->commitment() );
1476  }
1477  ++start;
1478  }
1479  for( const auto& u : used )
1480  {
1481  auto itr = my->_wallet.blind_receipts.get<by_commitment>().find( u );
1482  my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } );
1483  }
1484  for( auto item : balances )
1485  result.push_back( asset( item.second, item.first ) );
1486  return result;
1487 }
1488 
1489 blind_confirmation wallet_api::transfer_from_blind( string from_blind_account_key_or_label,
1490  string to_account_id_or_name,
1491  string amount_in,
1492  string symbol,
1493  bool broadcast )
1494 { try {
1495  transfer_from_blind_operation from_blind;
1496 
1497 
1498  auto fees = my->_remote_db->get_global_properties().parameters.get_current_fees();
1499  fc::optional<asset_object> asset_obj = get_asset(symbol);
1500  FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol));
1501  auto amount = asset_obj->amount_from_string(amount_in);
1502 
1503  from_blind.fee = fees.calculate_fee( from_blind, asset_obj->options.core_exchange_rate );
1504 
1505  auto blind_in = asset_obj->amount_to_string( from_blind.fee + amount );
1506 
1507 
1508  auto conf = blind_transfer_help( from_blind_account_key_or_label,
1509  from_blind_account_key_or_label,
1510  blind_in, symbol, false, true/*to_temp*/ );
1511  FC_ASSERT( conf.outputs.size() > 0 );
1512 
1513  auto to_account = my->get_account( to_account_id_or_name );
1514  from_blind.to = to_account.id;
1515  from_blind.amount = amount;
1516  from_blind.blinding_factor = conf.outputs.back().decrypted_memo.blinding_factor;
1517  from_blind.inputs.push_back( {conf.outputs.back().decrypted_memo.commitment, authority() } );
1518  from_blind.fee = fees.calculate_fee( from_blind, asset_obj->options.core_exchange_rate );
1519 
1520  idump( (from_blind) );
1521  conf.trx.operations.push_back(from_blind);
1522  ilog( "about to validate" );
1523  conf.trx.validate();
1524 
1525  ilog( "about to broadcast" );
1526  conf.trx = sign_transaction( conf.trx, broadcast );
1527 
1528  if( broadcast && conf.outputs.size() == 2 ) {
1529 
1530  // Save the change
1531  blind_confirmation::output conf_output;
1532  blind_confirmation::output change_output = conf.outputs[0];
1533 
1534  // The wallet must have a private key for confirmation.to, this is used to decrypt the memo
1535  public_key_type from_key = get_public_key(from_blind_account_key_or_label);
1536  conf_output.confirmation.to = from_key;
1537  conf_output.confirmation.one_time_key = change_output.confirmation.one_time_key;
1538  conf_output.confirmation.encrypted_memo = change_output.confirmation.encrypted_memo;
1539  conf_output.confirmation_receipt = conf_output.confirmation;
1540  //try {
1542  from_blind_account_key_or_label,
1543  "@"+to_account.name );
1544  //} catch ( ... ){}
1545  }
1546 
1547  return conf;
1548 } FC_CAPTURE_AND_RETHROW( (from_blind_account_key_or_label)(to_account_id_or_name)(amount_in)(symbol) ) }
1549 
1551  string to_key_or_label,
1552  string amount_in,
1553  string symbol,
1554  bool broadcast )
1555 {
1556  return blind_transfer_help( from_key_or_label, to_key_or_label, amount_in, symbol, broadcast, false );
1557 }
1559  string to_key_or_label,
1560  string amount_in,
1561  string symbol,
1562  bool broadcast,
1563  bool to_temp )
1564 {
1565  blind_confirmation confirm;
1566  try {
1567 
1568  FC_ASSERT( !is_locked() );
1569  public_key_type from_key = get_public_key(from_key_or_label);
1570  public_key_type to_key = get_public_key(to_key_or_label);
1571 
1572  fc::optional<asset_object> asset_obj = get_asset(symbol);
1573  FC_ASSERT(asset_obj.valid(), "Could not find asset matching ${asset}", ("asset", symbol));
1574 
1575  blind_transfer_operation blind_tr;
1576  blind_tr.outputs.resize(2);
1577 
1578  auto fees = my->_remote_db->get_global_properties().parameters.get_current_fees();
1579 
1580  auto amount = asset_obj->amount_from_string(amount_in);
1581 
1582  asset total_amount = asset_obj->amount(0);
1583 
1584  vector<fc::sha256> blinding_factors;
1585 
1586  //auto from_priv_key = my->get_private_key( from_key );
1587 
1588  blind_tr.fee = fees.calculate_fee( blind_tr, asset_obj->options.core_exchange_rate );
1589 
1590  vector<commitment_type> used;
1591 
1592  auto& to_asset_used_idx = my->_wallet.blind_receipts.get<by_to_asset_used>();
1593  auto start = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,false) );
1594  auto end = to_asset_used_idx.lower_bound( std::make_tuple(from_key,amount.asset_id,true) );
1595  while( start != end )
1596  {
1597  auto result = my->_remote_db->get_blinded_balances( {start->commitment() } );
1598  if( result.size() == 0 )
1599  {
1600  used.push_back( start->commitment() );
1601  }
1602  else
1603  {
1604  blind_tr.inputs.push_back({start->commitment(), start->control_authority});
1605  blinding_factors.push_back( start->data.blinding_factor );
1606  total_amount += start->amount;
1607 
1608  if( total_amount >= amount + blind_tr.fee )
1609  break;
1610  }
1611  ++start;
1612  }
1613  for( const auto& u : used )
1614  {
1615  auto itr = my->_wallet.blind_receipts.get<by_commitment>().find( u );
1616  my->_wallet.blind_receipts.modify( itr, []( blind_receipt& r ){ r.used = true; } );
1617  }
1618 
1619  FC_ASSERT( total_amount >= amount+blind_tr.fee,
1620  "Insufficient Balance",
1621  ("available",total_amount)("amount",amount)("fee",blind_tr.fee) );
1622 
1623  auto one_time_key = fc::ecc::private_key::generate();
1624  auto secret = one_time_key.get_shared_secret( to_key );
1625  auto child = fc::sha256::hash( secret );
1626  auto nonce = fc::sha256::hash( one_time_key.get_secret() );
1627  auto blind_factor = fc::sha256::hash( child );
1628 
1629  auto from_secret = one_time_key.get_shared_secret( from_key );
1630  auto from_child = fc::sha256::hash( from_secret );
1631  auto from_nonce = fc::sha256::hash( nonce );
1632 
1633  auto change = total_amount - amount - blind_tr.fee;
1634  fc::sha256 change_blind_factor;
1635  fc::sha256 to_blind_factor;
1636  if( change.amount > 0 )
1637  {
1638  idump(("to_blind_factor")(blind_factor) );
1639  blinding_factors.push_back( blind_factor );
1640  change_blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() - 1 );
1641  wdump(("change_blind_factor")(change_blind_factor) );
1642  }
1643  else // change == 0
1644  {
1645  blind_tr.outputs.resize(1);
1646  blind_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() );
1647  idump(("to_sum_blind_factor")(blind_factor) );
1648  blinding_factors.push_back( blind_factor );
1649  idump(("nochange to_blind_factor")(blind_factor) );
1650  }
1651  fc::ecc::public_key from_pub_key = from_key;
1652  fc::ecc::public_key to_pub_key = to_key;
1653 
1654  blind_output to_out;
1655  to_out.owner = to_temp ? authority() : authority( 1, public_key_type( to_pub_key.child( child ) ), 1 );
1656  to_out.commitment = fc::ecc::blind( blind_factor, amount.amount.value );
1657  idump(("to_out.blind")(blind_factor)(to_out.commitment) );
1658 
1659 
1660  if( blind_tr.outputs.size() > 1 )
1661  {
1662  to_out.range_proof = fc::ecc::range_proof_sign( 0, to_out.commitment, blind_factor, nonce,
1663  0, RANGE_PROOF_MANTISSA, amount.amount.value );
1664 
1665  blind_output change_out;
1666  change_out.owner = authority( 1, public_key_type( from_pub_key.child( from_child ) ), 1 );
1667  change_out.commitment = fc::ecc::blind( change_blind_factor, change.amount.value );
1668  change_out.range_proof = fc::ecc::range_proof_sign( 0, change_out.commitment, change_blind_factor, from_nonce,
1669  0, RANGE_PROOF_MANTISSA, change.amount.value );
1670  blind_tr.outputs[1] = change_out;
1671 
1672 
1673  blind_confirmation::output conf_output;
1674  conf_output.label = from_key_or_label;
1675  conf_output.pub_key = from_key;
1676  conf_output.decrypted_memo.from = from_key;
1677  conf_output.decrypted_memo.amount = change;
1678  conf_output.decrypted_memo.blinding_factor = change_blind_factor;
1679  conf_output.decrypted_memo.commitment = change_out.commitment;
1680  conf_output.decrypted_memo.check = from_secret._hash[0].value();
1681  conf_output.confirmation.one_time_key = one_time_key.get_public_key();
1682  conf_output.confirmation.to = from_key;
1683  conf_output.confirmation.encrypted_memo =
1684  fc::aes_encrypt( from_secret, fc::raw::pack( conf_output.decrypted_memo ) );
1685  conf_output.auth = change_out.owner;
1686  conf_output.confirmation_receipt = conf_output.confirmation;
1687 
1688  confirm.outputs.push_back( conf_output );
1689  }
1690  blind_tr.outputs[0] = to_out;
1691 
1692  blind_confirmation::output conf_output;
1693  conf_output.label = to_key_or_label;
1694  conf_output.pub_key = to_key;
1695  conf_output.decrypted_memo.from = from_key;
1696  conf_output.decrypted_memo.amount = amount;
1697  conf_output.decrypted_memo.blinding_factor = blind_factor;
1698  conf_output.decrypted_memo.commitment = to_out.commitment;
1699  conf_output.decrypted_memo.check = secret._hash[0].value();
1700  conf_output.confirmation.one_time_key = one_time_key.get_public_key();
1701  conf_output.confirmation.to = to_key;
1702  conf_output.confirmation.encrypted_memo = fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) );
1703  conf_output.auth = to_out.owner;
1704  conf_output.confirmation_receipt = conf_output.confirmation;
1705 
1706  confirm.outputs.push_back( conf_output );
1707 
1709  std::sort( blind_tr.outputs.begin(), blind_tr.outputs.end(),
1710  [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } );
1711  std::sort( blind_tr.inputs.begin(), blind_tr.inputs.end(),
1712  [&]( const blind_input& a, const blind_input& b ){ return a.commitment < b.commitment; } );
1713 
1714  confirm.trx.operations.emplace_back( std::move(blind_tr) );
1715  ilog( "validate before" );
1716  confirm.trx.validate();
1717  confirm.trx = sign_transaction(confirm.trx, broadcast);
1718 
1719  if( broadcast )
1720  {
1721  for( const auto& out : confirm.outputs )
1722  {
1723  try { receive_blind_transfer( out.confirmation_receipt, from_key_or_label, "" ); } catch ( ... ){}
1724  }
1725  }
1726 
1727  return confirm;
1728 } FC_CAPTURE_AND_RETHROW( (from_key_or_label)(to_key_or_label)(amount_in)(symbol)(broadcast)(confirm) ) }
1729 
1730 
1731 
1732 /*
1733  * Transfers a public balance from @from to one or more blinded balances using a
1734  * stealth transfer.
1735  */
1736 blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name,
1737  string asset_symbol,
1738  /* map from key or label to amount */
1739  vector<pair<string, string>> to_amounts,
1740  bool broadcast )
1741 { try {
1742  FC_ASSERT( !is_locked() );
1743  idump((to_amounts));
1744 
1745  blind_confirmation confirm;
1746  account_object from_account = my->get_account(from_account_id_or_name);
1747 
1748  fc::optional<asset_object> asset_obj = get_asset(asset_symbol);
1749  FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol));
1750 
1752  bop.from = from_account.id;
1753 
1754  vector<fc::sha256> blinding_factors;
1755 
1756  asset total_amount = asset_obj->amount(0);
1757 
1758  for( auto item : to_amounts )
1759  {
1760  auto one_time_key = fc::ecc::private_key::generate();
1761  auto to_key = get_public_key( item.first );
1762  auto secret = one_time_key.get_shared_secret( to_key );
1763  auto child = fc::sha256::hash( secret );
1764  auto nonce = fc::sha256::hash( one_time_key.get_secret() );
1765  auto blind_factor = fc::sha256::hash( child );
1766 
1767  blinding_factors.push_back( blind_factor );
1768 
1769  auto amount = asset_obj->amount_from_string(item.second);
1770  total_amount += amount;
1771 
1772 
1773  fc::ecc::public_key to_pub_key = to_key;
1774  blind_output out;
1775  out.owner = authority( 1, public_key_type( to_pub_key.child( child ) ), 1 );
1776  out.commitment = fc::ecc::blind( blind_factor, amount.amount.value );
1777  if( to_amounts.size() > 1 )
1778  out.range_proof = fc::ecc::range_proof_sign( 0, out.commitment, blind_factor, nonce,
1779  0, RANGE_PROOF_MANTISSA, amount.amount.value );
1780 
1781  blind_confirmation::output conf_output;
1782  conf_output.label = item.first;
1783  conf_output.pub_key = to_key;
1784  conf_output.decrypted_memo.amount = amount;
1785  conf_output.decrypted_memo.blinding_factor = blind_factor;
1786  conf_output.decrypted_memo.commitment = out.commitment;
1787  conf_output.decrypted_memo.check = secret._hash[0].value();
1788  conf_output.confirmation.one_time_key = one_time_key.get_public_key();
1789  conf_output.confirmation.to = to_key;
1790  conf_output.confirmation.encrypted_memo =
1791  fc::aes_encrypt( secret, fc::raw::pack( conf_output.decrypted_memo ) );
1792  conf_output.confirmation_receipt = conf_output.confirmation;
1793 
1794  confirm.outputs.push_back( conf_output );
1795 
1796  bop.outputs.push_back(out);
1797  }
1798  bop.amount = total_amount;
1799  bop.blinding_factor = fc::ecc::blind_sum( blinding_factors, blinding_factors.size() );
1800 
1802  std::sort( bop.outputs.begin(), bop.outputs.end(),
1803  [&]( const blind_output& a, const blind_output& b ){ return a.commitment < b.commitment; } );
1804 
1805  confirm.trx.operations.push_back( bop );
1806  my->set_operation_fees( confirm.trx, my->_remote_db->get_global_properties().parameters.get_current_fees());
1807  confirm.trx.validate();
1808  confirm.trx = sign_transaction(confirm.trx, broadcast);
1809 
1810  if( broadcast )
1811  {
1812  for( const auto& out : confirm.outputs )
1813  {
1814  try {
1815  receive_blind_transfer( out.confirmation_receipt, "@"+from_account.name, "from @"+from_account.name );
1816  } catch ( ... ){}
1817  }
1818  }
1819 
1820  return confirm;
1821 } FC_CAPTURE_AND_RETHROW( (from_account_id_or_name)(asset_symbol)(to_amounts) ) }
1822 
1823 blind_receipt wallet_api::receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo )
1824 {
1825  FC_ASSERT( !is_locked() );
1826  stealth_confirmation conf(confirmation_receipt);
1827  FC_ASSERT( conf.to );
1828 
1829  blind_receipt result;
1830  result.conf = conf;
1831 
1832  auto to_priv_key_itr = my->_keys.find( *conf.to );
1833  FC_ASSERT( to_priv_key_itr != my->_keys.end(), "No private key for receiver", ("conf",conf) );
1834 
1835 
1836  auto to_priv_key = wif_to_key( to_priv_key_itr->second );
1837  FC_ASSERT( to_priv_key );
1838 
1839  auto secret = to_priv_key->get_shared_secret( conf.one_time_key );
1840  auto child = fc::sha256::hash( secret );
1841 
1842  auto child_priv_key = to_priv_key->child( child );
1843  //auto blind_factor = fc::sha256::hash( child );
1844 
1845  auto plain_memo = fc::aes_decrypt( secret, conf.encrypted_memo );
1846  auto memo = fc::raw::unpack<stealth_confirmation::memo_data>( plain_memo );
1847 
1848  result.to_key = *conf.to;
1849  result.to_label = get_key_label( result.to_key );
1850  if( memo.from )
1851  {
1852  result.from_key = *memo.from;
1853  result.from_label = get_key_label( result.from_key );
1854  if( result.from_label == string() )
1855  {
1856  result.from_label = opt_from;
1857  set_key_label( result.from_key, result.from_label );
1858  }
1859  }
1860  else
1861  {
1862  result.from_label = opt_from;
1863  }
1864  result.amount = memo.amount;
1865  result.memo = opt_memo;
1866 
1867  // confirm the amount matches the commitment (verify the blinding factor)
1868  auto commtiment_test = fc::ecc::blind( memo.blinding_factor, memo.amount.amount.value );
1869  FC_ASSERT( fc::ecc::verify_sum( {commtiment_test}, {memo.commitment}, 0 ) );
1870 
1871  blind_balance bal;
1872  bal.amount = memo.amount;
1873  bal.to = *conf.to;
1874  if( memo.from ) bal.from = *memo.from;
1875  bal.one_time_key = conf.one_time_key;
1876  bal.blinding_factor = memo.blinding_factor;
1877  bal.commitment = memo.commitment;
1878  bal.used = false;
1879 
1880  auto child_pubkey = child_priv_key.get_public_key();
1881  auto owner = authority(1, public_key_type(child_pubkey), 1);
1882  result.control_authority = owner;
1883  result.data = memo;
1884 
1885  auto child_key_itr = owner.key_auths.find( child_pubkey );
1886  if( child_key_itr != owner.key_auths.end() )
1887  my->_keys[child_key_itr->first] = key_to_wif( child_priv_key );
1888 
1889  // my->_wallet.blinded_balances[memo.amount.asset_id][bal.to].push_back( bal );
1890 
1891  result.date = fc::time_point::now();
1892  my->_wallet.blind_receipts.insert( result );
1893  my->_keys[child_pubkey] = key_to_wif( child_priv_key );
1894 
1895  save_wallet_file();
1896 
1897  return result;
1898 }
1899 
1900 vector<blind_receipt> wallet_api::blind_history( string key_or_account )
1901 {
1902  vector<blind_receipt> result;
1903  auto pub_key = get_public_key( key_or_account );
1904 
1905  if( pub_key == public_key_type() )
1906  return vector<blind_receipt>();
1907 
1908  for( auto& r : my->_wallet.blind_receipts )
1909  {
1910  if( r.from_key == pub_key || r.to_key == pub_key )
1911  result.push_back( r );
1912  }
1913  std::sort( result.begin(), result.end(),
1914  [&]( const blind_receipt& a, const blind_receipt& b ){ return a.date > b.date; } );
1915  return result;
1916 }
1917 
1918 order_book wallet_api::get_order_book( const string& base, const string& quote, unsigned limit )
1919 {
1920  return( my->_remote_db->get_order_book( base, quote, limit ) );
1921 }
1922 
1923 // custom operations
1924 signed_transaction wallet_api::account_store_map(string account, string catalog, bool remove,
1925  flat_map<string, optional<string>> key_values, bool broadcast)
1926 {
1927  return my->account_store_map(account, catalog, remove, key_values, broadcast);
1928 }
1929 
1930 vector<account_storage_object> wallet_api::get_account_storage(string account, string catalog)
1931 { try {
1932  return my->_custom_operations->get_storage_info(account, catalog);
1933 } FC_CAPTURE_AND_RETHROW( (account)(catalog) ) }
1934 
1936  : signed_block( block )
1937 {
1938  block_id = id();
1939  signing_key = signee();
1940  transaction_ids.reserve( transactions.size() );
1941  for( const processed_transaction& tx : transactions )
1942  transaction_ids.push_back( tx.id() );
1943 }
1944 
1946  const vesting_balance_object& vbo,
1947  fc::time_point_sec now )
1948  : vesting_balance_object( vbo )
1949 {
1951  allowed_withdraw_time = now;
1952 }
1953 
1954 } } // graphene::wallet
1955 
1956 namespace fc {
1957  void to_variant( const account_multi_index_type& accts, variant& vo, uint32_t max_depth )
1958  {
1959  to_variant( std::vector<account_object>(accts.begin(), accts.end()), vo, max_depth );
1960  }
1961 
1962  void from_variant( const variant& var, account_multi_index_type& vo, uint32_t max_depth )
1963  {
1964  const std::vector<account_object>& v = var.as<std::vector<account_object>>( max_depth );
1965  vo = account_multi_index_type(v.begin(), v.end());
1966  }
1967 }
account_id_type get_account_id(string account_name_or_id) const
Definition: wallet.cpp:594
bool exists(const path &p)
Definition: filesystem.cpp:209
struct graphene::chain::htlc_object::transfer_info transfer
future_extensions::flat_set_type extensions_type
Definition: base.hpp:155
blind_confirmation blind_transfer(string from_key_or_label, string to_key_or_label, string amount, string symbol_or_id, bool broadcast=false)
Definition: wallet.cpp:1550
uint64_t get_asset_count() const
Definition: wallet.cpp:197
signed_transaction account_store_map(string account, string catalog, bool remove, flat_map< string, optional< string >> key_values, bool broadcast)
Definition: wallet.cpp:1924
void dbg_stream_json_objects(const std::string &filename)
Definition: wallet.cpp:1062
signed_transaction update_asset(string symbol_or_id, optional< string > new_issuer, asset_options new_options, bool broadcast=false)
Definition: wallet.cpp:808
std::string get_approximate_relative_time_string(const time_point_sec &event_time, const time_point_sec &relative_to_time=fc::time_point::now(), const std::string &ago=" ago")
Definition: time.cpp:70
std::shared_ptr< detail::wallet_api_impl > my
Definition: wallet.hpp:1777
signed_transaction approve_proposal(const string &fee_paying_account, const string &proposal_id, const approval_delta &delta, bool broadcast)
Definition: wallet.cpp:1108
fc::ecc::commitment_type commitment
transaction_handle_type begin_builder_transaction()
Definition: wallet.cpp:504
string address_to_shorthash(const graphene::protocol::address &addr)
Definition: wallet_sign.cpp:36
asset get_allowed_withdraw(const time_point_sec &now) const
vector< limit_order_object > get_account_limit_orders(const string &name_or_id, const string &base, const string &quote, uint32_t limit=101, optional< limit_order_id_type > ostart_id=optional< limit_order_id_type >(), optional< price > ostart_price=optional< price >())
Fetch all orders relevant to the specified account sorted descendingly by price.
Definition: wallet.cpp:439
multi_index_container< account_object, indexed_by< ordered_unique< tag< by_id >, member< object, object_id_type, &object::id > >, ordered_unique< tag< by_name >, member< account_object, string, &account_object::name > > > > account_multi_index_type
unsigned aes_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext)
Definition: aes.cpp:181
signed_transaction htlc_create(string source, string destination, string amount, string asset_symbol_or_id, string hash_algorithm, const std::string &preimage_hash, uint32_t preimage_size, const uint32_t claim_period_seconds, const std::string &memo, bool broadcast=false)
Definition: wallet.cpp:202
struct graphene::chain::htlc_object::condition_info::time_lock_info time_lock
std::string str() const
Definition: sha1.cpp:18
vector< account_object > list_my_accounts()
Definition: wallet.cpp:177
const uint32_t word_list_size
Definition: words.cpp:49776
dynamic_global_property_object get_dynamic_global_properties() const
Definition: wallet.cpp:1123
operation get_prototype_operation(string operation_type)
Definition: wallet.cpp:1035
signed_transaction create_asset(string issuer, string symbol, uint8_t precision, asset_options common, fc::optional< bitasset_options > bitasset_opts, bool broadcast=false)
Definition: wallet.cpp:797
signed_transaction global_settle_asset(string symbol_or_id, price settle_price, bool broadcast=false)
Definition: wallet.cpp:868
Identifies a weighted set of keys and accounts that must approve operations.
Definition: authority.hpp:34
stealth_confirmation::memo_data decrypted_memo
vector< limit_order_object > get_limit_orders(string a, string b, uint32_t limit) const
Get limit orders in a given market.
Definition: wallet.cpp:450
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
Definition: flat.hpp:11
void flood_network(string prefix, uint32_t number_of_transactions)
Definition: wallet.cpp:1082
std::string uint128_amount_to_string(const fc::uint128_t &amount, const uint8_t precision)
Definition: util.cpp:42
static constexpr size_t data_size()
Definition: sha256.hpp:21
signed_transaction claim_asset_fee_pool(string symbol_or_id, string amount, bool broadcast=false)
Definition: wallet.cpp:853
flat_set< public_key_type > get_transaction_signers(const signed_transaction &tx) const
Definition: wallet.cpp:1025
database object to store HTLCs
Definition: htlc_object.hpp:40
signed_transaction sign_transaction2(signed_transaction tx, const vector< public_key_type > &signing_keys=vector< public_key_type >(), bool broadcast=true)
Definition: wallet.cpp:1019
vector< collateral_bid_object > get_collateral_bids(string asset_symbol_or_id, uint32_t limit=100, uint32_t start=0) const
Definition: wallet.cpp:465
bool verify_encapsulated_message(string message)
Definition: wallet.cpp:1374
contains properties that only apply to bitassets (market issued assets)
transaction preview_builder_transaction(transaction_handle_type handle)
Definition: wallet.cpp:529
optional< signed_block_with_info > get_block(uint32_t num)
Definition: wallet.cpp:167
string trim_and_normalize_spaces(const string &s)
Definition: string.cpp:104
void set_password(string password)
Definition: wallet.cpp:1273
public_key_type to
the account this balance is logically associated with
vector< operation > operations
Definition: transaction.hpp:89
struct graphene::chain::htlc_object::condition_info conditions
bool verify_sum(const std::vector< commitment_type > &commits, const std::vector< commitment_type > &neg_commits, int64_t excess)
signed_transaction vote_for_witness(string voting_account, string witness, bool approve, bool broadcast=false)
Definition: wallet.cpp:985
void dbg_generate_blocks(std::string debug_wif_key, uint32_t count)
Definition: wallet.cpp:1057
public_key get_public_key() const
string str() const
Definition: hash160.cpp:46
blind_confirmation blind_transfer_help(string from_key_or_label, string to_key_or_label, string amount, string symbol, bool broadcast=false, bool to_temp=false)
Definition: wallet.cpp:1558
vector< asset > get_blind_balances(string key_or_label)
Definition: wallet.cpp:1456
vector< transaction_id_type > transaction_ids
This class represents an account on the object graphAccounts are the primary unit of authority on the...
Maintains global state information (committee_member list, current fees)This is an implementation det...
An order-perserving dictionary of variant&#39;s.
signed_transaction borrow_asset(string borrower, string amount_to_borrow, string asset_symbol_or_id, string amount_of_collateral, bool broadcast=false)
Definition: wallet.cpp:1313
Definition: api.cpp:56
#define elog(FORMAT,...)
Definition: logger.hpp:129
fc::optional< fc::ecc::private_key > wif_to_key(const std::string &wif_key)
full_account get_full_account(const string &name_or_id)
Fetch all objects relevant to the specified account.
Definition: wallet.cpp:424
signed_transaction bid_collateral(string bidder, string debt_amount, string debt_symbol_or_id, string additional_collateral, bool broadcast=false)
Definition: wallet.cpp:883
signed_transaction htlc_extend(string htlc_id, string issuer, const uint32_t seconds_to_add, bool broadcast=false)
Definition: wallet.cpp:273
asset set_fees_on_builder_transaction(transaction_handle_type handle, string fee_asset=GRAPHENE_SYMBOL)
Definition: wallet.cpp:524
public_key_type get_public_key(string label) const
Definition: wallet.cpp:1393
The asset_options struct contains options available on all assets in the network. ...
Definition: asset_ops.hpp:47
signed_transaction update_bitasset(string symbol_or_id, bitasset_options new_options, bool broadcast=false)
Definition: wallet.cpp:823
vector< account_storage_object > get_account_storage(string account, string catalog)
Definition: wallet.cpp:1930
signed_transaction sell_asset(string seller_account, string amount_to_sell, string symbol_or_id_to_sell, string min_to_receive, string symbol_or_id_to_receive, uint32_t timeout_sec=0, bool fill_or_kill=false, bool broadcast=false)
Definition: wallet.cpp:1300
void dbg_make_mia(string creator, string symbol)
Definition: wallet.cpp:1046
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
signed_transaction propose_builder_transaction(transaction_handle_type handle, time_point_sec expiration=time_point::now()+fc::minutes(1), uint32_t review_period_seconds=0, bool broadcast=true)
Definition: wallet.cpp:551
signed_transaction cancel_order(object_id_type order_id, bool broadcast=false)
Definition: wallet.cpp:1330
signed_transaction borrow_asset_ext(string borrower, string amount_to_borrow, string asset_symbol_or_id, string amount_of_collateral, call_order_update_operation::extensions_type extensions, bool broadcast=false)
Definition: wallet.cpp:1320
void network_add_nodes(const vector< string > &nodes)
Definition: wallet.cpp:1072
vector< operation_detail > get_relative_account_history(const string &account_name_or_id, uint32_t stop, uint32_t limit, uint32_t start) const
Definition: wallet.cpp:337
signed_transaction set_desired_witness_and_committee_member_count(string account_to_modify, uint16_t desired_number_of_witnesses, uint16_t desired_number_of_committee_members, bool broadcast=false)
Definition: wallet.cpp:1000
signed_transaction create_witness(string owner_account, string url, bool broadcast=false)
Definition: wallet.cpp:925
static sha512 hash(const char *d, uint32_t dlen)
Definition: sha512.cpp:34
fc::static_variant< transfer_operation, limit_order_create_operation, limit_order_cancel_operation, call_order_update_operation, fill_order_operation, account_create_operation, account_update_operation, account_whitelist_operation, account_upgrade_operation, account_transfer_operation, asset_create_operation, asset_update_operation, asset_update_bitasset_operation, asset_update_feed_producers_operation, asset_issue_operation, asset_reserve_operation, asset_fund_fee_pool_operation, asset_settle_operation, asset_global_settle_operation, asset_publish_feed_operation, witness_create_operation, witness_update_operation, proposal_create_operation, proposal_update_operation, proposal_delete_operation, withdraw_permission_create_operation, withdraw_permission_update_operation, withdraw_permission_claim_operation, withdraw_permission_delete_operation, committee_member_create_operation, committee_member_update_operation, committee_member_update_global_parameters_operation, vesting_balance_create_operation, vesting_balance_withdraw_operation, worker_create_operation, custom_operation, assert_operation, balance_claim_operation, override_transfer_operation, transfer_to_blind_operation, blind_transfer_operation, transfer_from_blind_operation, asset_settle_cancel_operation, asset_claim_fees_operation, fba_distribute_operation, bid_collateral_operation, execute_bid_operation, asset_claim_pool_operation, asset_update_issuer_operation, htlc_create_operation, htlc_redeem_operation, htlc_redeemed_operation, htlc_extend_operation, htlc_refund_operation, custom_authority_create_operation, custom_authority_update_operation, custom_authority_delete_operation, ticket_create_operation, ticket_update_operation, liquidity_pool_create_operation, liquidity_pool_delete_operation, liquidity_pool_deposit_operation, liquidity_pool_withdraw_operation, liquidity_pool_exchange_operation, samet_fund_create_operation, samet_fund_delete_operation, samet_fund_update_operation, samet_fund_borrow_operation, samet_fund_repay_operation, credit_offer_create_operation, credit_offer_delete_operation, credit_offer_update_operation, credit_offer_accept_operation, credit_deal_repay_operation, credit_deal_expired_operation > operation
Definition: operations.hpp:131
vector< extended_asset_object > list_assets(const string &lowerbound, uint32_t limit) const
Definition: wallet.cpp:192
groups operations that should be applied atomically
Definition: transaction.hpp:69
memo_data sign_memo(string from, string to, string memo)
Definition: wallet.cpp:1336
vector< signed_transaction > import_balance(string account_name_or_id, const vector< string > &wif_keys, bool broadcast)
Definition: wallet.cpp:1281
bool import_account_keys(string filename, string password, string src_account_name, string dest_account_name)
Definition: wallet.cpp:695
string gethelp(const string &method) const
Definition: wallet.cpp:1152
signed_transaction publish_asset_feed(string publishing_account, string symbol_or_id, price_feed feed, bool broadcast=false)
Definition: wallet.cpp:837
signed_transaction settle_asset(string account_to_settle, string amount_to_settle, string symbol_or_id, bool broadcast=false)
Definition: wallet.cpp:875
signed_transaction sign_builder_transaction(transaction_handle_type transaction_handle, bool broadcast=true)
Definition: wallet.cpp:534
char * data() const
Definition: sha256.cpp:29
visitor::result_type visit(visitor &v)
map< string, committee_member_id_type > list_committee_members(const string &lowerbound, uint32_t limit)
Definition: wallet.cpp:910
blind_confirmation transfer_from_blind(string from_blind_account_key_or_label, string to_account_name_or_id, string amount, string asset_symbol_or_id, bool broadcast=false)
Definition: wallet.cpp:1489
const auto source
asset_id_type get_asset_id(const string &asset_symbol_or_id) const
Definition: wallet.cpp:599
signed_transaction fund_asset_fee_pool(string from, string symbol_or_id, string amount, bool broadcast=false)
Definition: wallet.cpp:845
bool copy_wallet_file(string destination_filename)
Definition: wallet.cpp:162
account_id_type get_id() const
signed_transaction sign_builder_transaction2(transaction_handle_type transaction_handle, const vector< public_key_type > &signing_keys=vector< public_key_type >(), bool broadcast=true)
Definition: wallet.cpp:539
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
bool verify_signed_message(signed_message message)
Definition: wallet.cpp:1364
wallet_api(const wallet_data &initial_data, fc::api< login_api > rapi)
Definition: wallet.cpp:153
const const_char_ptr word_list[]
Definition: words.cpp:29
account_history_operation_detail get_account_history_by_operations(const string &account_name_or_id, const flat_set< uint16_t > &operation_types, uint32_t start, uint32_t limit)
Definition: wallet.cpp:377
void add_operation_to_builder_transaction(transaction_handle_type transaction_handle, const operation &op)
Definition: wallet.cpp:509
std::string key_to_wif(const fc::sha256 &private_secret)
#define BRAIN_KEY_WORD_COUNT
Definition: wallet.cpp:81
public_key child(const fc::sha256 &offset) const
fc::sha256 digest() const
Definition: wallet.cpp:88
signed_transaction issue_asset(string to_account, string amount, string symbol_or_id, string memo, bool broadcast=false)
Definition: wallet.cpp:786
string get_wallet_filename() const
Definition: wallet.cpp:499
bool import_key(string account_name_or_id, string wif_key)
Definition: wallet.cpp:604
asset amount(share_type a) const
Helper function to get an asset object with the given amount in this asset&#39;s type.
commitment_type blind(const blind_factor_type &blind, uint64_t value)
void unlock(string password)
Definition: wallet.cpp:1261
string get_key_label(public_key_type key) const
Definition: wallet.cpp:1380
signed_transaction whitelist_account(string authorizing_account, string account_to_list, account_whitelist_operation::account_listing new_listing_status, bool broadcast=false)
Definition: wallet.cpp:891
fc::ecc::commitment_type commitment
vector< bucket_object > get_market_history(string symbol, string symbol2, uint32_t bucket, fc::time_point_sec start, fc::time_point_sec end) const
Get OHLCV data of a trading pair in a time range.
Definition: wallet.cpp:429
bool verify_message(string message, string account, int block, const string &time, compact_signature sig)
Definition: wallet.cpp:1354
fc::optional< fc::variant > get_htlc(string htlc_id) const
Definition: wallet.cpp:210
signed_transaction propose_builder_transaction2(transaction_handle_type handle, string account_name_or_id, time_point_sec expiration=time_point::now()+fc::minutes(1), uint32_t review_period_seconds=0, bool broadcast=true)
Definition: wallet.cpp:560
void save_wallet_file(string wallet_filename="")
Definition: wallet.cpp:1225
#define FC_THROW( ...)
Definition: exception.hpp:366
variant get_object(object_id_type id) const
Definition: wallet.cpp:494
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number)
Definition: wallet_sign.cpp:54
fc::optional< memo_data > memo
Definition: htlc_object.hpp:62
bool load_wallet_file(string wallet_filename="")
Definition: wallet.cpp:1215
#define wdump(SEQ)
Definition: logger.hpp:174
object_id_type id
Definition: object.hpp:69
static private_key generate()
vector< public_key_type > get_keys() const
Definition: authority.hpp:85
blind_receipt receive_blind_transfer(string confirmation_receipt, string opt_from, string opt_memo)
Definition: wallet.cpp:1823
Defines data required to create a new blind commitmentThe blinded output that must be proven to be gr...
signed_transaction register_account(string name, public_key_type owner, public_key_type active, string registrar_account, string referrer_account, uint32_t referrer_percent, bool broadcast=false)
Definition: wallet.cpp:766
std::string str()
Definition: sstream.cpp:33
fc::ecc::commitment_type commitment
contains only the public point of an elliptic curve key.
Definition: elliptic.hpp:35
Converts blinded/stealth balance to a public account balance.
bool valid() const
Definition: optional.hpp:186
bool set_key_label(public_key_type key, string label)
Definition: wallet.cpp:1403
order_book get_order_book(const string &base, const string &quote, unsigned limit=50)
Definition: wallet.cpp:1918
#define ilog(FORMAT,...)
Definition: logger.hpp:117
vector< asset > list_account_balances(const string &account_name_or_id)
Definition: wallet.cpp:187
string serialize_transaction(signed_transaction tx) const
Definition: wallet.cpp:489
stealth_confirmation::memo_data data
#define idump(SEQ)
Definition: logger.hpp:166
map< string, public_key_type > get_my_blind_accounts() const
Definition: wallet.cpp:1424
bool is_public_key_registered(string public_key) const
Definition: wallet.cpp:482
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
string name
The account&#39;s name. This name must be unique among all account names on the graph. May not be empty.
asset_bitasset_data_object get_bitasset_data(string asset_symbol_or_id) const
Definition: wallet.cpp:587
T as(uint32_t max_depth) const
Definition: variant.hpp:337
void set_wallet_filename(string wallet_filename)
Definition: wallet.cpp:1009
signed_transaction update_asset_issuer(string symbol_or_id, string new_issuer, bool broadcast=false)
Definition: wallet.cpp:816
void replace_operation_in_builder_transaction(transaction_handle_type handle, unsigned operation_index, const operation &new_op)
Definition: wallet.cpp:516
signed_block_with_info(const signed_block &block)
Definition: wallet.cpp:1935
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
int64_t to_int64() const
Definition: bigint.cpp:54
std::map< string, std::function< string(fc::variant, const fc::variants &)> > get_result_formatters() const
Definition: wallet.cpp:1231
vector< force_settlement_object > get_settle_orders(string a, uint32_t limit) const
Get forced settlement orders in a given asset.
Definition: wallet.cpp:460
static string to_pretty_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:748
string amount_to_string(share_type amount) const
Convert an asset to a textual representation, i.e. "123.45".
signed_transaction withdraw_vesting(string witness_name, string amount, string asset_symbol_or_id, bool broadcast=false)
Definition: wallet.cpp:968
static private_key regenerate(const fc::sha256 &secret)
string normalize_brain_key(string s)
Definition: wallet_sign.cpp:62
void remove_builder_transaction(transaction_handle_type handle)
Definition: wallet.cpp:570
signed_transaction create_account_with_brain_key(string brain_key, string account_name, string registrar_account, string referrer_account, bool broadcast=false)
Definition: wallet.cpp:777
string str() const
Definition: ripemd160.cpp:21
public_key_type from
the account this balance came from
vector< call_order_object > get_call_orders(string asset_symbol_or_id, uint32_t limit) const
Get call orders (aka margin positions) for a given asset.
Definition: wallet.cpp:455
brain_key_info suggest_brain_key() const
Definition: wallet.cpp:470
signed_transaction update_worker_votes(string account, worker_vote_delta delta, bool broadcast=false)
Definition: wallet.cpp:946
account_object get_account(string account_name_or_id) const
Definition: wallet.cpp:575
void dbg_update_object(fc::variant_object update)
Definition: wallet.cpp:1067
void dbg_make_uia(string creator, string symbol)
Definition: wallet.cpp:1040
witness_object get_witness(string owner_account)
Definition: wallet.cpp:915
object_restriction_predicate< operation > result_type
Definition: list_1.cpp:29
public_key_type one_time_key
used to derive the authority key and blinding factor
private_key_secret get_secret() const
std::string to_detail_string(log_level ll=log_level::all) const
Definition: exception.cpp:183
vector< flat_set< account_id_type > > get_key_references(const vector< public_key_type > &keys) const
Definition: wallet.cpp:1030
vesting_balance_object_with_info(const vesting_balance_object &vbo, fc::time_point_sec now)
Definition: wallet.cpp:1945
signed_transaction update_witness(string witness_name, string url, string block_signing_key, bool broadcast=false)
Definition: wallet.cpp:954
range_proof_type range_proof_sign(uint64_t min_value, const commitment_type &commit, const blind_factor_type &commit_blind, const blind_factor_type &nonce, int8_t base10_exp, uint8_t min_bits, uint64_t actual_value)
blind_factor_type blind_sum(const std::vector< blind_factor_type > &blinds, uint32_t non_neg)
void from_variant(const variant &var, flat_set< T, A... > &vo, uint32_t _max_depth)
Definition: flat.hpp:116
signed_transaction create_worker(string owner_account, time_point_sec work_begin_date, time_point_sec work_end_date, share_type daily_pay, string name, string url, variant worker_settings, bool broadcast=false)
Definition: wallet.cpp:932
safe< int64_t > share_type
Definition: types.hpp:274
signed_transaction reserve_asset(string from, string amount, string symbol_or_id, bool broadcast=false)
Definition: wallet.cpp:860
string get_private_key(public_key_type pubkey) const
Definition: wallet.cpp:1388
uint16_t transaction_handle_type
map< string, account_id_type > list_accounts(const string &lowerbound, uint32_t limit)
Definition: wallet.cpp:182
signed_transaction set_voting_proxy(string account_to_modify, optional< string > voting_account, bool broadcast=false)
Definition: wallet.cpp:993
signed_transaction propose_fee_change(const string &proposing_account, fc::time_point_sec expiration_time, const variant_object &changed_values, bool broadcast=false)
Definition: wallet.cpp:1098
Definition: api.hpp:15
unsigned aes_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext)
Definition: aes.cpp:230
virtual void validate() const
Definition: transaction.cpp:58
string str() const
Definition: sha256.cpp:24
map< public_key_type, string > dump_private_keys()
Definition: wallet.cpp:1289
signed_message sign_message(string signer, string message)
Definition: wallet.cpp:1348
account_statistics_id_type statistics
vector< brain_key_info > derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys=1) const
Definition: wallet.cpp:475
Maintains global state information (committee_member list, current fees)This is an implementation det...
vector< vesting_balance_object_with_info > get_vesting_balances(string account_name)
Definition: wallet.cpp:963
map< string, witness_id_type > list_witnesses(const string &lowerbound, uint32_t limit)
Definition: wallet.cpp:905
uint64_t get_account_count() const
Definition: wallet.cpp:172
static brain_key_info suggest_brain_key()
Definition: wallet.cpp:120
public_key_type create_blind_account(string label, string brain_key)
Definition: wallet.cpp:1436
pair< transaction_id_type, signed_transaction > broadcast_transaction(signed_transaction tx)
Definition: wallet.cpp:546
static vector< brain_key_info > derive_owner_keys_from_brain_key(string brain_key, int number_of_desired_keys=1)
Definition: wallet.cpp:99
vector< blind_receipt > blind_history(string key_or_account)
Definition: wallet.cpp:1900
struct graphene::chain::htlc_object::condition_info::hash_lock_info hash_lock
signed_transaction propose_parameter_change(const string &proposing_account, fc::time_point_sec expiration_time, const variant_object &changed_values, bool broadcast=false)
Definition: wallet.cpp:1088
static time_point now()
Definition: time.cpp:13
variant_object about() const
Definition: wallet.cpp:756
signed_transaction transfer(string from, string to, string amount, string asset_symbol_or_id, string memo, bool broadcast=false)
Definition: wallet.cpp:792
signed_transaction create_committee_member(string owner_account, string url, bool broadcast=false)
Definition: wallet.cpp:899
signed_transaction add_transaction_signature(signed_transaction tx, bool broadcast=false)
Definition: wallet.cpp:1128
signed_transaction htlc_redeem(string htlc_id, string issuer, const std::string &preimage, bool broadcast=false)
Definition: wallet.cpp:266
string read_memo(const memo_data &memo)
Definition: wallet.cpp:1342
extended_asset_object get_asset(string asset_symbol_or_id) const
Definition: wallet.cpp:580
an elliptic curve private key.
Definition: elliptic.hpp:89
zero_initialized_array< unsigned char, 65 > compact_signature
Definition: elliptic.hpp:27
map< string, public_key_type > get_blind_accounts() const
Definition: wallet.cpp:1417
signed_transaction vote_for_committee_member(string voting_account, string committee_member, bool approve, bool broadcast=false)
Definition: wallet.cpp:977
std::string to_hex(const char *d, uint32_t s)
Definition: hex.cpp:17
tracks information about a committee_member account.A committee_member is responsible for setting blo...
#define RANGE_PROOF_MANTISSA
Definition: wallet.cpp:82
Transfers from blind to blind.
captures the result of evaluating the operations contained in the transaction
map< string, bool > import_accounts(string filename, string password)
Definition: wallet.cpp:623
void dbg_push_blocks(std::string src_filename, uint32_t count)
Definition: wallet.cpp:1052
An order-perserving dictionary of variant&#39;s.
vector< operation_detail > get_account_history(const string &account_name_or_id, uint32_t limit) const
Definition: wallet.cpp:279
The bitasset_options struct contains configurable options available only to BitAssets.
Definition: asset_ops.hpp:109
signed_transaction upgrade_account(string account_name_or_id, bool broadcast)
Definition: wallet.cpp:1295
Converts public account balance to a blinded or stealth balance.
vector< variant > network_get_connected_peers()
Definition: wallet.cpp:1077
fc::ecc::private_key derive_private_key(const std::string &prefix_string, int sequence_number) const
Definition: wallet.cpp:761
signed_transaction sign_transaction(signed_transaction tx, bool broadcast=false)
Definition: wallet.cpp:1014
T value
Definition: safe.hpp:22
asset amount_from_string(string amount_string) const
signed_transaction update_asset_feed_producers(string symbol_or_id, flat_set< string > new_feed_producers, bool broadcast=false)
Definition: wallet.cpp:830
blind_confirmation transfer_to_blind(string from_account_name_or_id, string asset_symbol_or_id, vector< pair< string, string >> to_amounts, bool broadcast=false)
Definition: wallet.cpp:1736
Definition: api.hpp:120
string normalize_brain_key(string s) const
Definition: wallet.cpp:746
committee_member_object get_committee_member(string owner_account)
Definition: wallet.cpp:920
global_property_object get_global_properties() const
Definition: wallet.cpp:1118