Electroneum
Loading...
Searching...
No Matches
cryptonote::simple_wallet Class Reference

Manages wallet operations. This is the most abstracted wallet class. More...

#include <simplewallet.h>

Inheritance diagram for cryptonote::simple_wallet:
Collaboration diagram for cryptonote::simple_wallet:

Public Types

typedef std::vector< std::string > command_type

Public Member Functions

 simple_wallet ()
bool init (const boost::program_options::variables_map &vm)
bool deinit ()
bool run ()
void stop ()
void interrupt ()
bool process_command (const std::vector< std::string > &args)
std::string get_commands_str ()
std::string get_command_usage (const std::vector< std::string > &args)
Public Member Functions inherited from tools::i_wallet2_callback
virtual void on_lw_new_block (uint64_t height)
virtual void on_lw_etn_received (uint64_t height, const crypto::hash &txid, uint64_t amount)
virtual void on_lw_unconfirmed_etn_received (uint64_t height, const crypto::hash &txid, uint64_t amount)
virtual void on_lw_etn_spent (uint64_t height, const crypto::hash &txid, uint64_t amount)
virtual void on_device_button_pressed ()
virtual void on_device_progress (const hw::device_progress &event)
virtual void on_pool_tx_removed (const crypto::hash &txid)
virtual ~i_wallet2_callback ()

Static Public Member Functions

static const char * tr (const char *str)

Friends

class refresh_progress_reporter_t

Detailed Description

Manages wallet operations. This is the most abstracted wallet class.

Definition at line 67 of file simplewallet.h.

Member Typedef Documentation

◆ command_type

typedef std::vector<std::string> cryptonote::simple_wallet::command_type

Definition at line 73 of file simplewallet.h.

Constructor & Destructor Documentation

◆ simple_wallet()

simple_wallet::simple_wallet ( )

Definition at line 2744 of file simplewallet.cpp.

