diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 80cee87..9f990e3 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -173,7 +173,7 @@ set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION add_library(cryptonote_format_utils_basic STATIC IMPORTED) set_target_properties(cryptonote_format_utils_basic PROPERTIES IMPORTED_LOCATION - ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libcryptonote_format_utils_basic.a) + ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/wownero/libcryptonote_format_utils_basic.a) ############# # System diff --git a/app/build.gradle b/app/build.gradle index a96b0ca..bd85723 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,7 +8,7 @@ android { applicationId "com.m2049r.wowwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 11010 + versionCode 1101000 versionName "2.1.1.0 'Vertant'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { diff --git a/app/src/main/cpp/monerujo.cpp b/app/src/main/cpp/monerujo.cpp index a1144d7..de0d068 100644 --- a/app/src/main/cpp/monerujo.cpp +++ b/app/src/main/cpp/monerujo.cpp @@ -191,12 +191,13 @@ struct MyWalletListener : Monero::WalletListener { /** * @brief refreshed - called when wallet refreshed by background thread or explicitly refreshed by calling "refresh" synchronously */ - void refreshed() { + void refreshed(bool success) { std::lock_guard lock(_listenerMutex); if (jlistener == nullptr) return; - LOGD("refreshed"); - JNIEnv *jenv; + LOGD("refreshed %s", success ? "true" : "false"); + if (!success) return; + JNIEnv *jenv; int envStat = attachJVM(&jenv); if (envStat == JNI_ERR) return; @@ -229,7 +230,7 @@ std::vector java2cpp(JNIEnv *env, jobject arrayList) { return result; } -jobject cpp2java(JNIEnv *env, const std::vector& vector) { +jobject cpp2java(JNIEnv *env, const std::vector &vector) { jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "", "(I)V"); jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add", @@ -506,8 +507,8 @@ Java_com_m2049r_xmrwallet_model_WalletManager_startMining(JNIEnv *env, jobject i const char *_address = env->GetStringUTFChars(address, nullptr); bool success = Monero::WalletManagerFactory::getWalletManager()->startMining(std::string(_address), - background_mining, - ignore_battery); + background_mining, + ignore_battery); env->ReleaseStringUTFChars(address, _address); return static_cast(success); } @@ -538,7 +539,7 @@ Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instan jobject walletInstance) { Monero::Wallet *wallet = getHandle(env, walletInstance); bool closeSuccess = Monero::WalletManagerFactory::getWalletManager()->closeWallet(wallet, - false); + false); if (closeSuccess) { MyWalletListener *walletListener = getHandle(env, walletInstance, "listenerHandle"); @@ -937,9 +938,9 @@ Java_com_m2049r_xmrwallet_model_Wallet_createTransactionJ(JNIEnv *env, jobject i Monero::Wallet *wallet = getHandle(env, instance); Monero::PendingTransaction *tx = wallet->createTransaction(_dst_addr, _payment_id, - amount, (uint32_t) mixin_count, - _priority, - (uint32_t) accountIndex); + amount, (uint32_t) mixin_count, + _priority, + (uint32_t) accountIndex); env->ReleaseStringUTFChars(dst_addr, _dst_addr); env->ReleaseStringUTFChars(payment_id, _payment_id); @@ -962,9 +963,9 @@ Java_com_m2049r_xmrwallet_model_Wallet_createSweepTransaction(JNIEnv *env, jobje Monero::optional empty; Monero::PendingTransaction *tx = wallet->createTransaction(_dst_addr, _payment_id, - empty, (uint32_t) mixin_count, - _priority, - (uint32_t) accountIndex); + empty, (uint32_t) mixin_count, + _priority, + (uint32_t) accountIndex); env->ReleaseStringUTFChars(dst_addr, _dst_addr); env->ReleaseStringUTFChars(payment_id, _payment_id); @@ -1174,7 +1175,7 @@ Java_com_m2049r_xmrwallet_model_Wallet_getLastSubaddress(JNIEnv *env, jobject in JNIEXPORT jint JNICALL Java_com_m2049r_xmrwallet_model_TransactionHistory_getCount(JNIEnv *env, jobject instance) { Monero::TransactionHistory *history = getHandle(env, - instance); + instance); return history->count(); } @@ -1241,7 +1242,7 @@ jobject newTransactionInfo(JNIEnv *env, Monero::TransactionInfo *info) { #include #include -jobject cpp2java(JNIEnv *env, const std::vector& vector) { +jobject cpp2java(JNIEnv *env, const std::vector &vector) { jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "", "(I)V"); jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add", @@ -1260,7 +1261,7 @@ jobject cpp2java(JNIEnv *env, const std::vector& vect JNIEXPORT jobject JNICALL Java_com_m2049r_xmrwallet_model_TransactionHistory_refreshJ(JNIEnv *env, jobject instance) { Monero::TransactionHistory *history = getHandle(env, - instance); + instance); history->refresh(); return cpp2java(env, history->getAll()); } diff --git a/external-libs/VERSION b/external-libs/VERSION index 0fd2fe9..aecc1cd 100644 --- a/external-libs/VERSION +++ b/external-libs/VERSION @@ -1 +1 @@ -MONERUJO_wownero master with wownero wonerujo +MONERUJO_wownero feature-v0.10 with wownero wonerujo-v0.10.1.0 diff --git a/external-libs/include/wallet2_api.h b/external-libs/include/wallet2_api.h index 72ff19c..0edeaae 100644 --- a/external-libs/include/wallet2_api.h +++ b/external-libs/include/wallet2_api.h @@ -66,6 +66,47 @@ enum NetworkType : uint8_t { bool set; }; +/* + * @brief Transaction construction data + */ +struct TransactionConstructionInfo +{ + struct Input { + Input(uint64_t _amount, const std::string &_pubkey); + const uint64_t amount; + const std::string pubkey; + }; + + struct Output { + Output(uint64_t _amount, const std::string &_address); + const uint64_t amount; + const std::string address; + }; + + virtual ~TransactionConstructionInfo() = 0; + virtual uint64_t unlockTime() const = 0; + virtual std::set subaddressIndices() const = 0; + virtual std::vector subaddresses() const = 0; + virtual uint64_t minMixinCount() const = 0; + virtual std::vector inputs() const = 0; + virtual std::vector outputs() const = 0; +}; + + +/* +* @brief Detailed pending transaction information +*/ +struct PendingTransactionInfo +{ + virtual ~PendingTransactionInfo() = 0; + virtual uint64_t fee() const = 0; + virtual uint64_t dust() const = 0; + virtual bool dustAddedToFee() const = 0; + virtual std::string txKey() const = 0; + virtual TransactionConstructionInfo * constructionData() const = 0; +}; + + /** * @brief Transaction-like interface for sending money */ @@ -101,6 +142,13 @@ struct PendingTransaction virtual uint64_t txCount() const = 0; virtual std::vector subaddrAccount() const = 0; virtual std::vector> subaddrIndices() const = 0; + virtual std::string unsignedTxToBin() const = 0; + virtual std::string unsignedTxToBase64() const = 0; + virtual std::string signedTxToHex(int index) const = 0; + virtual size_t signedTxSize(int index) const = 0; + virtual PendingTransactionInfo * transaction(int index) const = 0; + virtual void refresh() = 0; + virtual std::vector getAll() const = 0; /** * @brief multisigSignData @@ -160,6 +208,9 @@ struct UnsignedTransaction * return - true on success */ virtual bool sign(const std::string &signedFileName) = 0; + virtual void refresh() = 0; + virtual std::vector getAll() const = 0; + virtual TransactionConstructionInfo * transaction(int index) const = 0; }; /** @@ -198,6 +249,7 @@ struct TransactionInfo virtual std::string paymentId() const = 0; //! only applicable for output transactions virtual const std::vector & transfers() const = 0; + virtual const std::vector>> & rings() const = 0; }; /** * @brief The TransactionHistory - interface for displaying transaction history @@ -260,22 +312,66 @@ struct AddressBook virtual int lookupPaymentID(const std::string &payment_id) const = 0; }; +/** + * @brief The CoinsInfo - interface for displaying coins information + */ +struct CoinsInfo +{ + virtual ~CoinsInfo() = 0; + + virtual uint64_t blockHeight() const = 0; + virtual std::string hash() const = 0; + virtual size_t internalOutputIndex() const = 0; + virtual uint64_t globalOutputIndex() const = 0; + virtual bool spent() const = 0; + virtual bool frozen() const = 0; + virtual uint64_t spentHeight() const = 0; + virtual uint64_t amount() const = 0; + virtual bool rct() const = 0; + virtual bool keyImageKnown() const = 0; + virtual size_t pkIndex() const = 0; + virtual uint32_t subaddrIndex() const = 0; + virtual uint32_t subaddrAccount() const = 0; + virtual std::string address() const = 0; + virtual std::string addressLabel() const = 0; + virtual std::string keyImage() const = 0; + virtual uint64_t unlockTime() const = 0; + virtual bool unlocked() const = 0; + virtual std::string pubKey() const = 0; + virtual bool coinbase() const = 0; +}; + +struct Coins +{ + virtual ~Coins() = 0; + virtual int count() const = 0; + virtual CoinsInfo * coin(int index) const = 0; + virtual std::vector getAll() const = 0; + virtual void refresh() = 0; + virtual void setFrozen(int index) = 0; + virtual void thaw(int index) = 0; + virtual bool isTransferUnlocked(uint64_t unlockTime, uint64_t blockHeight) = 0; +}; + struct SubaddressRow { public: - SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label): + SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label, bool _used): m_rowId(_rowId), m_address(_address), - m_label(_label) {} + m_label(_label), + m_used(_used) {} private: std::size_t m_rowId; std::string m_address; std::string m_label; + bool m_used; public: std::string extra; std::string getAddress() const {return m_address;} std::string getLabel() const {return m_label;} std::size_t getRowId() const {return m_rowId;} + bool isUsed() const {return m_used;} }; struct Subaddress @@ -382,7 +478,7 @@ struct WalletListener /** * @brief refreshed - called when wallet refreshed by background thread or explicitly refreshed by calling "refresh" synchronously */ - virtual void refreshed() = 0; + virtual void refreshed(bool success) = 0; /** * @brief called by device if the action is required @@ -460,6 +556,7 @@ struct Wallet virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; }; virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; }; virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0; + virtual bool subaddressIndex(std::string address, std::pair &index) const = 0; std::string mainAddress() const { return address(0, 0); } virtual std::string path() const = 0; virtual NetworkType nettype() const = 0; @@ -869,6 +966,18 @@ struct Wallet uint32_t subaddr_account = 0, std::set subaddr_indices = {}) = 0; + /*! + * \brief createTransactionSingle creates transaction with single input + * \param key_image key image as string + * \param dst_addr destination address as string + * \param priority + * \return PendingTransaction object. caller is responsible to check PendingTransaction::status() + * after object returned + */ + + virtual PendingTransaction * createTransactionSingle(const std::string &key_image, const std::string &dst_addr, + size_t outputs = 1, PendingTransaction::Priority = PendingTransaction::Priority_Low) = 0; + /*! * \brief createSweepUnmixableTransaction creates transaction with unmixable outputs. * \return PendingTransaction object. caller is responsible to check PendingTransaction::status() @@ -883,7 +992,27 @@ struct Wallet * after object returned */ virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0; - + + /*! + * \brief loadUnsignedTx - creates transaction from unsigned tx string + * \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() + * after object returned + */ + virtual UnsignedTransaction * loadUnsignedTxFromStr(const std::string &unsigned_tx) = 0; + + /*! + * \brief loadUnsignedTx - creates transaction from unsigned base64 encoded tx string + * \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() + * after object returned + */ + virtual UnsignedTransaction * loadUnsignedTxFromBase64Str(const std::string &unsigned_tx_base64) = 0; + + /*! + * \brief loadSignedTx - creates transaction from signed tx file + * \return - PendingTransaction object. + */ + virtual PendingTransaction * loadSignedTx(const std::string &signed_filename) = 0; + /*! * \brief submitTransaction - submits transaction in signed tx file * \return - true on success @@ -934,8 +1063,29 @@ struct Wallet */ virtual bool importOutputs(const std::string &filename) = 0; + virtual bool importTransaction(const std::string &txid, std::vector &o_indices, uint64_t height, uint8_t block_version, uint64_t ts, bool miner_tx, bool pool, bool double_spend_seen) = 0; + + virtual std::string printBlockchain() = 0; + virtual std::string printTransfers() = 0; + virtual std::string printPayments() = 0; + virtual std::string printUnconfirmedPayments() = 0; + virtual std::string printConfirmedTransferDetails() = 0; + virtual std::string printUnconfirmedTransferDetails() = 0; + virtual std::string printPubKeys() = 0; + virtual std::string printTxNotes() = 0; + virtual std::string printSubaddresses() = 0; + virtual std::string printSubaddressLabels() = 0; + virtual std::string printAdditionalTxKeys() = 0; + virtual std::string printAttributes() = 0; + virtual std::string printKeyImages() = 0; + virtual std::string printAccountTags() = 0; + virtual std::string printTxKeys() = 0; + virtual std::string printAddressBook() = 0; + virtual std::string printScannedPoolTxs() = 0; + virtual TransactionHistory * history() = 0; virtual AddressBook * addressBook() = 0; + virtual Coins * coins() = 0; virtual Subaddress * subaddress() = 0; virtual SubaddressAccount * subaddressAccount() = 0; virtual void setListener(WalletListener *) = 0; @@ -992,9 +1142,10 @@ struct Wallet /* * \brief signMessage - sign a message with the spend private key * \param message - the message to sign (arbitrary byte data) - * \return the signature + * \param address - the address to make the signature with, defaults to primary address (optional) + * \return the signature, empty string if the address is invalid or does not belong to the wallet */ - virtual std::string signMessage(const std::string &message, const std::string &address = "") = 0; + virtual std::string signMessage(const std::string &message) = 0; /*! * \brief verifySignedMessage - verify a signature matches a given message * \param message - the message (arbitrary byte data) @@ -1086,15 +1237,6 @@ struct Wallet //! shows address on device display virtual void deviceShowAddress(uint32_t accountIndex, uint32_t addressIndex, const std::string &paymentId) = 0; - - //! attempt to reconnect to hardware device - virtual bool reconnectDevice() = 0; - - //! get bytes received - virtual uint64_t getBytesReceived() = 0; - - //! get bytes sent - virtual uint64_t getBytesSent() = 0; }; /** @@ -1202,6 +1344,25 @@ struct WalletManager return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString); } + /*! + * \brief recover deterministic wallet from spend key. + * \param path Name of wallet file to be created + * \param password Password of wallet file + * \param language language + * \param nettype Network type + * \param restoreHeight restore from start height + * \param spendKeyString spend key + * \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 * createDeterministicWalletFromSpendKey(const std::string &path, + const std::string &password, + const std::string &language, + NetworkType nettype, + uint64_t restoreHeight, + const std::string &spendKeyString, + uint64_t kdf_rounds = 1) = 0; + /*! * \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted @@ -1373,3 +1534,6 @@ struct WalletManagerFactory } + +namespace Bitmonero = Monero; +