From 9b1751463546683d7ddf1b46bbb915383ceda93c Mon Sep 17 00:00:00 2001 From: Dylan Seago Date: Thu, 10 Jan 2019 15:12:41 -0500 Subject: [PATCH 1/4] Switch to v0.13.0.4 --- Makefile | 7 +-- include/wallet2_api.h | 100 +++++++++++++++++++++++++++++++++++++++--- src/addon.cc | 2 +- 3 files changed, 98 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 4d63abd..3af8780 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,11 @@ -MONERO_BRANCH?="release-v0.12-multisig-wallet-assembled" +MONERO_BRANCH?="v0.13.0.4" MONERO_BUILD_TYPE?=Release BOOST_VERSION=1.66.0 BOOST_DIRNAME=boost_1_66_0 PWD=${shell pwd} -BOOST_LIBS=chrono,date_time,filesystem,program_options,regex,serialization,system,thread +BOOST_LIBS=chrono,date_time,filesystem,program_options,regex,serialization,system,thread,locale THREADS?=1 .PHONY: all @@ -39,7 +39,7 @@ deps: boost monero/build cp boost/lib/*.a deps monero: - git clone --depth 1 --recurse-submodules -b ${MONERO_BRANCH} https://github.com/exantech/monero + git clone --depth 1 --recurse-submodules -b ${MONERO_BRANCH} https://github.com/monero-project/monero cp monero/src/wallet/api/wallet2_api.h include monero/build: boost monero @@ -52,6 +52,7 @@ monero/build: boost monero -DCMAKE_POSITION_INDEPENDENT_CODE:BOOL=true \ -DCMAKE_ARCHIVE_OUTPUT_DIRECTORY=${PWD}/deps \ -DEMBEDDED_WALLET=1 \ + -DMANUAL_SUBMODULES=1 \ .. cd monero/build && make -j${THREADS} wallet_merged epee easylogging lmdb unbound VERBOSE=1 diff --git a/include/wallet2_api.h b/include/wallet2_api.h index 5b99bd9..ec1a848 100644 --- a/include/wallet2_api.h +++ b/include/wallet2_api.h @@ -373,6 +373,10 @@ struct WalletListener */ struct Wallet { + enum Device { + Device_Software = 0, + Device_Ledger = 1 + }; enum Status { Status_Ok, @@ -509,6 +513,21 @@ struct Wallet */ virtual void setRecoveringFromSeed(bool recoveringFromSeed) = 0; + /*! + * \brief setRecoveringFromDevice - set state to recovering from device + * + * \param recoveringFromDevice - true/false + */ + virtual void setRecoveringFromDevice(bool recoveringFromDevice) = 0; + + /*! + * \brief setSubaddressLookahead - set size of subaddress lookahead + * + * \param major - size fot the major index + * \param minor - size fot the minor index + */ + virtual void setSubaddressLookahead(uint32_t major, uint32_t minor) = 0; + /** * @brief connectToDaemon - connects to the daemon. TODO: check if it can be removed * @return @@ -687,6 +706,12 @@ struct Wallet * @return in case of N / N wallets returns empty string since no more key exchanges needed. For N - 1 / N wallets returns base58 encoded extra multisig info */ virtual std::string makeMultisig(const std::vector& info, uint32_t threshold) = 0; + /** + * @brief exchange_multisig_keys - provides additional key exchange round for arbitrary multisig schemes (like N-1/N, M/N) + * @param info - base58 encoded key derivations returned by makeMultisig or exchangeMultisigKeys function call + * @return new info string if more rounds required or an empty string if wallet creation is done + */ + virtual std::string exchangeMultisigKeys(const std::vector &info) = 0; /** * @brief finalizeMultisig - finalizes N - 1 / N multisig wallets creation * @param extraMultisigInfo - wallet participants' extra multisig info obtained with makeMultisig call @@ -705,6 +730,11 @@ struct Wallet * @return number of imported images */ virtual size_t importMultisigImages(const std::vector& images) = 0; + /** + * @brief hasMultisigPartialKeyImages - checks if wallet needs to import multisig key images from other participants + * @return true if there are partial key images + */ + virtual bool hasMultisigPartialKeyImages() const = 0; /** * @brief restoreMultisigTransaction creates PendingTransaction from signData @@ -857,10 +887,13 @@ struct Wallet virtual bool rescanSpent() = 0; //! blackballs a set of outputs - virtual bool blackballOutputs(const std::vector &pubkeys, bool add) = 0; + virtual bool blackballOutputs(const std::vector &outputs, bool add) = 0; + + //! blackballs an output + virtual bool blackballOutput(const std::string &amount, const std::string &offset) = 0; //! unblackballs an output - virtual bool unblackballOutput(const std::string &pubkey) = 0; + virtual bool unblackballOutput(const std::string &amount, const std::string &offset) = 0; //! gets the ring used for a key image, if any virtual bool getRing(const std::string &key_image, std::vector &ring) const = 0; @@ -885,6 +918,18 @@ struct Wallet //! Initiates a light wallet import wallet request virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) = 0; + + //! locks/unlocks the keys file; returns true on success + virtual bool lockKeysFile() = 0; + virtual bool unlockKeysFile() = 0; + //! returns true if the keys file is locked + virtual bool isKeysFileLocked() = 0; + + /*! + * \brief Queries backing device for wallet keys + * \return Device they are on + */ + virtual Device getDeviceType() const = 0; }; /** @@ -899,9 +944,10 @@ struct WalletManager * \param password Password of wallet file * \param language Language to be used to generate electrum seed mnemonic * \param nettype Network type + * \param kdf_rounds Number of rounds for key derivation function * \return Wallet instance (Wallet::status() needs to be called to check if created successfully) */ - virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype) = 0; + virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) = 0; Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet = false) // deprecated { return createWallet(path, password, language, testnet ? TESTNET : MAINNET); @@ -912,9 +958,10 @@ struct WalletManager * \param path Name of wallet file * \param password Password of wallet file * \param nettype Network type + * \param kdf_rounds Number of rounds for key derivation function * \return Wallet instance (Wallet::status() needs to be called to check if opened successfully) */ - virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype) = 0; + virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1) = 0; Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated { return openWallet(path, password, testnet ? TESTNET : MAINNET); @@ -927,10 +974,11 @@ struct WalletManager * \param mnemonic mnemonic (25 words electrum seed) * \param nettype Network type * \param restoreHeight restore from start height + * \param kdf_rounds Number of rounds for key derivation function * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic, - NetworkType nettype = MAINNET, uint64_t restoreHeight = 0) = 0; + NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1) = 0; Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic, bool testnet = false, uint64_t restoreHeight = 0) // deprecated { @@ -962,6 +1010,7 @@ struct WalletManager * \param addressString public address * \param viewKeyString view key * \param spendKeyString spend key (optional) + * \param kdf_rounds Number of rounds for key derivation function * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ virtual Wallet * createWalletFromKeys(const std::string &path, @@ -971,7 +1020,8 @@ struct WalletManager uint64_t restoreHeight, const std::string &addressString, const std::string &viewKeyString, - const std::string &spendKeyString = "") = 0; + const std::string &spendKeyString = "", + uint64_t kdf_rounds = 1) = 0; Wallet * createWalletFromKeys(const std::string &path, const std::string &password, const std::string &language, @@ -1014,6 +1064,25 @@ struct WalletManager return createWalletFromKeys(path, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString); } + /*! + * \brief creates wallet using hardware device. + * \param path Name of wallet file to be created + * \param password Password of wallet file + * \param nettype Network type + * \param deviceName Device name + * \param restoreHeight restore from start height (0 sets to current height) + * \param subaddressLookahead Size of subaddress lookahead (empty sets to some default low value) + * \param kdf_rounds Number of rounds for key derivation function + * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) + */ + virtual Wallet * createWalletFromDevice(const std::string &path, + const std::string &password, + NetworkType nettype, + const std::string &deviceName, + uint64_t restoreHeight = 0, + const std::string &subaddressLookahead = "", + uint64_t kdf_rounds = 1) = 0; + /*! * \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted * \param wallet previously opened / created wallet instance @@ -1037,9 +1106,26 @@ struct WalletManager * @param keys_file_name - location of keys file * @param password - password to verify * @param no_spend_key - verify only view keys? + * @param kdf_rounds - number of rounds for key derivation function * @return - true if password is correct + * + * @note + * This function will fail when the wallet keys file is opened because the wallet program locks the keys file. + * In this case, Wallet::unlockKeysFile() and Wallet::lockKeysFile() need to be called before and after the call to this function, respectively. + */ + virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0; + + /*! + * \brief determine the key storage for the specified wallet file + * \param device_type (OUT) wallet backend as enumerated in Wallet::Device + * \param keys_file_name Keys file to verify password for + * \param password Password to verify + * \return true if password correct, else false + * + * for verification only - determines key storage hardware + * */ - virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key) const = 0; + virtual bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const = 0; /*! * \brief findWallets - searches for the wallet files by given path name recursively diff --git a/src/addon.cc b/src/addon.cc index 8bc9d1a..3b50dca 100644 --- a/src/addon.cc +++ b/src/addon.cc @@ -2,7 +2,7 @@ #include "wallet.h" #include "pendingtransaction.h" -extern void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size = 104850000); +extern void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size = 104850000, const std::size_t max_log_files = 4); extern void mlog_set_log(const char *log); From c46a0323cc0cbd3b64542595c2983d84ed2fc5a9 Mon Sep 17 00:00:00 2001 From: Dylan Seago Date: Wed, 30 Jan 2019 11:29:02 -0500 Subject: [PATCH 2/4] Update readme with list of prerequisite dependencies --- README.md | 41 ++++++++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2752111..9fcd33b 100644 --- a/README.md +++ b/README.md @@ -15,24 +15,51 @@ If `npm` couldn't find proper binaries for your platform please refer to [manual # Manual Build If you want to build the addon manually or there are no prebuilt binaries for your platform in `npm` repository please check the [official monero guide](https://github.com/monero-project/monero#compiling-monero-from-source) on how to satisfy all the dependencies. After that you may compile the addon following these steps: -Checkout the repository: +## Install prerequisites + +Start with node dependencies: + ```sh -$ git clone https://github.com/exantech/monero-nodejs-libwallet +npm install ``` -Install prerequisites (example for ubuntu below) +### OSX + ```sh -$ sudo apt-get install libpcsclite-dev +brew install \ + git wget curl pcsc-lite \ + gcc cmake pkg-config boost openssl zeromq libpgm norm \ + unbound libsodium libunwind-headers xz readline ldns expat ``` -Run build: +### Ubuntu + ```sh -$ npm run build +sudo apt-get -y install \ + git wget curl python-software-properties libpcsclite-dev \ + build-essential cmake pkg-config libboost-dev libpcsclite-dev \ + libssl-dev libzmq3-dev libunwind8-dev liblzma-dev libsodium-dev libboost-all-dev \ + libreadline6-dev libldns-dev libexpat1-dev doxygen graphviz libgtest-dev cl-chipz \ ``` +## Checkout the repository + +```sh +git clone https://github.com/exantech/monero-nodejs-libwallet +``` + +## Run build + +```sh +make clean +npm run build +``` + +## Use build + Link your local build (using [`npm link`](https://docs.npmjs.com/cli/link) command): ```sh -$ npm link +npm link ``` Then, in your project directory: From 417129a5034120da099c231cd5fdf431aa8fcd42 Mon Sep 17 00:00:00 2001 From: Dylan Seago Date: Wed, 30 Jan 2019 15:40:27 -0500 Subject: [PATCH 3/4] Add -lsodium to binding gyp to fix build process --- binding.gyp | 1 + 1 file changed, 1 insertion(+) diff --git a/binding.gyp b/binding.gyp index 5d0d941..462f4ed 100644 --- a/binding.gyp +++ b/binding.gyp @@ -63,6 +63,7 @@ "<@(additional_libraries)", "-lssl", "-lcrypto", + "-lsodium", "-lz", ""], "include_dirs": [ From 38107559fa25c294a706effc78449cd7d29e4cc7 Mon Sep 17 00:00:00 2001 From: Dylan Seago Date: Thu, 31 Jan 2019 10:06:57 -0500 Subject: [PATCH 4/4] Build from exantech monero repo --- Makefile | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3af8780..73a0bdf 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -MONERO_BRANCH?="v0.13.0.4" +MONERO_BRANCH?="release-v0.13" +MONERO_REPO?=https://github.com/monero-project/monero + MONERO_BUILD_TYPE?=Release BOOST_VERSION=1.66.0 @@ -39,7 +41,7 @@ deps: boost monero/build cp boost/lib/*.a deps monero: - git clone --depth 1 --recurse-submodules -b ${MONERO_BRANCH} https://github.com/monero-project/monero + git clone --depth 1 --recurse-submodules -b ${MONERO_BRANCH} ${MONERO_REPO} cp monero/src/wallet/api/wallet2_api.h include monero/build: boost monero