2745 : m_allow_mismatched_daemon_version(false)
2746 , m_refresh_progress_reporter(*this)
2747 , m_idle_run(true)
2748 , m_auto_refresh_enabled(false)
2749 , m_auto_refresh_refreshing(false)
2750 , m_in_manual_refresh(false)
2751 , m_current_subaddress_account(0)
2752{
2753 /*
2754 m_cmd_binder.set_handler("start_mining",
2755 boost::bind(&simple_wallet::start_mining, this, _1),
2756 tr(USAGE_START_MINING),
2757 tr("Start mining in the daemon (bg_mining and ignore_battery are optional booleans)."));
2758 m_cmd_binder.set_handler("stop_mining",
2759 boost::bind(&simple_wallet::stop_mining, this, _1),
2760 tr("Stop mining in the daemon."));
2761 */
2762 m_cmd_binder.set_handler("set_daemon",
2763 boost::bind(&simple_wallet::set_daemon, this, _1),
2764 tr(USAGE_SET_DAEMON),
2765 tr("Set another daemon to connect to."));
2766 m_cmd_binder.set_handler("save_bc",
2767 boost::bind(&simple_wallet::save_bc, this, _1),
2768 tr("Save the current blockchain data."));
2769 m_cmd_binder.set_handler("refresh",
2770 boost::bind(&simple_wallet::refresh, this, _1),
2771 tr("Synchronize the transactions and balance."));
2772 m_cmd_binder.set_handler("balance",
2773 boost::bind(&simple_wallet::show_balance, this, _1),
2774 tr(USAGE_SHOW_BALANCE),
2775 tr("Show the wallet's balance of the currently selected account."));
2776 m_cmd_binder.set_handler("incoming_transfers",
2777 boost::bind(&simple_wallet::show_incoming_transfers, this, _1),
2778 tr(USAGE_INCOMING_TRANSFERS),
2779 tr("Show the incoming transfers, all or filtered by availability and address index.\n\n"
2780 "Output format:\n"
2781 "Amount, Spent(\"T\"|\"F\"), \"frozen\"|\"locked\"|\"unlocked\", RingCT, Global Index, Transaction Hash, Address Index, [Public Key, Key Image] "));
2782 m_cmd_binder.set_handler("payments",
2783 boost::bind(&simple_wallet::show_payments, this, _1),
2784 tr(USAGE_PAYMENTS),
2785 tr("Show the payments for the given payment IDs."));
2786 m_cmd_binder.set_handler("bc_height",
2787 boost::bind(&simple_wallet::show_blockchain_height, this, _1),
2788 tr("Show the blockchain height."));
2789 m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this, _1),
2790 tr(USAGE_TRANSFER),
2791 tr("Transfer <amount> to <address>. If the parameter \"index=<N1>[,<N2>,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs in the ring signature. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)"));
2792 m_cmd_binder.set_handler("locked_transfer",
2793 boost::bind(&simple_wallet::locked_transfer, this, _1),
2794 tr(USAGE_LOCKED_TRANSFER),
2795 tr("Transfer <amount> to <address> and lock it for <lockblocks> (max. 1000000). If the parameter \"index=<N1>[,<N2>,...]\" is specified, the wallet uses outputs received by addresses of those indices. If omitted, the wallet randomly chooses address indices to be used. In any case, it tries its best not to combine outputs across multiple addresses. <priority> is the priority of the transaction. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used. <ring_size> is the number of inputs in the ring signature. Multiple payments can be made at once by adding URI_2 or <address_2> <amount_2> etcetera (before the payment ID, if it's included)"));
2796 m_cmd_binder.set_handler("locked_sweep_all",
2797 boost::bind(&simple_wallet::locked_sweep_all, this, _1),
2798 tr(USAGE_LOCKED_SWEEP_ALL),
2799 tr("Send all unlocked balance to an address and lock it for <lockblocks> (max. 1000000). If the parameter \"index=<N1>[,<N2>,...]\" or \"index=all\" is specified, the wallet sweeps outputs received by those or all address indices, respectively. If omitted, the wallet randomly chooses an address index to be used. <priority> is the priority of the sweep. The higher the priority, the higher the transaction fee. Valid values in priority order (from lowest to highest) are: unimportant, normal, elevated, priority. If omitted, the default value (see the command \"set priority\") is used."));
2800 m_cmd_binder.set_handler("sweep_unmixable",
2801 boost::bind(&simple_wallet::sweep_unmixable, this, _1),
2802 tr("Send all unmixable outputs to yourself with ring_size 1"));
2803 m_cmd_binder.set_handler("sweep_all", boost::bind(&simple_wallet::sweep_all, this, _1),
2804 tr(USAGE_SWEEP_ALL),
2805 tr("Send all unlocked balance to an address. If the parameter \"index=<N1>[,<N2>,...]\" or \"index=all\" is specified, the wallet sweeps outputs received by those or all address indices, respectively. If omitted, the wallet randomly chooses an address index to be used. If the parameter \"outputs=<N>\" is specified and N > 0, wallet splits the transaction into N even outputs."));
2806 m_cmd_binder.set_handler("sweep_below",
2807 boost::bind(&simple_wallet::sweep_below, this, _1),
2808 tr(USAGE_SWEEP_BELOW),
2809 tr("Send all unlocked outputs below the threshold to an address."));
2810 m_cmd_binder.set_handler("sweep_single",
2811 boost::bind(&simple_wallet::sweep_single, this, _1),
2812 tr(USAGE_SWEEP_SINGLE),
2813 tr("Send a single output of the given key image to an address without change."));
2814 /*
2815 m_cmd_binder.set_handler("donate",
2816 boost::bind(&simple_wallet::donate, this, _1),
2817 tr(USAGE_DONATE),
2818 tr("Donate <amount> to the development team."));
2819 */
2820 m_cmd_binder.set_handler("sign_transfer",
2821 boost::bind(&simple_wallet::sign_transfer, this, _1),
2822 tr(USAGE_SIGN_TRANSFER),
2823 tr("Sign a transaction from a file. If the parameter \"export_raw\" is specified, transaction raw hex data suitable for the daemon RPC /sendrawtransaction is exported."));
2824 m_cmd_binder.set_handler("submit_transfer",
2825 boost::bind(&simple_wallet::submit_transfer, this, _1),
2826 tr("Submit a signed transaction from a file."));
2827 m_cmd_binder.set_handler("set_log",
2828 boost::bind(&simple_wallet::set_log, this, _1),
2829 tr(USAGE_SET_LOG),
2830 tr("Change the current log detail (level must be <0-4>)."));
2831 m_cmd_binder.set_handler("account",
2832 boost::bind(&simple_wallet::account, this, _1),
2833 tr(USAGE_ACCOUNT),
2834 tr("If no arguments are specified, the wallet shows all the existing accounts along with their balances.\n"
2835 "If the \"new\" argument is specified, the wallet creates a new account with its label initialized by the provided label text (which can be empty).\n"
2836 "If the \"switch\" argument is specified, the wallet switches to the account specified by <index>.\n"
2837 "If the \"label\" argument is specified, the wallet sets the label of the account specified by <index> to the provided label text.\n"
2838 "If the \"tag\" argument is specified, a tag <tag_name> is assigned to the specified accounts <account_index_1>, <account_index_2>, ....\n"
2839 "If the \"untag\" argument is specified, the tags assigned to the specified accounts <account_index_1>, <account_index_2> ..., are removed.\n"
2840 "If the \"tag_description\" argument is specified, the tag <tag_name> is assigned an arbitrary text <description>."));
2841 m_cmd_binder.set_handler("address",
2842 boost::bind(&simple_wallet::print_address, this, _1),
2843 tr(USAGE_ADDRESS),
2844 tr("If no arguments are specified or <index> is specified, the wallet shows the default or specified address. If \"all\" is specified, the wallet shows all the existing addresses in the currently selected account. If \"new \" is specified, the wallet creates a new address with the provided label text (which can be empty). If \"label\" is specified, the wallet sets the label of the address specified by <index> to the provided label text."));
2845 m_cmd_binder.set_handler("integrated_address",
2846 boost::bind(&simple_wallet::print_integrated_address, this, _1),
2847 tr(USAGE_INTEGRATED_ADDRESS),
2848 tr("Encode a payment ID into an integrated address for the current wallet public address (no argument uses a random payment ID), or decode an integrated address to standard address and payment ID"));
2849 m_cmd_binder.set_handler("address_book",
2850 boost::bind(&simple_wallet::address_book, this, _1),
2851 tr(USAGE_ADDRESS_BOOK),
2852 tr("Print all entries in the address book, optionally adding/deleting an entry to/from it."));
2853 m_cmd_binder.set_handler("save",
2854 boost::bind(&simple_wallet::save, this, _1),
2855 tr("Save the wallet data."));
2856 m_cmd_binder.set_handler("save_watch_only",
2857 boost::bind(&simple_wallet::save_watch_only, this, _1),
2858 tr("Save a watch-only keys file."));
2859 m_cmd_binder.set_handler("viewkey",
2860 boost::bind(&simple_wallet::viewkey, this, _1),
2861 tr("Display the private view key."));
2862 m_cmd_binder.set_handler("spendkey",
2863 boost::bind(&simple_wallet::spendkey, this, _1),
2864 tr("Display the private spend key."));
2865 m_cmd_binder.set_handler("seed",
2866 boost::bind(&simple_wallet::seed, this, _1),
2867 tr("Display the Electrum-style mnemonic seed"));
2868 m_cmd_binder.set_handler("set",
2869 boost::bind(&simple_wallet::set_variable, this, _1),
2870 tr(USAGE_SET_VARIABLE),
2871 tr("Available options:\n "
2872 "seed language\n "
2873 " Set the wallet's seed language.\n "
2874 "always-confirm-transfers <1|0>\n "
2875 " Whether to confirm unsplit txes.\n "
2876 "print-ring-members <1|0>\n "
2877 " Whether to print detailed information about ring members during confirmation.\n "
2878 "store-tx-info <1|0>\n "
2879 " Whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference.\n "
2880 "default-ring-size <n>\n "
2881 " Set the default ring size (obsolete).\n "
2882 "auto-refresh <1|0>\n "
2883 " Whether to automatically synchronize new blocks from the daemon.\n "
2884 "refresh-type <full|optimize-coinbase|no-coinbase|default>\n "
2885 " Set the wallet's refresh behaviour.\n "
2886 "priority [0|1|2|3|4]\n "
2887 " Set the fee to default/unimportant/normal/elevated/priority.\n "
2888 "confirm-missing-payment-id <1|0> (obsolete)\n "
2889 "ask-password <0|1|2 (or never|action|decrypt)>\n "
2890 " action: ask the password before many actions such as transfer, etc\n "
2891 " decrypt: same as action, but keeps the spend key encrypted in memory when not needed\n "
2892 "unit <ETN|cent>\n "
2893 " Set the default Electroneum (sub-)unit.\n "
2894 "min-outputs-count [n]\n "
2895 " Try to keep at least that many outputs of value at least min-outputs-value.\n "
2896 "min-outputs-value [n]\n "
2897 " Try to keep at least min-outputs-count outputs of at least that value.\n "
2898 "merge-destinations <1|0>\n "
2899 " Whether to merge multiple payments to the same destination address.\n "
2900 "confirm-backlog <1|0>\n "
2901 " Whether to warn if there is transaction backlog.\n "
2902 "confirm-backlog-threshold [n]\n "
2903 " Set a threshold for confirm-backlog to only warn if the transaction backlog is greater than n blocks.\n "
2904 "refresh-from-block-height [n]\n "
2905 " Set the height before which to ignore blocks.\n "
2906 "auto-low-priority <1|0>\n "
2907 " Whether to automatically use the low priority fee level when it's safe to do so.\n "
2908 "segregate-pre-fork-outputs <1|0>\n "
2909 " Set this if you intend to spend outputs on both Electroneum AND a key reusing fork.\n "
2910 "key-reuse-mitigation2 <1|0>\n "
2911 " Set this if you are not sure whether you will spend on a key reusing Electroneum fork later.\n"
2912 "subaddress-lookahead <major>:<minor>\n "
2913 " Set the lookahead sizes for the subaddress hash table.\n "
2914 " Set this if you are not sure whether you will spend on a key reusing Electroneum fork later.\n "
2915 "segregation-height <n>\n "
2916 " Set to the height of a key reusing fork you want to use, 0 to use default."));
2917 m_cmd_binder.set_handler("encrypted_seed",
2918 boost::bind(&simple_wallet::encrypted_seed, this, _1),
2919 tr("Display the encrypted Electrum-style mnemonic seed."));
2920 m_cmd_binder.set_handler("rescan_spent",
2921 boost::bind(&simple_wallet::rescan_spent, this, _1),
2922 tr("Rescan the blockchain for spent outputs."));
2923 m_cmd_binder.set_handler("get_tx_key",
2924 boost::bind(&simple_wallet::get_tx_key, this, _1),
2925 tr(USAGE_GET_TX_KEY),
2926 tr("Get the transaction key (r) for a given <txid>."));
2927 m_cmd_binder.set_handler("set_tx_key",
2928 boost::bind(&simple_wallet::set_tx_key, this, _1),
2929 tr(USAGE_SET_TX_KEY),
2930 tr("Set the transaction key (r) for a given <txid> in case the tx was made by some other device or 3rd party wallet."));
2931 m_cmd_binder.set_handler("check_tx_key",
2932 boost::bind(&simple_wallet::check_tx_key, this, _1),
2933 tr(USAGE_CHECK_TX_KEY),
2934 tr("Check the amount going to <address> in <txid>."));
2935 m_cmd_binder.set_handler("get_tx_proof",
2936 boost::bind(&simple_wallet::get_tx_proof, this, _1),
2937 tr(USAGE_GET_TX_PROOF),
2938 tr("Generate a signature proving funds sent to <address> in <txid>, optionally with a challenge string <message>, using either the transaction secret key (when <address> is not your wallet's address) or the view secret key (otherwise), which does not disclose the secret key."));
2939 m_cmd_binder.set_handler("check_tx_proof",
2940 boost::bind(&simple_wallet::check_tx_proof, this, _1),
2941 tr(USAGE_CHECK_TX_PROOF),
2942 tr("Check the proof for funds going to <address> in <txid> with the challenge string <message> if any."));
2943 m_cmd_binder.set_handler("get_spend_proof",
2944 boost::bind(&simple_wallet::get_spend_proof, this, _1),
2945 tr(USAGE_GET_SPEND_PROOF),
2946 tr("Generate a signature proving that you generated <txid> using the spend secret key, optionally with a challenge string <message>."));
2947 m_cmd_binder.set_handler("check_spend_proof",
2948 boost::bind(&simple_wallet::check_spend_proof, this, _1),
2949 tr(USAGE_CHECK_SPEND_PROOF),
2950 tr("Check a signature proving that the signer generated <txid>, optionally with a challenge string <message>."));
2951 m_cmd_binder.set_handler("get_reserve_proof",
2952 boost::bind(&simple_wallet::get_reserve_proof, this, _1),
2953 tr(USAGE_GET_RESERVE_PROOF),
2954 tr("Generate a signature proving that you own at least this much, optionally with a challenge string <message>.\n"
2955 "If 'all' is specified, you prove the entire sum of all of your existing accounts' balances.\n"
2956 "Otherwise, you prove the reserve of the smallest possible amount above <amount> available in your current account."));
2957 m_cmd_binder.set_handler("check_reserve_proof",
2958 boost::bind(&simple_wallet::check_reserve_proof, this, _1),
2959 tr(USAGE_CHECK_RESERVE_PROOF),
2960 tr("Check a signature proving that the owner of <address> holds at least this much, optionally with a challenge string <message>."));
2961 m_cmd_binder.set_handler("show_transfers",
2962 boost::bind(&simple_wallet::show_transfers, this, _1),
2963 tr(USAGE_SHOW_TRANSFERS),
2964 // Seemingly broken formatting to compensate for the backslash before the quotes.
2965 tr("Show the incoming/outgoing transfers within an optional height range.\n\n"
2966 "Output format:\n"
2967 "In or Coinbase: Block Number, \"block\"|\"in\", Time, Amount, Transaction Hash, Payment ID, Subaddress Index, \"-\", Note\n"
2968 "Out: Block Number, \"out\", Time, Amount*, Transaction Hash, Payment ID, Fee, Destinations, Input addresses**, \"-\", Note\n"
2969 "Pool: \"pool\", \"in\", Time, Amount, Transaction Hash, Payment Id, Subaddress Index, \"-\", Note, Double Spend Note\n"
2970 "Pending or Failed: \"failed\"|\"pending\", \"out\", Time, Amount*, Transaction Hash, Payment ID, Fee, Input addresses**, \"-\", Note\n\n"
2971 "* Excluding change and fee.\n"
2972 "** Set of address indices used as inputs in this transfer."));
2973 m_cmd_binder.set_handler("export_transfers",
2974 boost::bind(&simple_wallet::export_transfers, this, _1),
2975 tr("export_transfers [in|out|all|pending|failed|coinbase] [index=<N1>[,<N2>,...]] [<min_height> [<max_height>]] [output=<filepath>]"),
2976 tr("Export to CSV the incoming/outgoing transfers within an optional height range."));
2977 m_cmd_binder.set_handler("unspent_outputs",
2978 boost::bind(&simple_wallet::unspent_outputs, this, _1),
2979 tr(USAGE_UNSPENT_OUTPUTS),
2980 tr("Show the unspent outputs of a specified address within an optional amount range."));
2981 m_cmd_binder.set_handler("rescan_bc",
2982 boost::bind(&simple_wallet::rescan_blockchain, this, _1),
2983 tr(USAGE_RESCAN_BC),
2984 tr("Rescan the blockchain from scratch. If \"hard\" is specified, you will lose any information which can not be recovered from the blockchain itself."));
2985 m_cmd_binder.set_handler("set_tx_note",
2986 boost::bind(&simple_wallet::set_tx_note, this, _1),
2987 tr(USAGE_SET_TX_NOTE),
2988 tr("Set an arbitrary string note for a <txid>."));
2989 m_cmd_binder.set_handler("get_tx_note",
2990 boost::bind(&simple_wallet::get_tx_note, this, _1),
2991 tr(USAGE_GET_TX_NOTE),
2992 tr("Get a string note for a txid."));
2993 m_cmd_binder.set_handler("set_description",
2994 boost::bind(&simple_wallet::set_description, this, _1),
2995 tr(USAGE_SET_DESCRIPTION),
2996 tr("Set an arbitrary description for the wallet."));
2997 m_cmd_binder.set_handler("get_description",
2998 boost::bind(&simple_wallet::get_description, this, _1),
2999 tr(USAGE_GET_DESCRIPTION),
3000 tr("Get the description of the wallet."));
3001 m_cmd_binder.set_handler("status",
3002 boost::bind(&simple_wallet::status, this, _1),
3003 tr("Show the wallet's status."));
3004 m_cmd_binder.set_handler("wallet_info",
3005 boost::bind(&simple_wallet::wallet_info, this, _1),
3006 tr("Show the wallet's information."));
3007 m_cmd_binder.set_handler("sign",
3008 boost::bind(&simple_wallet::sign, this, _1),
3009 tr(USAGE_SIGN),
3010 tr("Sign the contents of a file."));
3011 m_cmd_binder.set_handler("verify",
3012 boost::bind(&simple_wallet::verify, this, _1),
3013 tr(USAGE_VERIFY),
3014 tr("Verify a signature on the contents of a file."));
3015 m_cmd_binder.set_handler("export_key_images",
3016 boost::bind(&simple_wallet::export_key_images, this, _1),
3017 tr(USAGE_EXPORT_KEY_IMAGES),
3018 tr("Export a signed set of key images to a <filename>."));
3019 m_cmd_binder.set_handler("import_key_images",
3020 boost::bind(&simple_wallet::import_key_images, this, _1),
3021 tr(USAGE_IMPORT_KEY_IMAGES),
3022 tr("Import a signed key images list and verify their spent status."));
3023 m_cmd_binder.set_handler("hw_key_images_sync",
3024 boost::bind(&simple_wallet::hw_key_images_sync, this, _1),
3025 tr(USAGE_HW_KEY_IMAGES_SYNC),
3026 tr("Synchronizes key images with the hw wallet."));
3027 m_cmd_binder.set_handler("hw_reconnect",
3028 boost::bind(&simple_wallet::hw_reconnect, this, _1),
3029 tr(USAGE_HW_RECONNECT),
3030 tr("Attempts to reconnect HW wallet."));
3031 m_cmd_binder.set_handler("export_outputs",
3032 boost::bind(&simple_wallet::export_outputs, this, _1),
3033 tr(USAGE_EXPORT_OUTPUTS),
3034 tr("Export a set of outputs owned by this wallet."));
3035 m_cmd_binder.set_handler("import_outputs",
3036 boost::bind(&simple_wallet::import_outputs, this, _1),
3037 tr(USAGE_IMPORT_OUTPUTS),
3038 tr("Import a set of outputs owned by this wallet."));
3039 m_cmd_binder.set_handler("show_transfer",
3040 boost::bind(&simple_wallet::show_transfer, this, _1),
3041 tr(USAGE_SHOW_TRANSFER),
3042 tr("Show information about a transfer to/from this address."));
3043 m_cmd_binder.set_handler("password",
3044 boost::bind(&simple_wallet::change_password, this, _1),
3045 tr("Change the wallet's password."));
3046 m_cmd_binder.set_handler("payment_id",
3047 boost::bind(&simple_wallet::payment_id, this, _1),
3048 tr(USAGE_PAYMENT_ID),
3049 tr("Generate a new random full size payment id (obsolete). These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids."));
3050 m_cmd_binder.set_handler("fee",
3051 boost::bind(&simple_wallet::print_fee_info, this, _1),
3052 tr("Print the information about the current fee and transaction backlog."));
3053 m_cmd_binder.set_handler("prepare_multisig", boost::bind(&simple_wallet::prepare_multisig, this, _1),
3054 tr("Export data needed to create a multisig wallet"));
3055 m_cmd_binder.set_handler("make_multisig", boost::bind(&simple_wallet::make_multisig, this, _1),
3056 tr(USAGE_MAKE_MULTISIG),
3057 tr("Turn this wallet into a multisig wallet"));
3058 m_cmd_binder.set_handler("finalize_multisig",
3059 boost::bind(&simple_wallet::finalize_multisig, this, _1),
3060 tr(USAGE_FINALIZE_MULTISIG),
3061 tr("Turn this wallet into a multisig wallet, extra step for N-1/N wallets"));
3062 m_cmd_binder.set_handler("exchange_multisig_keys",
3063 boost::bind(&simple_wallet::exchange_multisig_keys, this, _1),
3064 tr(USAGE_EXCHANGE_MULTISIG_KEYS),
3065 tr("Performs extra multisig keys exchange rounds. Needed for arbitrary M/N multisig wallets"));
3066 m_cmd_binder.set_handler("export_multisig_info",
3067 boost::bind(&simple_wallet::export_multisig, this, _1),
3068 tr(USAGE_EXPORT_MULTISIG_INFO),
3069 tr("Export multisig info for other participants"));
3070 m_cmd_binder.set_handler("import_multisig_info",
3071 boost::bind(&simple_wallet::import_multisig, this, _1),
3072 tr(USAGE_IMPORT_MULTISIG_INFO),
3073 tr("Import multisig info from other participants"));
3074 m_cmd_binder.set_handler("sign_multisig",
3075 boost::bind(&simple_wallet::sign_multisig, this, _1),
3076 tr(USAGE_SIGN_MULTISIG),
3077 tr("Sign a multisig transaction from a file"));
3078 m_cmd_binder.set_handler("submit_multisig",
3079 boost::bind(&simple_wallet::submit_multisig, this, _1),
3080 tr(USAGE_SUBMIT_MULTISIG),
3081 tr("Submit a signed multisig transaction from a file"));
3082 m_cmd_binder.set_handler("export_raw_multisig_tx",
3083 boost::bind(&simple_wallet::export_raw_multisig, this, _1),
3084 tr(USAGE_EXPORT_RAW_MULTISIG_TX),
3085 tr("Export a signed multisig transaction to a file"));
3086 m_cmd_binder.set_handler("mms",
3087 boost::bind(&simple_wallet::mms, this, _1),
3088 tr(USAGE_MMS),
3089 tr("Interface with the MMS (Multisig Messaging System)\n"
3090 "<subcommand> is one of:\n"
3091 " init, info, signer, list, next, sync, transfer, delete, send, receive, export, note, show, set, help\n"
3092 " send_signer_config, start_auto_config, stop_auto_config, auto_config\n"
3093 "Get help about a subcommand with: help mms <subcommand>, or mms help <subcommand>"));
3094 m_cmd_binder.set_handler("mms init",
3095 boost::bind(&simple_wallet::mms, this, _1),
3096 tr(USAGE_MMS_INIT),
3097 tr("Initialize and configure the MMS for M/N = number of required signers/number of authorized signers multisig"));
3098 m_cmd_binder.set_handler("mms info",
3099 boost::bind(&simple_wallet::mms, this, _1),
3100 tr(USAGE_MMS_INFO),
3101 tr("Display current MMS configuration"));
3102 m_cmd_binder.set_handler("mms signer",
3103 boost::bind(&simple_wallet::mms, this, _1),
3104 tr(USAGE_MMS_SIGNER),
3105 tr("Set or modify authorized signer info (single-word label, transport address, Electroneum address), or list all signers"));
3106 m_cmd_binder.set_handler("mms list",
3107 boost::bind(&simple_wallet::mms, this, _1),
3108 tr(USAGE_MMS_LIST),
3109 tr("List all messages"));
3110 m_cmd_binder.set_handler("mms next",
3111 boost::bind(&simple_wallet::mms, this, _1),
3112 tr(USAGE_MMS_NEXT),
3113 tr("Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice\n"
3114 "By using 'sync' processing of waiting messages with multisig sync info can be forced regardless of wallet state"));
3115 m_cmd_binder.set_handler("mms sync",
3116 boost::bind(&simple_wallet::mms, this, _1),
3117 tr(USAGE_MMS_SYNC),
3118 tr("Force generation of multisig sync info regardless of wallet state, to recover from special situations like \"stale data\" errors"));
3119 m_cmd_binder.set_handler("mms transfer",
3120 boost::bind(&simple_wallet::mms, this, _1),
3121 tr(USAGE_MMS_TRANSFER),
3122 tr("Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there"));
3123 m_cmd_binder.set_handler("mms delete",
3124 boost::bind(&simple_wallet::mms, this, _1),
3125 tr(USAGE_MMS_DELETE),
3126 tr("Delete a single message by giving its id, or delete all messages by using 'all'"));
3127 m_cmd_binder.set_handler("mms send",
3128 boost::bind(&simple_wallet::mms, this, _1),
3129 tr(USAGE_MMS_SEND),
3130 tr("Send a single message by giving its id, or send all waiting messages"));
3131 m_cmd_binder.set_handler("mms receive",
3132 boost::bind(&simple_wallet::mms, this, _1),
3133 tr(USAGE_MMS_RECEIVE),
3134 tr("Check right away for new messages to receive"));
3135 m_cmd_binder.set_handler("mms export",
3136 boost::bind(&simple_wallet::mms, this, _1),
3137 tr(USAGE_MMS_EXPORT),
3138 tr("Write the content of a message to a file \"mms_message_content\""));
3139 m_cmd_binder.set_handler("mms note",
3140 boost::bind(&simple_wallet::mms, this, _1),
3141 tr(USAGE_MMS_NOTE),
3142 tr("Send a one-line message to an authorized signer, identified by its label, or show any waiting unread notes"));
3143 m_cmd_binder.set_handler("mms show",
3144 boost::bind(&simple_wallet::mms, this, _1),
3145 tr(USAGE_MMS_SHOW),
3146 tr("Show detailed info about a single message"));
3147 m_cmd_binder.set_handler("mms set",
3148 boost::bind(&simple_wallet::mms, this, _1),
3149 tr(USAGE_MMS_SET),
3150 tr("Available options:\n "
3151 "auto-send <1|0>\n "
3152 " Whether to automatically send newly generated messages right away.\n "));
3153 m_cmd_binder.set_handler("mms send_message_config",
3154 boost::bind(&simple_wallet::mms, this, _1),
3155 tr(USAGE_MMS_SEND_SIGNER_CONFIG),
3156 tr("Send completed signer config to all other authorized signers"));
3157 m_cmd_binder.set_handler("mms start_auto_config",
3158 boost::bind(&simple_wallet::mms, this, _1),
3159 tr(USAGE_MMS_START_AUTO_CONFIG),
3160 tr("Start auto-config at the auto-config manager's wallet by issuing auto-config tokens and optionally set others' labels"));
3161 m_cmd_binder.set_handler("mms stop_auto_config",
3162 boost::bind(&simple_wallet::mms, this, _1),
3163 tr(USAGE_MMS_STOP_AUTO_CONFIG),
3164 tr("Delete any auto-config tokens and abort a auto-config process"));
3165 m_cmd_binder.set_handler("mms auto_config",
3166 boost::bind(&simple_wallet::mms, this, _1),
3167 tr(USAGE_MMS_AUTO_CONFIG),
3168 tr("Start auto-config by using the token received from the auto-config manager"));
3169 m_cmd_binder.set_handler("print_ring",
3170 boost::bind(&simple_wallet::print_ring, this, _1),
3171 tr(USAGE_PRINT_RING),
3172 tr("Print the ring(s) used to spend a given key image or transaction (if the ring size is > 1)\n\n"
3173 "Output format:\n"
3174 "Key Image, \"absolute\", list of rings"));
3175 m_cmd_binder.set_handler("set_ring",
3176 boost::bind(&simple_wallet::set_ring, this, _1),
3177 tr(USAGE_SET_RING),
3178 tr("Set the ring used for a given key image, so it can be reused in a fork"));
3179 m_cmd_binder.set_handler("unset_ring",
3180 boost::bind(&simple_wallet::unset_ring, this, _1),
3181 tr(USAGE_UNSET_RING),
3182 tr("Unsets the ring used for a given key image or transaction"));
3183 m_cmd_binder.set_handler("save_known_rings",
3184 boost::bind(&simple_wallet::save_known_rings, this, _1),
3185 tr(USAGE_SAVE_KNOWN_RINGS),
3186 tr("Save known rings to the shared rings database"));
3187 m_cmd_binder.set_handler("mark_output_spent",
3188 boost::bind(&simple_wallet::blackball, this, _1),
3189 tr(USAGE_MARK_OUTPUT_SPENT),
3190 tr("Mark output(s) as spent so they never get selected as fake outputs in a ring"));
3191 m_cmd_binder.set_handler("mark_output_unspent",
3192 boost::bind(&simple_wallet::unblackball, this, _1),
3193 tr(USAGE_MARK_OUTPUT_UNSPENT),
3194 tr("Marks an output as unspent so it may get selected as a fake output in a ring"));
3195 m_cmd_binder.set_handler("is_output_spent",
3196 boost::bind(&simple_wallet::blackballed, this, _1),
3197 tr(USAGE_IS_OUTPUT_SPENT),
3198 tr("Checks whether an output is marked as spent"));
3199 m_cmd_binder.set_handler("freeze",
3200 boost::bind(&simple_wallet::freeze, this, _1),
3201 tr(USAGE_FREEZE),
3202 tr("Freeze a single output by key image so it will not be used"));
3203 m_cmd_binder.set_handler("thaw",
3204 boost::bind(&simple_wallet::thaw, this, _1),
3205 tr(USAGE_THAW),
3206 tr("Thaw a single output by key image so it may be used again"));
3207 m_cmd_binder.set_handler("frozen",
3208 boost::bind(&simple_wallet::frozen, this, _1),
3209 tr(USAGE_FROZEN),
3210 tr("Checks whether a given output is currently frozen by key image"));
3211 m_cmd_binder.set_handler("net_stats",
3212 boost::bind(&simple_wallet::net_stats, this, _1),
3213 tr(USAGE_NET_STATS),
3214 tr("Prints simple network stats"));
3215 m_cmd_binder.set_handler("welcome",
3216 boost::bind(&simple_wallet::welcome, this, _1),
3217 tr(USAGE_WELCOME),
3218 tr("Prints basic info about Electroneum for first time users"));
3219 m_cmd_binder.set_handler("version",
3220 boost::bind(&simple_wallet::version, this, _1),
3221 tr(USAGE_VERSION),
3222 tr("Returns version information"));
3223 m_cmd_binder.set_handler("help",
3224 boost::bind(&simple_wallet::help, this, _1),
3225 tr(USAGE_HELP),
3226 tr("Show the help section or the documentation about a <command>."));
3227}
#define tr(x)
Here is the caller graph for this function:

Member Function Documentation

◆ deinit()

bool simple_wallet::deinit ( )

Definition at line 4133 of file simplewallet.cpp.

4134{
4135 if (!m_wallet.get())
4136 return true;
4137
4138 return close_wallet();
4139}
Here is the caller graph for this function:

◆ get_command_usage()

std::string simple_wallet::get_command_usage ( const std::vector< std::string > & args)

Definition at line 686 of file simplewallet.cpp.

687{
688 std::pair<std::string, std::string> documentation = m_cmd_binder.get_documentation(args);
689 std::stringstream ss;
690 if(documentation.first.empty())
691 {
692 ss << tr("Unknown command: ") << args.front();
693 }
694 else
695 {
696 std::string usage = documentation.second.empty() ? args.front() : documentation.first;
697 std::string description = documentation.second.empty() ? documentation.first : documentation.second;
698 usage.insert(0, " ");
699 ss << tr("Command usage: ") << ENDL << usage << ENDL << ENDL;
700 boost::replace_all(description, "\n", "\n ");
701 description.insert(0, " ");
702 ss << tr("Command description: ") << ENDL << description << ENDL;
703 }
704 return ss.str();
705}
#define ENDL

◆ get_commands_str()

std::string simple_wallet::get_commands_str ( )

Definition at line 675 of file simplewallet.cpp.

676{
677 std::stringstream ss;
678 ss << tr("Commands: ") << ENDL;
679 std::string usage = m_cmd_binder.get_usage();
680 boost::replace_all(usage, "\n", "\n ");
681 usage.insert(0, " ");
682 ss << usage << ENDL;
683 return ss.str();
684}

◆ init()

bool simple_wallet::init ( const boost::program_options::variables_map & vm)

Definition at line 3520 of file simplewallet.cpp.

3521{
3523 m_electrum_seed.wipe();
3524 });
3525
3526 const bool testnet = tools::wallet2::has_testnet_option(vm);
3527 const bool stagenet = tools::wallet2::has_stagenet_option(vm);
3528 if (testnet && stagenet)
3529 {
3530 fail_msg_writer() << tr("Can't specify more than one of --testnet and --stagenet");
3531 return false;
3532 }
3533 const network_type nettype = testnet ? TESTNET : stagenet ? STAGENET : MAINNET;
3534
3535 epee::wipeable_string multisig_keys;
3536 epee::wipeable_string password;
3537
3538 if (!handle_command_line(vm))
3539 return false;
3540
3541 bool welcome = false;
3542
3543 if((!m_generate_new.empty()) + (!m_wallet_file.empty()) + (!m_generate_from_device.empty()) + (!m_generate_from_view_key.empty()) + (!m_generate_from_spend_key.empty()) + (!m_generate_from_keys.empty()) + (!m_generate_from_multisig_keys.empty()) + (!m_generate_from_json.empty()) > 1)
3544 {
3545 fail_msg_writer() << tr("can't specify more than one of --generate-new-wallet=\"wallet_name\", --wallet-file=\"wallet_name\", --generate-from-view-key=\"wallet_name\", --generate-from-spend-key=\"wallet_name\", --generate-from-keys=\"wallet_name\", --generate-from-multisig-keys=\"wallet_name\", --generate-from-json=\"jsonfilename\" and --generate-from-device=\"wallet_name\"");
3546 return false;
3547 }
3548 else if (m_generate_new.empty() && m_wallet_file.empty() && m_generate_from_device.empty() && m_generate_from_view_key.empty() && m_generate_from_spend_key.empty() && m_generate_from_keys.empty() && m_generate_from_multisig_keys.empty() && m_generate_from_json.empty())
3549 {
3550 if(!ask_wallet_create_if_needed()) return false;
3551 }
3552
3553 if (!m_generate_new.empty() || m_restoring)
3554 {
3555 if (!m_subaddress_lookahead.empty() && !parse_subaddress_lookahead(m_subaddress_lookahead))
3556 return false;
3557
3558 std::string old_language;
3559 // check for recover flag. if present, require electrum word list (only recovery option for now).
3560 if (m_restore_deterministic_wallet || m_restore_multisig_wallet)
3561 {
3562 if (m_non_deterministic)
3563 {
3564 fail_msg_writer() << tr("can't specify both --restore-deterministic-wallet or --restore-multisig-wallet and --non-deterministic");
3565 return false;
3566 }
3567 if (!m_wallet_file.empty())
3568 {
3569 if (m_restore_multisig_wallet)
3570 fail_msg_writer() << tr("--restore-multisig-wallet uses --generate-new-wallet, not --wallet-file");
3571 else
3572 fail_msg_writer() << tr("--restore-deterministic-wallet uses --generate-new-wallet, not --wallet-file");
3573 return false;
3574 }
3575
3576 if (m_electrum_seed.empty())
3577 {
3578 if (m_restore_multisig_wallet)
3579 {
3580 const char *prompt = "Specify multisig seed";
3581 m_electrum_seed = input_secure_line(prompt);
3582 if (std::cin.eof())
3583 return false;
3584 if (m_electrum_seed.empty())
3585 {
3586 fail_msg_writer() << tr("specify a recovery parameter with the --electrum-seed=\"multisig seed here\"");
3587 return false;
3588 }
3589 }
3590 else
3591 {
3592 m_electrum_seed = "";
3593 do
3594 {
3595 const char *prompt = m_electrum_seed.empty() ? "Specify Electrum seed" : "Electrum seed continued";
3596 epee::wipeable_string electrum_seed = input_secure_line(prompt);
3597 if (std::cin.eof())
3598 return false;
3599 if (electrum_seed.empty())
3600 {
3601 fail_msg_writer() << tr("specify a recovery parameter with the --electrum-seed=\"words list here\"");
3602 return false;
3603 }
3604 m_electrum_seed += electrum_seed;
3605 m_electrum_seed += ' ';
3606 } while (might_be_partial_seed(m_electrum_seed));
3607 }
3608 }
3609
3610 if (m_restore_multisig_wallet)
3611 {
3612 const boost::optional<epee::wipeable_string> parsed = m_electrum_seed.parse_hexstr();
3613 if (!parsed)
3614 {
3615 fail_msg_writer() << tr("Multisig seed failed verification");
3616 return false;
3617 }
3618 multisig_keys = *parsed;
3619 }
3620 else
3621 {
3622 if (!crypto::ElectrumWords::words_to_bytes(m_electrum_seed, m_recovery_key, old_language))
3623 {
3624 fail_msg_writer() << tr("Electrum-style word list failed verification");
3625 return false;
3626 }
3627 }
3628
3629 auto pwd_container = password_prompter(tr("Enter seed offset passphrase, empty if none"), false);
3630 if (std::cin.eof() || !pwd_container)
3631 return false;
3632 epee::wipeable_string seed_pass = pwd_container->password();
3633 if (!seed_pass.empty())
3634 {
3635 if (m_restore_multisig_wallet)
3636 {
3638 crypto::cn_slow_hash(seed_pass.data(), seed_pass.size(), (crypto::hash&)key);
3639 sc_reduce32((unsigned char*)key.data);
3640 multisig_keys = m_wallet->decrypt<epee::wipeable_string>(std::string(multisig_keys.data(), multisig_keys.size()), key, true);
3641 }
3642 else
3643 m_recovery_key = cryptonote::decrypt_key(m_recovery_key, seed_pass);
3644 }
3645 }
3646 if (!m_generate_from_view_key.empty())
3647 {
3648 m_wallet_file = m_generate_from_view_key;
3649 // parse address
3650 std::string address_string = input_line("Standard address");
3651 if (std::cin.eof())
3652 return false;
3653 if (address_string.empty()) {
3654 fail_msg_writer() << tr("No data supplied, cancelled");
3655 return false;
3656 }
3657 cryptonote::address_parse_info info;
3658 if(!get_account_address_from_str(info, nettype, address_string))
3659 {
3660 fail_msg_writer() << tr("failed to parse address");
3661 return false;
3662 }
3663 if (info.is_subaddress)
3664 {
3665 fail_msg_writer() << tr("This address is a subaddress which cannot be used here.");
3666 return false;
3667 }
3668
3669 // parse view secret key
3670 epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
3671 if (std::cin.eof())
3672 return false;
3673 if (viewkey_string.empty()) {
3674 fail_msg_writer() << tr("No data supplied, cancelled");
3675 return false;
3676 }
3677 crypto::secret_key viewkey;
3678 if (!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
3679 {
3680 fail_msg_writer() << tr("failed to parse view key secret key");
3681 return false;
3682 }
3683
3684 m_wallet_file=m_generate_from_view_key;
3685
3686 // check the view key matches the given address
3687 crypto::public_key pkey;
3688 if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
3689 fail_msg_writer() << tr("failed to verify view key secret key");
3690 return false;
3691 }
3692 if (info.address.m_view_public_key != pkey) {
3693 fail_msg_writer() << tr("view key does not match standard address");
3694 return false;
3695 }
3696
3697 auto r = new_wallet(vm, info.address, boost::none, viewkey);
3698 CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
3699 password = *r;
3700 welcome = true;
3701 }
3702 else if (!m_generate_from_spend_key.empty())
3703 {
3704 m_wallet_file = m_generate_from_spend_key;
3705 // parse spend secret key
3706 epee::wipeable_string spendkey_string = input_secure_line("Secret spend key");
3707 if (std::cin.eof())
3708 return false;
3709 if (spendkey_string.empty()) {
3710 fail_msg_writer() << tr("No data supplied, cancelled");
3711 return false;
3712 }
3713 if (!spendkey_string.hex_to_pod(unwrap(unwrap(m_recovery_key))))
3714 {
3715 fail_msg_writer() << tr("failed to parse spend key secret key");
3716 return false;
3717 }
3718 auto r = new_wallet(vm, m_recovery_key, true, false, "");
3719 CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
3720 password = *r;
3721 welcome = true;
3722 }
3723 else if (!m_generate_from_keys.empty())
3724 {
3725 m_wallet_file = m_generate_from_keys;
3726 // parse address
3727 std::string address_string = input_line("Standard address");
3728 if (std::cin.eof())
3729 return false;
3730 if (address_string.empty()) {
3731 fail_msg_writer() << tr("No data supplied, cancelled");
3732 return false;
3733 }
3734 cryptonote::address_parse_info info;
3735 if(!get_account_address_from_str(info, nettype, address_string))
3736 {
3737 fail_msg_writer() << tr("failed to parse address");
3738 return false;
3739 }
3740 if (info.is_subaddress)
3741 {
3742 fail_msg_writer() << tr("This address is a subaddress which cannot be used here.");
3743 return false;
3744 }
3745
3746 // parse spend secret key
3747 epee::wipeable_string spendkey_string = input_secure_line("Secret spend key");
3748 if (std::cin.eof())
3749 return false;
3750 if (spendkey_string.empty()) {
3751 fail_msg_writer() << tr("No data supplied, cancelled");
3752 return false;
3753 }
3754 crypto::secret_key spendkey;
3755 if (!spendkey_string.hex_to_pod(unwrap(unwrap(spendkey))))
3756 {
3757 fail_msg_writer() << tr("failed to parse spend key secret key");
3758 return false;
3759 }
3760
3761 // parse view secret key
3762 epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
3763 if (std::cin.eof())
3764 return false;
3765 if (viewkey_string.empty()) {
3766 fail_msg_writer() << tr("No data supplied, cancelled");
3767 return false;
3768 }
3769 crypto::secret_key viewkey;
3770 if(!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
3771 {
3772 fail_msg_writer() << tr("failed to parse view key secret key");
3773 return false;
3774 }
3775
3776 m_wallet_file=m_generate_from_keys;
3777
3778 // check the spend and view keys match the given address
3779 crypto::public_key pkey;
3780 if (!crypto::secret_key_to_public_key(spendkey, pkey)) {
3781 fail_msg_writer() << tr("failed to verify spend key secret key");
3782 return false;
3783 }
3784 if (info.address.m_spend_public_key != pkey) {
3785 fail_msg_writer() << tr("spend key does not match standard address");
3786 return false;
3787 }
3788 if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
3789 fail_msg_writer() << tr("failed to verify view key secret key");
3790 return false;
3791 }
3792 if (info.address.m_view_public_key != pkey) {
3793 fail_msg_writer() << tr("view key does not match standard address");
3794 return false;
3795 }
3796 auto r = new_wallet(vm, info.address, spendkey, viewkey);
3797 CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
3798 password = *r;
3799 welcome = true;
3800 }
3801
3802 // Asks user for all the data required to merge secret keys from multisig wallets into one master wallet, which then gets full control of the multisig wallet. The resulting wallet will be the same as any other regular wallet.
3803 else if (!m_generate_from_multisig_keys.empty())
3804 {
3805 m_wallet_file = m_generate_from_multisig_keys;
3806 unsigned int multisig_m;
3807 unsigned int multisig_n;
3808
3809 // parse multisig type
3810 std::string multisig_type_string = input_line("Multisig type (input as M/N with M <= N and M > 1)");
3811 if (std::cin.eof())
3812 return false;
3813 if (multisig_type_string.empty())
3814 {
3815 fail_msg_writer() << tr("No data supplied, cancelled");
3816 return false;
3817 }
3818 if (sscanf(multisig_type_string.c_str(), "%u/%u", &multisig_m, &multisig_n) != 2)
3819 {
3820 fail_msg_writer() << tr("Error: expected M/N, but got: ") << multisig_type_string;
3821 return false;
3822 }
3823 if (multisig_m <= 1 || multisig_m > multisig_n)
3824 {
3825 fail_msg_writer() << tr("Error: expected N > 1 and N <= M, but got: ") << multisig_type_string;
3826 return false;
3827 }
3828 if (multisig_m != multisig_n)
3829 {
3830 fail_msg_writer() << tr("Error: M/N is currently unsupported. ");
3831 return false;
3832 }
3833 message_writer() << boost::format(tr("Generating master wallet from %u of %u multisig wallet keys")) % multisig_m % multisig_n;
3834
3835 // parse multisig address
3836 std::string address_string = input_line("Multisig wallet address");
3837 if (std::cin.eof())
3838 return false;
3839 if (address_string.empty()) {
3840 fail_msg_writer() << tr("No data supplied, cancelled");
3841 return false;
3842 }
3843 cryptonote::address_parse_info info;
3844 if(!get_account_address_from_str(info, nettype, address_string))
3845 {
3846 fail_msg_writer() << tr("failed to parse address");
3847 return false;
3848 }
3849
3850 // parse secret view key
3851 epee::wipeable_string viewkey_string = input_secure_line("Secret view key");
3852 if (std::cin.eof())
3853 return false;
3854 if (viewkey_string.empty())
3855 {
3856 fail_msg_writer() << tr("No data supplied, cancelled");
3857 return false;
3858 }
3859 crypto::secret_key viewkey;
3860 if(!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
3861 {
3862 fail_msg_writer() << tr("failed to parse secret view key");
3863 return false;
3864 }
3865
3866 // check that the view key matches the given address
3867 crypto::public_key pkey;
3868 if (!crypto::secret_key_to_public_key(viewkey, pkey))
3869 {
3870 fail_msg_writer() << tr("failed to verify secret view key");
3871 return false;
3872 }
3873 if (info.address.m_view_public_key != pkey)
3874 {
3875 fail_msg_writer() << tr("view key does not match standard address");
3876 return false;
3877 }
3878
3879 // parse multisig spend keys
3880 crypto::secret_key spendkey;
3881 // parsing N/N
3882 if(multisig_m == multisig_n)
3883 {
3884 std::vector<crypto::secret_key> multisig_secret_spendkeys(multisig_n);
3885 epee::wipeable_string spendkey_string;
3886 cryptonote::blobdata spendkey_data;
3887 // get N secret spend keys from user
3888 for(unsigned int i=0; i<multisig_n; ++i)
3889 {
3890 spendkey_string = input_secure_line(tr((boost::format(tr("Secret spend key (%u of %u)")) % (i+1) % multisig_m).str().c_str()));
3891 if (std::cin.eof())
3892 return false;
3893 if (spendkey_string.empty())
3894 {
3895 fail_msg_writer() << tr("No data supplied, cancelled");
3896 return false;
3897 }
3898 if(!spendkey_string.hex_to_pod(unwrap(unwrap(multisig_secret_spendkeys[i]))))
3899 {
3900 fail_msg_writer() << tr("failed to parse spend key secret key");
3901 return false;
3902 }
3903 }
3904
3905 // sum the spend keys together to get the master spend key
3906 spendkey = multisig_secret_spendkeys[0];
3907 for(unsigned int i=1; i<multisig_n; ++i)
3908 sc_add(reinterpret_cast<unsigned char*>(&spendkey), reinterpret_cast<unsigned char*>(&spendkey), reinterpret_cast<unsigned char*>(&multisig_secret_spendkeys[i]));
3909 }
3910 // parsing M/N
3911 else
3912 {
3913 fail_msg_writer() << tr("Error: M/N is currently unsupported");
3914 return false;
3915 }
3916
3917 // check that the spend key matches the given address
3918 if (!crypto::secret_key_to_public_key(spendkey, pkey))
3919 {
3920 fail_msg_writer() << tr("failed to verify spend key secret key");
3921 return false;
3922 }
3923 if (info.address.m_spend_public_key != pkey)
3924 {
3925 fail_msg_writer() << tr("spend key does not match standard address");
3926 return false;
3927 }
3928
3929 // create wallet
3930 auto r = new_wallet(vm, info.address, spendkey, viewkey);
3931 CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
3932 password = *r;
3933 welcome = true;
3934 }
3935
3936 else if (!m_generate_from_json.empty())
3937 {
3938 try
3939 {
3940 auto rc = tools::wallet2::make_from_json(vm, false, m_generate_from_json, password_prompter);
3941 m_wallet = std::move(rc.first);
3942 password = rc.second.password();
3943 m_wallet_file = m_wallet->path();
3944 }
3945 catch (const std::exception &e)
3946 {
3947 fail_msg_writer() << e.what();
3948 return false;
3949 }
3950 if (!m_wallet)
3951 return false;
3952 }
3953 else if (!m_generate_from_device.empty())
3954 {
3955 m_wallet_file = m_generate_from_device;
3956 // create wallet
3957 auto r = new_wallet(vm);
3958 CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
3959 password = *r;
3960 welcome = true;
3961 // if no block_height is specified, assume its a new account and start it "now"
3962 if(m_wallet->get_refresh_from_block_height() == 0) {
3963 {
3964 tools::scoped_message_writer wrt = tools::msg_writer();
3965 wrt << tr("No restore height is specified.") << " ";
3966 wrt << tr("Assumed you are creating a new account, restore will be done from current estimated blockchain height.") << " ";
3967 wrt << tr("Use --restore-height or --restore-date if you want to restore an already setup account from a specific height.");
3968 }
3969 std::string confirm = input_line(tr("Is this okay?"), true);
3970 if (std::cin.eof() || !command_line::is_yes(confirm))
3971 CHECK_AND_ASSERT_MES(false, false, tr("account creation aborted"));
3972
3973 m_wallet->set_refresh_from_block_height(m_wallet->estimate_blockchain_height());
3974 m_wallet->explicit_refresh_from_block_height(true);
3975 m_restore_height = m_wallet->get_refresh_from_block_height();
3976 m_wallet->always_confirm_transfers(true);
3977 }
3978 }
3979 else
3980 {
3981 if (m_generate_new.empty()) {
3982 fail_msg_writer() << tr("specify a wallet path with --generate-new-wallet (not --wallet-file)");
3983 return false;
3984 }
3985 m_wallet_file = m_generate_new;
3986 boost::optional<epee::wipeable_string> r;
3987 if (m_restore_multisig_wallet)
3988 r = new_wallet(vm, multisig_keys, old_language);
3989 else
3990 r = new_wallet(vm, m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic, old_language);
3991 CHECK_AND_ASSERT_MES(r, false, tr("account creation failed"));
3992 password = *r;
3993 welcome = true;
3994 }
3995
3996 if (m_restoring && m_generate_from_json.empty() && m_generate_from_device.empty())
3997 {
3998 m_wallet->explicit_refresh_from_block_height(!(command_line::is_arg_defaulted(vm, arg_restore_height) ||
3999 command_line::is_arg_defaulted(vm, arg_restore_date)));
4000 if (command_line::is_arg_defaulted(vm, arg_restore_height) && !command_line::is_arg_defaulted(vm, arg_restore_date))
4001 {
4002 uint16_t year;
4003 uint8_t month;
4004 uint8_t day;
4005 if (!datestr_to_int(m_restore_date, year, month, day))
4006 return false;
4007 try
4008 {
4009 m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day);
4010 success_msg_writer() << tr("Restore height is: ") << m_restore_height;
4011 }
4012 catch (const std::runtime_error& e)
4013 {
4014 fail_msg_writer() << e.what();
4015 return false;
4016 }
4017 }
4018 }
4019 if (!m_wallet->explicit_refresh_from_block_height() && m_restoring)
4020 {
4021 uint32_t version;
4022 bool connected = try_connect_to_daemon(false, &version);
4023 while (true)
4024 {
4025 std::string heightstr;
4026 if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6))
4027 heightstr = input_line("Restore from specific blockchain height (optional, default 0)");
4028 else
4029 heightstr = input_line("Restore from specific blockchain height (optional, default 0),\nor alternatively from specific date (YYYY-MM-DD)");
4030 if (std::cin.eof())
4031 return false;
4032 if (heightstr.empty())
4033 {
4034 m_restore_height = 0;
4035 break;
4036 }
4037 try
4038 {
4039 m_restore_height = boost::lexical_cast<uint64_t>(heightstr);
4040 break;
4041 }
4042 catch (const boost::bad_lexical_cast &)
4043 {
4044 if (!connected || version < MAKE_CORE_RPC_VERSION(1, 6))
4045 {
4046 fail_msg_writer() << tr("bad m_restore_height parameter: ") << heightstr;
4047 continue;
4048 }
4049 uint16_t year;
4050 uint8_t month; // 1, 2, ..., 12
4051 uint8_t day; // 1, 2, ..., 31
4052 try
4053 {
4054 if (!datestr_to_int(heightstr, year, month, day))
4055 return false;
4056 m_restore_height = m_wallet->get_blockchain_height_by_date(year, month, day);
4057 success_msg_writer() << tr("Restore height is: ") << m_restore_height;
4058 std::string confirm = input_line(tr("Is this okay?"), true);
4059 if (std::cin.eof())
4060 return false;
4061 if(command_line::is_yes(confirm))
4062 break;
4063 }
4064 catch (const boost::bad_lexical_cast &)
4065 {
4066 fail_msg_writer() << tr("bad m_restore_height parameter: ") << heightstr;
4067 }
4068 catch (const std::runtime_error& e)
4069 {
4070 fail_msg_writer() << e.what();
4071 }
4072 }
4073 }
4074 }
4075 if (m_restoring)
4076 {
4077 uint64_t estimate_height = m_wallet->estimate_blockchain_height();
4078 if (m_restore_height >= estimate_height)
4079 {
4080 success_msg_writer() << tr("Restore height ") << m_restore_height << (" is not yet reached. The current estimated height is ") << estimate_height;
4081 std::string confirm = input_line(tr("Still apply restore height?"), true);
4082 if (std::cin.eof() || command_line::is_no(confirm))
4083 m_restore_height = 0;
4084 }
4085 m_wallet->set_refresh_from_block_height(m_restore_height);
4086 }
4087 m_wallet->rewrite(m_wallet_file, password);
4088 }
4089 else // OPENING A WALLET FROM A WALLET FILE
4090 {
4091 assert(!m_wallet_file.empty());
4092 if (!m_subaddress_lookahead.empty())
4093 {
4094 fail_msg_writer() << tr("can't specify --subaddress-lookahead and --wallet-file at the same time");
4095 return false;
4096 }
4097 auto r = open_wallet(vm);
4098 CHECK_AND_ASSERT_MES(r, false, tr("failed to open account"));
4099 password = *r;
4100 }
4101 if (!m_wallet)
4102 {
4103 fail_msg_writer() << tr("wallet is null");
4104 return false;
4105 }
4106
4107 if (!m_wallet->is_trusted_daemon())
4108 message_writer() << (boost::format(tr("Warning: using an untrusted daemon at %s, privacy will be lessened")) % m_wallet->get_daemon_address()).str();
4109
4110 if (m_wallet->get_ring_database().empty())
4111 fail_msg_writer() << tr("Failed to initialize ring database: privacy enhancing features will be inactive");
4112
4113 m_wallet->callback(this);
4114
4115 check_background_mining(password);
4116
4117 if (welcome)
4118 message_writer(console_color_yellow, true) << tr("If you are new to Electroneum, type \"welcome\" for a brief overview.");
4119
4120 /* Comment out this warning message for now
4121 if (m_long_payment_id_support)
4122 {
4123 message_writer(console_color_red, false) <<
4124 tr("WARNING: obsolete long payment IDs are enabled. Sending transactions with those payment IDs are bad for your privacy.");
4125 message_writer(console_color_red, false) <<
4126 tr("It is recommended that you do not use them, and ask recipients who ask for one to not endanger your privacy.");
4127 }
4128 */
4129
4130 return true;
4131}
bool hex_to_pod(T &pod) const
const char * data() const noexcept
bool empty() const noexcept
size_t size() const noexcept
static bool has_testnet_option(const boost::program_options::variables_map &vm)
Definition wallet2.cpp:1173
static std::pair< std::unique_ptr< wallet2 >, password_container > make_from_json(const boost::program_options::variables_map &vm, bool unattended, const std::string &json_file, const std::function< boost::optional< password_container >(const char *, bool)> &password_prompter)
Uses stdin and stdout. Returns a wallet2 if no errors.
Definition wallet2.cpp:1227
static bool has_stagenet_option(const boost::program_options::variables_map &vm)
Definition wallet2.cpp:1178
#define MAKE_CORE_RPC_VERSION(major, minor)
void sc_reduce32(unsigned char *)
void sc_add(unsigned char *, const unsigned char *, const unsigned char *)
const char * key
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
bool is_no(const std::string &str)
bool is_yes(const std::string &str)
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
bool words_to_bytes(const epee::wipeable_string &words, epee::wipeable_string &dst, size_t len, bool duplicate, std::string &language_name)
Converts seed words to bytes (secret key).
epee::mlocked< tools::scrubbed< ec_scalar > > secret_key
Definition crypto.h:82
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height)
POD_CLASS public_key
Definition crypto.h:79
bool secret_key_to_public_key(const secret_key &sec, public_key &pub)
Definition crypto.h:262
POD_CLASS hash
Definition hash.h:50
bool get_account_address_from_str(address_parse_info &info, network_type nettype, std::string const &str)
crypto::secret_key decrypt_key(crypto::secret_key key, const epee::wipeable_string &passphrase)
std::string blobdata
boost::shared_ptr< call_befor_die_base > auto_scope_leave_caller
auto_scope_leave_caller create_scope_leave_handler(t_scope_leave_handler f)
T & unwrap(mlocked< T > &src)
Definition mlocker.h:80
@ console_color_yellow
scoped_message_writer fail_msg_writer()
scoped_message_writer msg_writer(epee::console_colors color=epee::console_color_default)
boost::optional< std::pair< uint32_t, uint32_t > > parse_subaddress_lookahead(const std::string &str)
Definition util.cpp:977
scoped_message_writer success_msg_writer(bool color=true)
CXA_THROW_INFO_T * info
unsigned short uint16_t
Definition stdint.h:125
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
Here is the call graph for this function:
Here is the caller graph for this function:

◆ interrupt()

void simple_wallet::interrupt ( )

Definition at line 9567 of file simplewallet.cpp.

9568{
9569 if (m_in_manual_refresh.load(std::memory_order_relaxed))
9570 {
9571 m_wallet->stop();
9572 }
9573 else
9574 {
9575 stop();
9576 }
9577}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_command()

bool simple_wallet::process_command ( const std::vector< std::string > & args)

Definition at line 9562 of file simplewallet.cpp.

9563{
9564 return m_cmd_binder.process_command_vec(args);
9565}
Here is the caller graph for this function:

◆ run()

bool simple_wallet::run ( )

Definition at line 8428 of file simplewallet.cpp.

8429{
8430 // check and display warning, but go on anyway
8431 try_connect_to_daemon();
8432
8433 //initial refresh
8434 refresh_main(0, ResetNone, true);
8435
8436 m_auto_refresh_enabled = m_wallet->auto_refresh();
8437
8438 // Idle thread which scans if m_auto_refresh_enabled, and listens to daemon
8439 m_idle_thread = boost::thread([&]{wallet_idle_thread();});
8440
8441 message_writer(console_color_green, false) << "Background refresh thread started";
8442
8443 //Indefinitely runs and listens on commands until user says to close wallet or an exception is thrown
8444 return m_cmd_binder.run_handling([this](){return get_prompt();}, "");
8445}
@ console_color_green
Here is the caller graph for this function:

◆ stop()

void simple_wallet::stop ( )

Definition at line 8447 of file simplewallet.cpp.

8448{
8449 m_cmd_binder.stop_handling();
8450}
Here is the caller graph for this function:

◆ tr()

const char * cryptonote::simple_wallet::tr ( const char * str)
inlinestatic

Definition at line 70 of file simplewallet.h.

70{ return i18n_translate(str, "cryptonote::simple_wallet"); }
const char * i18n_translate(const char *s, const std::string &context)
Definition i18n.cpp:323
Here is the call graph for this function:
Here is the caller graph for this function:

◆ refresh_progress_reporter_t

friend class refresh_progress_reporter_t
friend

Definition at line 326 of file simplewallet.h.


The documentation for this class was generated from the following files:
  • /home/abuild/rpmbuild/BUILD/electroneum-5.1.3.1-build/electroneum-5.1.3.1/src/simplewallet/simplewallet.h
  • /home/abuild/rpmbuild/BUILD/electroneum-5.1.3.1-build/electroneum-5.1.3.1/src/simplewallet/simplewallet.cpp