From e82b471c149084043ecd637bc5bbe1e1bd164d58 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Sep 2021 21:23:12 +0200 Subject: [PATCH 01/18] adaptaions for monero v0.17.2.3 (#781) --- app/CMakeLists.txt | 5 ++++ build.gradle | 2 +- external-libs/VERSION | 2 +- external-libs/include/wallet2_api.h | 36 ++++++++++++++++++++++-- gradle/wrapper/gradle-wrapper.properties | 2 +- 5 files changed, 42 insertions(+), 5 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 80e07f78..a8b93d36 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -171,6 +171,10 @@ add_library(wallet-crypto STATIC IMPORTED) set_target_properties(wallet-crypto PROPERTIES IMPORTED_LOCATION ${EXTERNAL_LIBS_DIR}/${ANDROID_ABI}/monero/libwallet-crypto.a) +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) + ############# # System ############# @@ -193,6 +197,7 @@ target_link_libraries( monerujo wallet cryptonote_core cryptonote_basic + cryptonote_format_utils_basic mnemonics ringct ringct_basic diff --git a/build.gradle b/build.gradle index 4406443a..322ebf17 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.2' + classpath 'com.android.tools.build:gradle:7.0.2' } } diff --git a/external-libs/VERSION b/external-libs/VERSION index 8823154c..4aebddc9 100644 --- a/external-libs/VERSION +++ b/external-libs/VERSION @@ -1 +1 @@ -MONERUJO_monero master with monero release-v0.17.2.0-monerujo +MONERUJO_monero feature_v17.2.3 with monero release-v0.17.2.3-monerujo diff --git a/external-libs/include/wallet2_api.h b/external-libs/include/wallet2_api.h index 999823ff..0b8be83d 100644 --- a/external-libs/include/wallet2_api.h +++ b/external-libs/include/wallet2_api.h @@ -182,9 +182,11 @@ struct TransactionInfo virtual int direction() const = 0; virtual bool isPending() const = 0; virtual bool isFailed() const = 0; + virtual bool isCoinbase() const = 0; virtual uint64_t amount() const = 0; virtual uint64_t fee() const = 0; virtual uint64_t blockHeight() const = 0; + virtual std::string description() const = 0; virtual std::set subaddrIndex() const = 0; virtual uint32_t subaddrAccount() const = 0; virtual std::string label() const = 0; @@ -208,6 +210,7 @@ struct TransactionHistory virtual TransactionInfo * transaction(const std::string &id) const = 0; virtual std::vector getAll() const = 0; virtual void refresh() = 0; + virtual void setTxNote(const std::string &txid, const std::string ¬e) = 0; }; /** @@ -250,6 +253,7 @@ struct AddressBook virtual std::vector getAll() const = 0; virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0; virtual bool deleteRow(std::size_t rowId) = 0; + virtual bool setDescription(std::size_t index, const std::string &description) = 0; virtual void refresh() = 0; virtual std::string errorString() const = 0; virtual int errorCode() const = 0; @@ -442,7 +446,7 @@ struct Wallet }; virtual ~Wallet() = 0; - virtual std::string seed() const = 0; + virtual std::string seed(const std::string& seed_offset = "") const = 0; virtual std::string getSeedLanguage() const = 0; virtual void setSeedLanguage(const std::string &arg) = 0; //! returns wallet status (Status_Ok | Status_Error) @@ -452,6 +456,7 @@ struct Wallet //! returns both error and error string atomically. suggested to use in instead of status() and errorString() virtual void statusWithErrorString(int& status, std::string& errorString) const = 0; virtual bool setPassword(const std::string &password) = 0; + virtual const std::string& getPassword() const = 0; 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; @@ -622,6 +627,12 @@ struct Wallet */ virtual bool watchOnly() const = 0; + /** + * @brief isDeterministic - checks if wallet keys are deterministic + * @return - true if deterministic + */ + virtual bool isDeterministic() const = 0; + /** * @brief blockChainHeight - returns current blockchain height * @return @@ -897,9 +908,10 @@ struct Wallet /*! * \brief exportKeyImages - exports key images to file * \param filename + * \param all - export all key images or only those that have not yet been exported * \return - true on success */ - virtual bool exportKeyImages(const std::string &filename) = 0; + virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0; /*! * \brief importKeyImages - imports key images from file @@ -908,6 +920,19 @@ struct Wallet */ virtual bool importKeyImages(const std::string &filename) = 0; + /*! + * \brief importOutputs - exports outputs to file + * \param filename + * \return - true on success + */ + virtual bool exportOutputs(const std::string &filename, bool all = false) = 0; + + /*! + * \brief importOutputs - imports outputs from file + * \param filename + * \return - true on success + */ + virtual bool importOutputs(const std::string &filename) = 0; virtual TransactionHistory * history() = 0; virtual AddressBook * addressBook() = 0; @@ -995,6 +1020,7 @@ struct Wallet virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0; virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector &unknown_parameters, std::string &error) = 0; + virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const = 0; virtual std::string getDefaultDataDir() const = 0; @@ -1003,6 +1029,12 @@ struct Wallet * \return true on success */ virtual bool rescanSpent() = 0; + + /* + * \brief setOffline - toggle set offline on/off + * \param offline - true/false + */ + virtual void setOffline(bool offline) = 0; //! blackballs a set of outputs virtual bool blackballOutputs(const std::vector &outputs, bool add) = 0; diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 3c4101c3..29e41345 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 148faa00e48eb21945c13138d87b0af52ac43844 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Sep 2021 21:24:53 +0200 Subject: [PATCH 02/18] minor fixes for confirmations indicator (#782) --- .../xmrwallet/layout/TransactionInfoAdapter.java | 10 ++++------ .../com/m2049r/xmrwallet/model/TransactionInfo.java | 6 ++++++ app/src/main/res/layout/item_transaction.xml | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java index 835c3a14..da218804 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java @@ -49,8 +49,6 @@ import java.util.TimeZone; import timber.log.Timber; public class TransactionInfoAdapter extends RecyclerView.Adapter { - private final static int MAX_CONFIRMATIONS = 10; - private final static SimpleDateFormat DATETIME_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm"); private final int outboundColour; @@ -81,7 +79,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter 0) && (infoItems.get(0).confirmations < MAX_CONFIRMATIONS); + return (infoItems.size() > 0) && !infoItems.get(0).isConfirmed(); } private static class TransactionInfoDiff extends DiffCallback { @@ -169,7 +167,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter { + public static final int CONFIRMATION = 10; // blocks + @RequiredArgsConstructor public enum Direction { Direction_In(0), @@ -98,6 +100,10 @@ public class TransactionInfo implements Parcelable, Comparable this.transfers = transfers; } + public boolean isConfirmed() { + return confirmations >= CONFIRMATION; + } + public String getDisplayLabel() { if (subaddressLabel.isEmpty() || (Subaddress.DEFAULT_LABEL_FORMATTER.matcher(subaddressLabel).matches())) return ("#" + addressIndex); diff --git a/app/src/main/res/layout/item_transaction.xml b/app/src/main/res/layout/item_transaction.xml index c9e55d71..e2107019 100644 --- a/app/src/main/res/layout/item_transaction.xml +++ b/app/src/main/res/layout/item_transaction.xml @@ -48,7 +48,7 @@ Date: Sun, 5 Sep 2021 21:42:55 +0200 Subject: [PATCH 03/18] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 9a8a6f46..01173414 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1008 - versionName "2.0.8 'Puginarug'" + versionCode 1100 + versionName "2.1.0 'Vertant'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { From 84ec1ef418e4c2f852e01a792579c2f97133e738 Mon Sep 17 00:00:00 2001 From: m2049r Date: Wed, 8 Sep 2021 13:52:23 +0200 Subject: [PATCH 04/18] load notes on refresh (#783) --- .../com/m2049r/xmrwallet/WalletFragment.java | 4 ++-- .../xmrwallet/layout/TransactionInfoAdapter.java | 2 +- .../xmrwallet/model/TransactionHistory.java | 16 ++++------------ .../java/com/m2049r/xmrwallet/model/Wallet.java | 6 +++++- .../m2049r/xmrwallet/service/WalletService.java | 4 ++-- 5 files changed, 14 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java index c1e53cd5..35a93981 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java @@ -349,14 +349,14 @@ public class WalletFragment extends Fragment Timber.d("onRefreshed(%b)", full); if (adapter.needsTransactionUpdateOnNewBlock()) { - wallet.getHistory().refresh(); + wallet.refreshHistory(); full = true; } if (full) { List list = new ArrayList<>(); final long streetHeight = activityCallback.getStreetModeHeight(); Timber.d("StreetHeight=%d", streetHeight); - wallet.getHistory().refresh(); + wallet.refreshHistory(); for (TransactionInfo info : wallet.getHistory().getAll()) { Timber.d("TxHeight=%d, Label=%s", info.blockheight, info.subaddressLabel); if ((info.isPending || (info.blockheight >= streetHeight)) diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java index da218804..f7c4f936 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/TransactionInfoAdapter.java @@ -100,7 +100,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter transactions = new ArrayList<>(); - public void refreshWithNotes(Wallet wallet) { + void refreshWithNotes(Wallet wallet) { refresh(); loadNotes(wallet); } -// public void refresh() { -// transactions = refreshJ(); -// } - - public void refresh() { + private void refresh() { List transactionInfos = refreshJ(); - Timber.d("refreshed %d", transactionInfos.size()); + Timber.d("refresh size=%d", transactionInfos.size()); for (Iterator iterator = transactionInfos.iterator(); iterator.hasNext(); ) { TransactionInfo info = iterator.next(); if (info.accountIndex != accountIndex) { iterator.remove(); - Timber.d("removed %s", info.hash); - } else { - Timber.d("kept %s", info.hash); } } transactions = transactionInfos; } private native List refreshJ(); - } diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java index 6653418f..47df8e08 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java @@ -398,6 +398,10 @@ public class Wallet { private native long getHistoryJ(); + public void refreshHistory() { + getHistory().refreshWithNotes(this); + } + //virtual AddressBook * addressBook() const = 0; //virtual void setListener(WalletListener *) = 0; @@ -462,7 +466,7 @@ public class Wallet { public void setSubaddressLabel(int addressIndex, String label) { setSubaddressLabel(accountIndex, addressIndex, label); - getHistory().refreshWithNotes(this); + refreshHistory(); } public native void setSubaddressLabel(int accountIndex, int addressIndex, String label); diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java index 876c944c..65bf9ef4 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java @@ -124,7 +124,7 @@ public class WalletService extends Service { if (!wallet.isSynchronized()) { updated = true; // we want to see our transactions as they come in - wallet.getHistory().refresh(); + wallet.refreshHistory(); int txCount = wallet.getHistory().getCount(); if (txCount > lastTxCount) { // update the transaction list only if we have more than before @@ -152,7 +152,7 @@ public class WalletService extends Service { wallet.setSynchronized(); if (updated) { updateDaemonState(wallet, wallet.getBlockChainHeight()); - wallet.getHistory().refreshWithNotes(wallet); + wallet.refreshHistory(); if (observer != null) { updated = !observer.onRefreshed(wallet, true); } From ac70ba84248887853677cb958547ea23ddc1a054 Mon Sep 17 00:00:00 2001 From: m2049r Date: Wed, 8 Sep 2021 13:53:57 +0200 Subject: [PATCH 05/18] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 01173414..8d0a7475 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1100 - versionName "2.1.0 'Vertant'" + versionCode 1101 + versionName "2.1.1 'Vertant'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { From f07b439731838a8522db764e5da66a3994d1e888 Mon Sep 17 00:00:00 2001 From: m2049r Date: Tue, 26 Oct 2021 17:36:03 +0200 Subject: [PATCH 06/18] correct settleAmount formatting for non-US locales (#791) --- app/build.gradle | 2 -- .../sideshift/network/RequestQuoteImpl.java | 20 +++++++++++++------ build.gradle | 8 +------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8d0a7475..629dd6c1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -141,8 +141,6 @@ dependencies { implementation 'org.slf4j:slf4j-nop:1.7.30' implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2' - implementation 'com.github.aelstad:keccakj:1.1.0' - testImplementation "junit:junit:$rootProject.ext.junitVersion" testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion" testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0" diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java index c87465e6..1cbdf24c 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/RequestQuoteImpl.java @@ -20,21 +20,21 @@ import androidx.annotation.NonNull; import com.m2049r.xmrwallet.service.shift.NetworkCallback; import com.m2049r.xmrwallet.service.shift.ShiftApiCall; -import com.m2049r.xmrwallet.util.DateHelper; -import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote; -import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi; import com.m2049r.xmrwallet.service.shift.ShiftCallback; +import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote; +import com.m2049r.xmrwallet.util.DateHelper; import com.m2049r.xmrwallet.util.ServiceHelper; import org.json.JSONException; import org.json.JSONObject; import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.ParseException; import java.util.Date; +import java.util.Locale; import lombok.Getter; -import timber.log.Timber; class RequestQuoteImpl implements RequestQuote { @Getter @@ -101,7 +101,7 @@ class RequestQuoteImpl implements RequestQuote { /** * Create JSON request object * - * @param xmrAmount how much XMR to shift to BTC + * @param btcAmount how much XMR to shift to BTC */ static JSONObject createRequest(final double btcAmount) throws JSONException { @@ -114,5 +114,13 @@ class RequestQuoteImpl implements RequestQuote { return jsonObject; } - static DecimalFormat AmountFormatter = new DecimalFormat("#.############"); + static final DecimalFormat AmountFormatter; + + static { + AmountFormatter = new DecimalFormat(); + AmountFormatter.setDecimalFormatSymbols(new DecimalFormatSymbols(Locale.US)); + AmountFormatter.setMinimumIntegerDigits(1); + AmountFormatter.setMaximumFractionDigits(12); + AmountFormatter.setGroupingUsed(false); + } } diff --git a/build.gradle b/build.gradle index 322ebf17..90d708d5 100644 --- a/build.gradle +++ b/build.gradle @@ -6,19 +6,13 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:7.0.2' + classpath 'com.android.tools.build:gradle:7.0.3' } } allprojects { repositories { mavenCentral() - maven { - url "https://maven.google.com" - } - maven { - url "https://repository.mulesoft.org/nexus/content/repositories/public/" - } google() } } From 506e6ce0175dc33d15b477a189dcaa7885d4ec6d Mon Sep 17 00:00:00 2001 From: m2049r Date: Wed, 27 Oct 2021 08:37:52 +0200 Subject: [PATCH 07/18] bump version --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 629dd6c1..d0912531 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1101 - versionName "2.1.1 'Vertant'" + versionCode 1102 + versionName "2.1.2 'Vertant'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { From ce9046c7b50c3997e095d2b685afa67f7654b5ec Mon Sep 17 00:00:00 2001 From: Francesco Fusco Date: Wed, 1 Dec 2021 21:36:22 +0100 Subject: [PATCH 08/18] Update italian translation --- app/src/main/res/values-it/help.xml | 21 +++--- app/src/main/res/values-it/strings.xml | 88 +++++++++++++------------- 2 files changed, 54 insertions(+), 55 deletions(-) diff --git a/app/src/main/res/values-it/help.xml b/app/src/main/res/values-it/help.xml index 659114e6..ad07df03 100644 --- a/app/src/main/res/values-it/help.xml +++ b/app/src/main/res/values-it/help.xml @@ -148,13 +148,12 @@

Questo è l'indirizzo pubblico del portafoglio cui stai inviando Moneroj, puoi incollare qui un indirizzo che hai precededentemente copiato sul blocco appunti, scansionare un codice QR o inserire un indirizzo manualmente. Accertati più volte che sia l'indirizzo corretto e che tu non stia inviando Moneroj ad un indirizzo sbagliato.

-

In addition to using an XMR address, you can also use +

In alternativa a un indirizzo XMR, puoi anche usare

    -
  • an OpenAlias for XMR or BTC
  • -
  • a BTC address
  • +
  • un OpenAlias per XMR o BTC
  • +
  • un indirizzo BTC
  • - Please note, that sending BTC is processed through the SideShift.ai service (see https://sideshift.ai - for details). See the section on sending BTC below.

    + L'invio di BTC è processato tramite il servizio SideShift.ai. (per dettagli: https://sideshift.ai). Vedi la sezione sull'invio di BTC in basso.

    Inviare BTC

    SideShift.ai

    SideShift.ai è un servizio di terze parti che funziona come cambiavaluta da Monero a Bitcoin. @@ -285,14 +284,14 @@ Using a payment link -

    You have started monerujo with a payment link. In order to send funds, please do the following:

    +

    Uso di un link di pagamento

    +

    Hai avviato monerujo con un link di pagamento. Per inviare fondi, procedi in questo modo:

    - 1. Open the wallet you want to spend from
    - 2. Wait until the wallet is synced & the "Give" button appears
    - 3. Touch the "Give" button + 1. Apri il portafogli da cui vuoi spendere
    + 2. Attendi la sincronizzazione del portafogli; apparirà il pulsante "Invia"
    + 3. Tocca il pulsante "Invia"

    -

    The payment details will be filled in. Check them and proceed like for any other transaction.

    +

    I dettagli del pagamento saranno auto-inseriti. Controllali e procedi come per qualsiasi altra transazione.

    ]]> Got it! diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 1712f4d7..3b9b7888 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -362,73 +362,73 @@ Altezza di ripristino - Start Monero App on %1$s + Avvia app Monero su %1$s - Rescan! + Riscansiona! Ho capito! Next - I\'m ready! + Sono pronto! - Welcome to Monerujo! - This app allows you to create and use Monero wallets. You can store your sweet moneroj in them. - Keep your seed safe - The seed grants full access to whoever has it. If you lose it, we cannot help you recover it and you lose your beloved moneroj. - Send Crypto - Monerujo has SideShift.ai support built-in. Just paste or scan a BTC, LTC, ETH, DASH or DOGE address and you\'ll be sending these cryptos by spending XMR. - Nodes, your way - Nodes connect you to the Monero network. Choose between public nodes or go full cypherpunk using your own. - Send with fingerprint - You\'re now able to send XMR with just your fingerprint if you enabled it. To request the password, just disable fingerprint access. + Benvenuto su Monerujo! + Questa app ti permette di creare ed usare portafogli di Monero. Puoi conservare i tuoi bei moneroj all'interno. + Tieni al sicuro il tuo seed + Il seed permette l'accesso al portafogli a chiunque lo abbia. Se lo perdi, non possiamo aiutarti a recuperarlo. + Invia altre crypto + Monerujo supporta SideShift.ai. Copia o scansiona un indirizzo BTC, LTC, ETH, DASH o DOGE per inviare una di queste crypto spendendo XMR. + Nodi, a modo tuo + I nodi ti connettono alla rete di Monero. Scegli tra i vari nodi pubblici oppure usa il tuo. + Invia con impronta + Ora puoi inviare XMR con la tua impronta digitale. Per richiedere la password, disabilita l\'accesso all\'impronta. - Dark Mode + Modalità scura Auto - Day - Night + Giorno + Notte - There is nothing here\nPlease create or restore a wallet + Non c\'è niente qui\n Crea o ripristina un portafogli - Restore default nodes - Restoring already in progress… + Ripristina i nodi predefiniti + Ripristino già in corso… - Last Block: %1$d seconds ago - Last Block: %1$d minutes ago - Last Block: %1$d hours ago - Last Block: %1$d days ago + Ultimo blocco: %1$d secondi fa + Ultimo blocco: %1$d minuti fa + Ultimo blocco: %1$d ore fa + Ultimo blocco: %1$d giorni fa - Cannot get quote - Check amount and try again + Impossibile ottenere la quota + Controlla l\'ammontare e riprova Ambiguous address.
    - Please select the type above. + Indirizzo ambiguo.
    + Si prega di inserire il tipo selezionato. ]]>
    Please enter or scan a %1$s address.
    - You'll send XMR and the receiver will get %2$s using the SideShift.ai service. + Inserisci o scansiona un indirizzo %1$s.
    + Invierai XMR e il destinatario otterrà %2$s tramite il servizio SideShift.ai. ]]>
    Please enter or scan a Monero address. + Inserisci o scansiona un indirizzo di Monero. ]]> - Subaddresses - Subaddress Name - Too many unused addresses - use some to enable creating more! - Too many unused accounts - use some to enable creating more! - Transactions for this subaddress: - No transactions for this subaddress yet - Select a subaddress - Long-press for details + Sottoindirizzi + Nome sottoindirizzo + Troppi indirizzi non usati - usane qualcuno per poterne creare altri! + Troppi account non usati - usane qualcuno per poterne creare altri! + Transazioni per questo sottoindirizzo: + Nessuna transazione per questo sottoindirizzo + Seleziona un sottoindirizzo + Tieni premuto per i dettagli - Delete - Delete failed! + Elimina + Eliminazione fallita! - Import wallet - Import failed! + Importa portafogli + Importazione fallita! - Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + Resetta portafogli! + Il reset del portafogli cancellerà tutte le informazioni locali (note, nomi di account & sottoindirizzi, chiavi di transazione private, ...)! Procedi solo se il portafogli è corrotto e non si carica! From 27885f2c8630653a6c5dc6e4ce142a7a0e4f4518 Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Dec 2021 18:10:25 +0100 Subject: [PATCH 09/18] create wallet only by button & refactoring (#793) --- .../m2049r/xmrwallet/GenerateFragment.java | 310 ++++++++---------- 1 file changed, 128 insertions(+), 182 deletions(-) diff --git a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java index 079956fc..3048318d 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java @@ -16,6 +16,8 @@ package com.m2049r.xmrwallet; +import androidx.annotation.NonNull; + import android.app.Activity; import android.content.Context; import android.content.DialogInterface; @@ -56,6 +58,7 @@ import com.m2049r.xmrwallet.widget.Toolbar; import java.io.File; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Objects; import timber.log.Timber; @@ -120,134 +123,96 @@ public class GenerateFragment extends Fragment { etWalletViewKey.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); etWalletSpendKey.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); - etWalletName.getEditText().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - checkName(); - } + etWalletName.getEditText().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + checkName(); } }); clearErrorOnTextEntry(etWalletName); - etWalletMnemonic.getEditText().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - checkMnemonic(); - } + etWalletMnemonic.getEditText().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + checkMnemonic(); } }); clearErrorOnTextEntry(etWalletMnemonic); - etWalletAddress.getEditText().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - checkAddress(); - } + etWalletAddress.getEditText().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + checkAddress(); } }); clearErrorOnTextEntry(etWalletAddress); - etWalletViewKey.getEditText().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - checkViewKey(); - } + etWalletViewKey.getEditText().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + checkViewKey(); } }); clearErrorOnTextEntry(etWalletViewKey); - etWalletSpendKey.getEditText().setOnFocusChangeListener(new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus) { - checkSpendKey(); - } + etWalletSpendKey.getEditText().setOnFocusChangeListener((v, hasFocus) -> { + if (!hasFocus) { + checkSpendKey(); } }); clearErrorOnTextEntry(etWalletSpendKey); - Helper.showKeyboard(getActivity()); + Helper.showKeyboard(requireActivity()); - etWalletName.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) - || (actionId == EditorInfo.IME_ACTION_NEXT)) { - if (checkName()) { - etWalletPassword.requestFocus(); - } // otherwise ignore - return true; - } - return false; + etWalletName.getEditText().setOnEditorActionListener((v, actionId, event) -> { + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) + || (actionId == EditorInfo.IME_ACTION_NEXT)) { + if (checkName()) { + etWalletPassword.requestFocus(); + } // otherwise ignore + return true; } + return false; }); if (FingerprintHelper.isDeviceSupported(getContext())) { llFingerprintAuth.setVisibility(View.VISIBLE); final SwitchMaterial swFingerprintAllowed = (SwitchMaterial) llFingerprintAuth.getChildAt(0); - swFingerprintAllowed.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - if (!swFingerprintAllowed.isChecked()) return; + swFingerprintAllowed.setOnClickListener(view1 -> { + if (!swFingerprintAllowed.isChecked()) return; - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity()); - builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn))) - .setCancelable(false) - .setPositiveButton(getString(R.string.label_ok), null) - .setNegativeButton(getString(R.string.label_cancel), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - swFingerprintAllowed.setChecked(false); - } - }) - .show(); - } + MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireActivity()); + builder.setMessage(Html.fromHtml(getString(R.string.generate_fingerprint_warn))) + .setCancelable(false) + .setPositiveButton(getString(R.string.label_ok), null) + .setNegativeButton(getString(R.string.label_cancel), (dialogInterface, i) -> swFingerprintAllowed.setChecked(false)) + .show(); }); } - if (type.equals(TYPE_NEW)) { - etWalletPassword.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE); - etWalletPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) - || (actionId == EditorInfo.IME_ACTION_DONE)) { - Helper.hideKeyboard(getActivity()); - generateWallet(); - return true; - } - return false; - } - }); - } else if (type.equals(TYPE_LEDGER)) { - etWalletPassword.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE); - etWalletPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + switch (type) { + case TYPE_NEW: + etWalletPassword.getEditText().setImeOptions(EditorInfo.IME_ACTION_UNSPECIFIED); + break; + case TYPE_LEDGER: + etWalletPassword.getEditText().setImeOptions(EditorInfo.IME_ACTION_DONE); + etWalletPassword.getEditText().setOnEditorActionListener((v, actionId, event) -> { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) || (actionId == EditorInfo.IME_ACTION_DONE)) { etWalletRestoreHeight.requestFocus(); return true; } return false; - } - }); - } else if (type.equals(TYPE_SEED)) { - etWalletPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + }); + break; + case TYPE_SEED: + etWalletPassword.getEditText().setOnEditorActionListener((v, actionId, event) -> { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) || (actionId == EditorInfo.IME_ACTION_NEXT)) { etWalletMnemonic.requestFocus(); return true; } return false; - } - }); - etWalletMnemonic.setVisibility(View.VISIBLE); - etWalletMnemonic.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + }); + etWalletMnemonic.setVisibility(View.VISIBLE); + etWalletMnemonic.getEditText().setOnEditorActionListener((v, actionId, event) -> { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) || (actionId == EditorInfo.IME_ACTION_NEXT)) { if (checkMnemonic()) { @@ -256,22 +221,20 @@ public class GenerateFragment extends Fragment { return true; } return false; - } - }); - } else if (type.equals(TYPE_KEY) || type.equals(TYPE_VIEWONLY)) { - etWalletPassword.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + }); + break; + case TYPE_KEY: + case TYPE_VIEWONLY: + etWalletPassword.getEditText().setOnEditorActionListener((v, actionId, event) -> { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) || (actionId == EditorInfo.IME_ACTION_NEXT)) { etWalletAddress.requestFocus(); return true; } return false; - } - }); - etWalletAddress.setVisibility(View.VISIBLE); - etWalletAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + }); + etWalletAddress.setVisibility(View.VISIBLE); + etWalletAddress.getEditText().setOnEditorActionListener((v, actionId, event) -> { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) || (actionId == EditorInfo.IME_ACTION_NEXT)) { if (checkAddress()) { @@ -280,11 +243,9 @@ public class GenerateFragment extends Fragment { return true; } return false; - } - }); - etWalletViewKey.setVisibility(View.VISIBLE); - etWalletViewKey.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + }); + etWalletViewKey.setVisibility(View.VISIBLE); + etWalletViewKey.getEditText().setOnEditorActionListener((v, actionId, event) -> { if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) || (actionId == EditorInfo.IME_ACTION_NEXT)) { if (checkViewKey()) { @@ -297,44 +258,29 @@ public class GenerateFragment extends Fragment { return true; } return false; - } - }); + }); + break; } if (type.equals(TYPE_KEY)) { etWalletSpendKey.setVisibility(View.VISIBLE); - etWalletSpendKey.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) - || (actionId == EditorInfo.IME_ACTION_NEXT)) { - if (checkSpendKey()) { - etWalletRestoreHeight.requestFocus(); - } - return true; + etWalletSpendKey.getEditText().setOnEditorActionListener((v, actionId, event) -> { + if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) + || (actionId == EditorInfo.IME_ACTION_NEXT)) { + if (checkSpendKey()) { + etWalletRestoreHeight.requestFocus(); } - return false; + return true; } + return false; }); } if (!type.equals(TYPE_NEW)) { etWalletRestoreHeight.setVisibility(View.VISIBLE); - etWalletRestoreHeight.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN)) - || (actionId == EditorInfo.IME_ACTION_DONE)) { - Helper.hideKeyboard(getActivity()); - generateWallet(); - return true; - } - return false; - } - }); + etWalletRestoreHeight.getEditText().setImeOptions(EditorInfo.IME_ACTION_UNSPECIFIED); } - bGenerate.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Helper.hideKeyboard(getActivity()); - generateWallet(); - } + bGenerate.setOnClickListener(v -> { + Helper.hideKeyboard(getActivity()); + generateWallet(); }); etWalletName.requestFocus(); @@ -387,7 +333,7 @@ public class GenerateFragment extends Fragment { SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd"); parser.setLenient(false); height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight)); - } catch (ParseException ex) { + } catch (ParseException ignored) { } if ((height < 0) && (restoreHeight.length() == 8)) try { @@ -395,7 +341,7 @@ public class GenerateFragment extends Fragment { SimpleDateFormat parser = new SimpleDateFormat("yyyyMMdd"); parser.setLenient(false); height = RestoreHeight.getInstance().getHeight(parser.parse(restoreHeight)); - } catch (ParseException ex) { + } catch (ParseException ignored) { } if (height < 0) try { @@ -466,40 +412,46 @@ public class GenerateFragment extends Fragment { long height = getHeight(); if (height < 0) height = 0; - if (type.equals(TYPE_NEW)) { - bGenerate.setEnabled(false); - if (fingerprintAuthAllowed) { - KeyStoreHelper.saveWalletUserPass(getActivity(), name, password); - } - activityCallback.onGenerate(name, crazyPass); - } else if (type.equals(TYPE_SEED)) { - if (!checkMnemonic()) return; - String seed = etWalletMnemonic.getEditText().getText().toString(); - bGenerate.setEnabled(false); - if (fingerprintAuthAllowed) { - KeyStoreHelper.saveWalletUserPass(getActivity(), name, password); - } - activityCallback.onGenerate(name, crazyPass, seed, height); - } else if (type.equals(TYPE_LEDGER)) { - bGenerate.setEnabled(false); - if (fingerprintAuthAllowed) { - KeyStoreHelper.saveWalletUserPass(getActivity(), name, password); - } - activityCallback.onGenerateLedger(name, crazyPass, height); - } else if (type.equals(TYPE_KEY) || type.equals(TYPE_VIEWONLY)) { - if (checkAddress() && checkViewKey() && checkSpendKey()) { + switch (type) { + case TYPE_NEW: bGenerate.setEnabled(false); - String address = etWalletAddress.getEditText().getText().toString(); - String viewKey = etWalletViewKey.getEditText().getText().toString(); - String spendKey = ""; - if (type.equals(TYPE_KEY)) { - spendKey = etWalletSpendKey.getEditText().getText().toString(); - } if (fingerprintAuthAllowed) { - KeyStoreHelper.saveWalletUserPass(getActivity(), name, password); + KeyStoreHelper.saveWalletUserPass(requireActivity(), name, password); } - activityCallback.onGenerate(name, crazyPass, address, viewKey, spendKey, height); - } + activityCallback.onGenerate(name, crazyPass); + break; + case TYPE_SEED: + if (!checkMnemonic()) return; + String seed = etWalletMnemonic.getEditText().getText().toString(); + bGenerate.setEnabled(false); + if (fingerprintAuthAllowed) { + KeyStoreHelper.saveWalletUserPass(requireActivity(), name, password); + } + activityCallback.onGenerate(name, crazyPass, seed, height); + break; + case TYPE_LEDGER: + bGenerate.setEnabled(false); + if (fingerprintAuthAllowed) { + KeyStoreHelper.saveWalletUserPass(requireActivity(), name, password); + } + activityCallback.onGenerateLedger(name, crazyPass, height); + break; + case TYPE_KEY: + case TYPE_VIEWONLY: + if (checkAddress() && checkViewKey() && checkSpendKey()) { + bGenerate.setEnabled(false); + String address = etWalletAddress.getEditText().getText().toString(); + String viewKey = etWalletViewKey.getEditText().getText().toString(); + String spendKey = ""; + if (type.equals(TYPE_KEY)) { + spendKey = etWalletSpendKey.getEditText().getText().toString(); + } + if (fingerprintAuthAllowed) { + KeyStoreHelper.saveWalletUserPass(requireActivity(), name, password); + } + activityCallback.onGenerate(name, crazyPass, address, viewKey, spendKey, height); + } + break; } } @@ -552,7 +504,7 @@ public class GenerateFragment extends Fragment { } @Override - public void onAttach(Context context) { + public void onAttach(@NonNull Context context) { super.onAttach(context); if (context instanceof GenerateFragment.Listener) { this.activityCallback = (GenerateFragment.Listener) context; @@ -595,7 +547,7 @@ public class GenerateFragment extends Fragment { public void convertLedgerSeed() { if (ledgerDialog != null) return; - final Activity activity = getActivity(); + final Activity activity = requireActivity(); View promptsView = getLayoutInflater().inflate(R.layout.prompt_ledger_seed, null); MaterialAlertDialogBuilder alertDialogBuilder = new MaterialAlertDialogBuilder(activity); alertDialogBuilder.setView(promptsView); @@ -620,26 +572,20 @@ public class GenerateFragment extends Fragment { ledgerDialog = alertDialogBuilder.create(); - ledgerDialog.setOnShowListener(new DialogInterface.OnShowListener() { - @Override - public void onShow(DialogInterface dialog) { - Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - String ledgerSeed = etSeed.getEditText().getText().toString(); - String ledgerPassphrase = etPassphrase.getEditText().getText().toString(); - String moneroSeed = Monero.convert(ledgerSeed, ledgerPassphrase); - if (moneroSeed != null) { - etWalletMnemonic.getEditText().setText(moneroSeed); - ledgerDialog.dismiss(); - ledgerDialog = null; - } else { - etSeed.setError(getString(R.string.bad_ledger_seed)); - } - } - }); - } + ledgerDialog.setOnShowListener(dialog -> { + Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE); + button.setOnClickListener(view -> { + String ledgerSeed = etSeed.getEditText().getText().toString(); + String ledgerPassphrase = etPassphrase.getEditText().getText().toString(); + String moneroSeed = Monero.convert(ledgerSeed, ledgerPassphrase); + if (moneroSeed != null) { + etWalletMnemonic.getEditText().setText(moneroSeed); + ledgerDialog.dismiss(); + ledgerDialog = null; + } else { + etSeed.setError(getString(R.string.bad_ledger_seed)); + } + }); }); if (Helper.preventScreenshot()) { From 729fafdb481a95c02c54955a2155031e70ec973c Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Dec 2021 18:59:26 +0100 Subject: [PATCH 10/18] fix apostrophes --- app/src/main/res/values-it/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 3b9b7888..ab128ab6 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -371,9 +371,9 @@ Sono pronto! Benvenuto su Monerujo! - Questa app ti permette di creare ed usare portafogli di Monero. Puoi conservare i tuoi bei moneroj all'interno. + Questa app ti permette di creare ed usare portafogli di Monero. Puoi conservare i tuoi bei moneroj all\'interno. Tieni al sicuro il tuo seed - Il seed permette l'accesso al portafogli a chiunque lo abbia. Se lo perdi, non possiamo aiutarti a recuperarlo. + Il seed permette l\'accesso al portafogli a chiunque lo abbia. Se lo perdi, non possiamo aiutarti a recuperarlo. Invia altre crypto Monerujo supporta SideShift.ai. Copia o scansiona un indirizzo BTC, LTC, ETH, DASH o DOGE per inviare una di queste crypto spendendo XMR. Nodi, a modo tuo From 9f0e89719c9553bbae2093bb13b96157ca70dd0c Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Dec 2021 19:00:10 +0100 Subject: [PATCH 11/18] remove arabic (#795) --- app/src/main/res/values-ar/about.xml | 48 --- app/src/main/res/values-ar/help.xml | 215 ------------- app/src/main/res/values-ar/strings.xml | 418 ------------------------- 3 files changed, 681 deletions(-) delete mode 100644 app/src/main/res/values-ar/about.xml delete mode 100644 app/src/main/res/values-ar/help.xml delete mode 100644 app/src/main/res/values-ar/strings.xml diff --git a/app/src/main/res/values-ar/about.xml b/app/src/main/res/values-ar/about.xml deleted file mode 100644 index 1d6b13fc..00000000 --- a/app/src/main/res/values-ar/about.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - أغلق - أنا مونيرويو - النسخة %1$s (%2$d) - - الاعتمادات -
    - m2049r, baltsar777, anhdres, keejef, - rehrar, EarlOfEgo, ErCiccione et al. -

    - monerujo.io - ]]>
    - - سياسة الخصوصية -

    - هذه الصفحة تخبرك بسياستنا بخصوص التجميع، الاستخدام، و الافصاح عن المعلومات الشخصيةالتي نستلمها من مستخدمي تطبيقنا (مونيرويو: محفظة مونيرو) -

    -

    باستخدامك هذا التطبيق أنت توافق تجميع و استخدام المعلومات وفقاً لهذه السياسة -

    -

    البيانات المجمعة

    -

    المعلومات الشخصية هي نوع من البيانات التي قد تعرف هوية شخص ما -

    -

    مفاتيح مونيرو و العناوين العامة مجمعة و معالجة من قبل التطبيق محليا لغرض معالجة المعاملات و هي ترسل الى شبكة مونيرو في حالة مشفرة -

    -

    لا يجمع التطبيق أي معلومات شخصية أخرى

    -

    إذا أنت تستخدم خدمة الصراف (اختياري)، مونيرويو يجلب سعر الصرف عبر api coinmarketcap.com. اطلع على سياسة الخصوصية الخاصة بهم على https://coinmarketcap.com/privacy لتفاصيل على كيف تجمع بياناتك التي في الطلب.

    -

    عندما تستعمل التطبيق لتدفع إلى عنوانين بيتكوين، فأنت تستعمل خدمة SideShift.ai. اطلع على سياسة الخصوصية الخاصة بهم على https://sideshift.ai للتفاصيل. يرسل مونيرويو عنوان بيتوين و المبلغ إليهم. سيأخذ أيضاً عنوان بروتوكول الإنترنت (ip) الخاص بك.

    -

    صلاحيات التطبيق

    -
      -
    • الإنترنت: للإتصال بشبكة مونيرو عبر عقدة مونيرو
    • -
    • قرائة ملفات التخزين الخارجي: لقرائة ملفات المحفظة المخزنة على الجهاز
    • -
    • الكتابة إلى التخزين الخارجي: لكتابة ملفات المحفظة المخزنة على الجهاز
    • -
    • قفل الإيقاظ: لإبقاء الجهاز ياقظاً عند التزامن
    • -
    • الكاميرا: لمسح رموز الاستجابة السريعة (qr) لاستلام مونيرو
    • -
    -

    التغيرات لسياسة الخصوصية هذه

    -

    . يمكن أن نحدث سياسة الخصوصية هذه من حين إلى أخرى. سنقوم بتنبيهك لأاي تغيرات بنشر سياسة الخصوصية الجديدة في التطبيق و على الموقع (www.monerujo.io) - ننصحك أن تراجع هذه السياسة بشكل دوري لأاي تغيرات -

    آخر تحديث لسياسة الخصوصية هذه كان في 10/11/2017 -

    -

    تواصل معنا

    -

    privacy@monerujo.io.إذا كان لديك أي سؤال عن سياستنا أو عن كيفية تجميع بياناتك و معالجتها، الرجاء إرسال بريد الكتروني إلى -

    - ]]>
    -
    diff --git a/app/src/main/res/values-ar/help.xml b/app/src/main/res/values-ar/help.xml deleted file mode 100644 index 3d69d577..00000000 --- a/app/src/main/res/values-ar/help.xml +++ /dev/null @@ -1,215 +0,0 @@ - - - أنشئ محفظة - جديدة -

    إذا كنت تحتاج إلى عنوان مونيرو جديد!

    -

    أدخل اسم محفظة و كلمة سر فريدين. - كلمة المرور مستخدمة لتأمين بيانات محفظتك على الجهاز. استخدم كلمة سر قوية - و استخدام عبارة سر أفضل.

    -

    دون البذرة الذاكرية!

    -

    سترى في الشاشة التالية \"البذرة الذاكرية\" ذات 25 كلمة خاصة بك. هي كل ما تحتاجه لاسترجاع محفظتك لاحقاً و الحصول على وصول كامل لمالك. - إبقائها آمنة و خاصة مهم جداً، فهي تعطي أي أحد وصولاً كاملاً لمالك!

    -

    إذا نسيت كلمة مرور محفظتك يمكنك استرجاع محفظتك باستعمال بذرة الذاكرة.

    -

    ليس هناك طريقة لاسترجاع البذرة الذاكرية، إذا أضعتها ضاع مالك! - أيضاً، لا يمكن لبذرة الذاكرية أن تتغير و إذا ما سرقت أو انفضحت، - عليك أن تحول مالك إلى محفظة جديدة (مع بذرة ذاكرية جديدة). لذا من - الأفضل عمل نسخ احتياطية من بذرتك بكتابتها و تخزينها في أكثر من - مكان آمن

    - ]]>
    - - أنشئ محفظة - بذرة -

    إذا لديك عنوان مونيرو و تريد استعادة المعاملات من سلسلة الكتل!

    -

    أدخل اسم محفظة و كلمة سر فريدين. - كلمة المرور مستخدمة لتأمين بيانات محفظتك على الجهاز. استخدم كلمة سر قوية - و استخدام عبارة سر أفضل.

    -

    أدخل بذرتك في حقل \"البذرة الذاكيرة\".

    -

    أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

    - ]]>
    - - أنشئ محفظة - لدجر -

    إذا كنت تسترجع محفظتك من جهاز لدجر نانو اس.

    -

    مفاتيحك السرية لا تغادر جهاز لدجر، لذا تجتاج إلى توصيله كلما أردت الوصول لمحفظتك.

    -

    أدخل اسم محفظة و كلمة سر فريدين. كلمة المرور مستخدمة لتأمين بيانات محفظتك على جهاز الأندرويد. استخدم كلمة سر قوية - واستخدام عبارة سر أفضل.

    -

    أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

    - ]]>
    - - أنشئ محفظة - مفاتيح -

    إذا كنت تسترجع محفظتك باستخدام مفاتيحك!

    -

    أدخل اسم محفظة و كلمة سر فريدين. كلمة المرور مستخدمة لتأمين بيانات محفظتك على جهاز الأندرويد. استخدم كلمة سر قوية - واستخدام عبارة سر أفضل.

    -

    أدخل عنوان مونيرو في حقل \"العنوان العام\" و عبئ \"مفتاح الرؤية\" و \"مفتاح الانفاق\".

    -

    أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

    - ]]>
    - - أنشئ محفظة - رؤية -

    إذا كنت تريد مراقبة المعاملات القادمة إلى المحفظة!

    -

    أدخل اسم محفظة و كلمة سر فريدين. كلمة المرور مستخدمة لتأمين بيانات محفظتك على جهاز الأندرويد. استخدم كلمة سر قوية - واستخدام عبارة سر أفضل.

    -

    أدخل عنوان مونيرو ملكك في حقل "\عنوان عام"\ و املأ \مفتاح الرؤية"\".

    -

    أدخل رقم الكتلة لأول معاملة لهذا العنوان في حقل \""\. يمكنك أيضاًاستعمال تاريخ في صيغة سسسس-شش-يي. إن لم تكن متأكداً أدخل تاريخ/كتلة تقريبي(ة) قبل استخدامك الأول لهذا العنوان.

    - ]]>
    - - تفاصيل المحفظة -

    العنوان العام

    - عنوانك العام بمثابة رقم حسابك البنكي يمكنك مشاركته مع أي أحد دون خوف من خسارة مونيرو الخاص بك. يرسل الناس المونيرو إلى محفظتك باستخدام هذا العنوان. -

    البذرة الذاكرية

    - هي كل ما تحتاجه لاسترجاع محفظتك و الحصول على وصول كامل لمالك. إبقائها خاصة و آمنة مهم جداًَ، فهي تعطي لي أحد وصولاً كاملاً لمونيرواتك! إذا لم تكتبها في مكان آمن رجاءً افعل! -

    كلمة مرور استرجاع ملفات المحفظة

    - تأكد من تدوين كلمة المرور هذه. ستحتاج إليها إذا أعدت ضبط جهازك أو ألغيت تثبيت التطبيق.
    -

    CrAzYpass

    - إذا كانت كلمة المرور المعروضة هنا هي أبجدية رقمية من 52 جزء في مجموعات من 4 - تهانينا! - ملفات محفظتك مؤمنة باستخدام مفتاح 256 بت مولد باستخدام خصائص أمان جهازك - أساساً على عبارة المرور التي خترتها (عند الإنشاء أو بتغييرها). هذا يجعلها صعبة جداً للاختراق!
    - هذه الميزة اجبارية لكل المحافظ الجديدة. -

    كلمة السر القديمة

    - إذا ترى عبارة مرورك هنا، محفظتك ليسب بأمان استخدام CrAzYpass. لإصلاح هذا فقط اختار \"غير كلمة المرور\" من القائمة. بعد إدخالك عبارة مرور جديدة (ربما نفسها القديمة) سيولد التطبيق CrAzYpass لك و سيؤمن ملفات محفظتك به. اكتبه! -

    CrAzYpass محافظ

    - إذا احبجت في أي وقت إلى إعادة تثبيت مونيرويو (بعد إعادة ضبط هاتفك أو التبديل إلى جهاز جديد مثلاً) أو إذا أردت استخدام ملفات المحفظة جهاز مختلف أو حاسوب، فيجب عليك استعمال كلمة المرور الاسترجاعية هذه للوصول إلى محفظتك مجدداً.
    - بإختيارك \"غير عبارة المرور\" من القاءمة، يمكنك اختيار عبارة مرور أخرى. انتبة أن هذا سيولد كلمة مرور استرجاعية جديدة. اكتبها! -

    مفتاح الرؤية

    - يمكنك استخدام مفتاح الرؤية الخاص بك لمراقبة المعاملات القادمة لمحفظتك دون اعطاء إذن لإنفاق المال داخل محفظتك. -

    مفتاح الإنفاق

    - مفتاح الانفاق الخاص بك يسمح لأي شحص بانفاق المونيرو المتعلق بمحفظتك، لذا لا تخبر أجداً بالمفتاح. أبقه آمناً كبذرة الذاكرية. - ]]>
    - - قائمة المحافظ -

    العقدة

    -

    .مونيرويو يستخدم عقدة بعيدة للاتصال بشبكة مونيرو دون الحاجة إلى تنزيل و الاحتفاظ بنسخة كاملة من سلسة الكتل. يمكنك العثور على قائمة من العقد الشائعة أو تعلم كيف تشغل عقدة خاصة بك هنا https://moneroworld.com

    -

    يأتي مونيرويو مع بعض العقد البعيدة المحددة مسبقاً. مونيرويو يتذكر آخر خمس عقد مستخدمة.

    - -

    المحافظ

    -

    هنا ترى محافظك. هن موجودات في مجلد monerujo في التخزين الداخلى لجهازك. - يمكنك استعمال تطبيق مستكشف ملفات لرؤيتهن. ينبغي عليك عمل نسخ احتياطية من هذا المجلد - على أسس منتظمة لتخزين خارج جهازك في حالة انفجاره أو سرقته

    -

    اختر محفظة لتفتحها أو المس زر \"+\" لإنشاء واحدة جديدة. أو اختر واحدة من عمليات المحفظة:

    -

    التفاصيل

    -

    أظهر تفاصيل المحفظة، البذرة و المفاتيح.

    -

    استلم

    -

    أنشئ رمز استجابة سريعة(qr code) لاستلام المونيرو.

    -

    أعد التسمية

    -

    أعد تسمية المحفظة. النسخ الاحتياطية لا تعاد التسمية.

    -

    نسخة احتياطية

    -

    أنشئ نسخة من المحفظة في مجلد backups داخل مجلد monerujo مستبدلة النسخ السابقة هناك.

    -

    أرشيف

    -

    أنشئ نسخة احتياطية ثم احذف المحفظة. النسخة تبقى في مجلد backups إذا لم تعد بحاجة إلى نسخك الاحتياطية ينبغي أن تحذفهم باستعمال متصفح ملفات أو تطبيق حذف آمن.

    - ]]>
    - - تفاصيل المعاملة -

    الوجهة

    - هذا هو العنوان العام للمحفظة التي تريد إرسال مونيرو إليها. -

    معرف الدفع

    - يمكنك استخدام معرف دفع لتعريف السبب لارسالك مونيرو بين طرفين. هذا اختياري - و خاص. فمثلاً يسمح لشركة بتسوية معاملتك مع غرض شريته. -

    TX ID

    - هذا هو معرف معاملتك. يمكنك استخدامه لتعريف معاملتك المشوشة في مستكشف سلسلة كتل مونيرو مثل https://xmrchain.net/ -

    TX KEY (مفتاح المعاملة)

    - هذا هو مفتاح معاملتك الخاص، أبقه آمناً فإظهاره إلى طرف ثالث يظهر أي توقيع في (حلقة/طوق/خاتم) هو الخاص بك، جاعلاً معاملاتك شفافة. -

    كتلة

    - هذه هي الكتلة التي تحتوي معاملتك. - ]]>
    - - أرسل -

    عنوان المستلم

    -

    هذا هو العنوان العام للمحفظة التي تريد إرسال مونيرو إليها، يمكنك نسخه من الحافظة - ، مسح رمز استجابة سريعة (QR) أو إدخاله يدوياً. تأكد من العنوان لضمان عدم الارسال إلى عنوان خطأ.

    -

    بالإضافة إلى عنوان مونيرو يمكنك استعمال -

      -
    • مفتوحة (OpenAlias) لXMR أو BTC
    • -
    • عنوان بيتكوين
    • - - يرجى ملاحظة أن إرسال BTC يتم من خلال خدمة Sideshift.ai (انظر https://sideshift.ai - للتفاصيل). راجع قسم إرسال BTC أدناه.

      -

      معرف الدفع

      -

      يمكنك استخدام معرف دفع لتعريف السبب لارسالك مونيرو بين طرفين. هذا اختياري - و خاص. فمثلاً يسمح لشركة بتسوية معاملتك مع غرض شريته

      -

      إرسال بيتكوين

      -

      SideShift.ai

      -

      Sideshift.ai خدمة طرف ثالث تعمل كصرافة من مونيرو إلى بيتكوين. نستخدم API Sideshift.ai لإدراج دفع بيتكوين في مونيرويو. رجاءاً اطلع على https://sideshift.ai و قرر لنفسك إذا ما كانت جدمة تريد استخدامها. فريق مونيرويو ليس مرتبطاً بSideshift.ai ولا يمكنه مساعدتك مع خدمتهم

      -

      SideShift.ai سعر صرف

      -

      في شاشة \"المبلغ\" ستعرض عليك الضوابط الحالية لخدمة Sideshift.ai - هذه الضوابط تتضمن سعر الصرف الحالي بالإضافة إلى حدود BTC الدنيا و العليا. لاحظ أن هذا السعر ليس مضموناً في هذه المرحلة

      -

      SideShift.ai طلب

      -

      في شاشة \"أكد\" سترى طلب Sideshift.ai الفعلي. هذا الطلب صحيح لفترة محدودة - قد تلاحظ عداًَ تنازلياً على زر \"spend\". قد يكون سعر الصرف مختلفاً عن السعر الدلالي في الشاشة السابقة

      -

      السري SideShift.ai مفتاح

      -

      لأن مونيرويو فقط يتعامل مع جزء مونيرو من معاملتك يمكن لمفتاح Sideshift.ai السري الخاص البك أن يستعل لتتبع جزء بيتكوين من طلبك على موقع Sideshift.ai

      -

      SideShift.ai عد تنازلي

      -

      عند وصول العد التنازلي إلى الصفر، تحتاج إلى الحصول على سعر جديد من Sideshift.ai بالرجوع إلى الخطوة السابقة ثم العودة إلى شاشة \"أكد\"

      - ]]> - - إرسال بيتكوين -

      SideShift.ai

      -

      Sideshift.ai خدمة طرف ثالث تعمل كصرافة من مونيرو إلى بيتكوين. نستخدم API Sideshift.ai لإدراج دفع بيتكوين في مونيرويو. رجاءاً اطلع على https://sideshift.ai و قرر لنفسك إذا ما كانت جدمة تريد استخدامها. فريق مونيرويو ليس مرتبطاً بSideshift.ai ولا يمكنه مساعدتك مع خدمتهم.

      -

      SideShift.ai سعر صرف

      -

      في شاشة \"المبلغ\" ستعرض عليك الضوابط الحالية لخدمة Sideshift.ai - هذه الضوابط تتضمن سعر الصرف الحالي بالإضافة إلى حدود BTC الدنيا و العليا. لاحظ أن هذا السعر ليس مضموناً في هذه المرحلة.

      -

      SideShift.ai طلب

      -

      في شاشة \"أكد\" سترى طلب Sideshift.ai الفعلي. هذا الطلب صحيح لفترة محدودة - قد تلاحظ عداًَ تنازلياً على زر \"spend\". قد يكون سعر الصرف مختلفاً عن السعر الدلالي في الشاشة السابقة.

      -

      السري SideShift.ai مفتاح

      -

      لأن مونيرويو فقط يتعامل مع جزء مونيرو من معاملتك يمكن لمفتاح Sideshift.ai السري الخاص البك أن يستعل لتتبع جزء بيتكوين من طلبك على موقع Sideshift.ai

      -

      التنازلي! SideShift.ai عد

      -

      عند وصول العد التنازلي إلى الصفر، تحتاج إلى الحصول على سعر جديد من Sideshift.ai بالرجوع إلى الخطوة السابقة ثم العودة إلى شاشة \"أكد\"

      - - المحفظة -

      وضع الشارع

      -

      - يمكنك تفعيل/تعطيل وضع الشارع في القائمة أو أيقونة رأس غونثر. في هذا الوضع، رصيدك لا يظهر على أي شاشة لذا يمكنك استخدام محفظتك بأمان في الشارع، القهوة، أو أي مكان عام. المعاملات السابقة أيضاً مخفية. ستعرض المعاملات الجديدة لترى أنك أرسلت/استلمت موينرو.

      -

      مسح

      - لأن مونيرو يحب إبقاء الأشياء خاصة، كل مرة تفتح محفظة موينيرويو علينا مسح سلسلة الكتل لنرى إذا ما أرسل مونيرة إلى محفظتك. أحياناً يستغرق فترةً لأنك لم تزامن منذ فترة طويلة. -

      الرصيد

      -

      النجدة! رصيد محفظتي اختفى أو هو غير مؤكد!
      - لا تفزع! عندما ترسل المال من محفظتك، بعض رصيدك سيظهر مؤقتاً كغير مؤكد. - يحصل نتيجةً لكيفية تبادل مونيرو على سلسلة الكتل و كيفية عمل الفكة. إقرأ أكثر عن الفكة على https://getmonero.org/resources/moneropedia/change.html -

      قائمة المعاملات

      -

      في محافظ الرؤية، فقط تعرض المعاملات القادمة.

      - ]]>
      - - العقد -

      المختصر المفيد

      -

      أعد تحميل قائمة العقد بالسحب للأسفل & bookmark 3–5 عقد لتسمح لمونيرويو أن يختار الأفضل لك!

      -

      ما هي العقد؟

      -

      مونيرويو يستخدم عقدة خارجية لالتواصل بشبكة مونيرو دون الحاجة لتنزيل نسخة كاملة من سلسلة الكتل .

      -

      قائمة العقد

      -

      إذا القائمة فارغة، يمكنك إما إضافة العقد يدوياً أو دع مونيرويو يمسح الشبكة لك. أو كلا الأمرين. إقرأ أكثر…

      -

      تعرض قائمة العقد كل العقد المعروفة حالياً. إضافةً، الطابع \ الختم الزمني لأحدث كتلة معروفة لكل عقدة يظهر - تحت اسم العقدة. تظهر أيقونة تمثل سلوك استجابة العقدة (يشير إلى مستوى الاتصال المتوقع) بجانب كل عقدة.

      -

      أي عقدة في القائمة يمكن أن تعلم لاستعمال لاحق. - العقد التي لم تعلم ستنسى.

      -

      سيختار مونيرويو العقدة المعلمة الأمثل كل مرة تستعمله. - يفعل هذا بالتأكد من ارتفاع الكتلة (ما هي حداثة العقدة؟) - إضافة إلى استجابتها (ما سرعة استجابة العقدة للطلبات؟).

      -

      هذه القائمة مفروزة حسب هذه الخصائص، فالعقدة العليا هي التي يختارها مونيرويو الآن. سيظهر الجزء السفلى عقد بطيئة جداً أو غير متوفرة.

      -

      أضف عقدة

      -

      عند لمس زر "أضف عقدة" في الأسفل، سيطلب منك إدخال تفاصيل العقدة في الحوار التالى. - "العنوان" هو اسم المضيف أو عنوان IP للعقدة - هذا المدخل الإلزامي الوحيد. - أدخل "المنفذ" إذا تشتغل العقدة في منفذ غير افتراضي )18089) - يمكنك أيضاً تسمية العقدة لتتمكن من التعرف عليها بسهولة في وقت لاحق. - بعض العقد تتطلب بيانات اعتماد لاستخدامهم. أدخل اسم المستخدم و كلمة المرور المزودين في الحقول المناسبة. الآن يمكنك "اختبار" هذه الاعدادات. - ستعرض "نتائج الاختبار" ارتفاع الكتلة، وقت الاستجابة، و عنوان IP المستعمل. - قد تكون النتيجة خطأً - عادة لأن اسم المصيف المزود لا يمكن الوصول إليه في وقت معقول أو أن بيانات الاعتماد غير صحيحة.أو أن اسم المضيف/المنفذ لا يشيران إلى عقدة مونيرو حقيقية! - عند اجتياز الاختبار (لا اخطاء) - يمكنك لمس "حسناً" لحفظ و تعليم هذه العقدة

      -

      ابحث عن العقد

      -

      إضافةً، يمكنك مسح الشبكة للعقد. مونيرويو سيبدأ مسح الشبكة للعقد البعيدة في منفذ 18098. يبدأ بيؤال العقد المعلمة عن أنداد آخرين في شبكة مونيرو ثم يستمر بسؤالهم عن أندادهم، وهكذا. إذا لا تملك عقد معلمة (أو لا يخبروننا عن أندادهم)، مونيرويو سيتجه مباشرةً إلى عقد بذور مونيرو ضمن مونيرو. سيتوقف المسح عند العثور على 10 عقد بعيدة.

      - ]]>
      - - استخدام رابط دفع -

      لقد بدأت مونيرويو باستخدام رابط دفق. لإرسال المال افعل التالي:

      -

      - 1. المحفظة التي تريد الانفاق منها
      - 2. انتظر حتى تزامن المحفظة وamp; يظهر زر "أعط"
      - 3. المس زر "أعط" -

      -

      .ستعبأ تفاصيل الدفع. تأكد منهم ثم أكمل كأي معاملة أخرى

      - ]]>
      - - فهمت! - diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml deleted file mode 100644 index 69527654..00000000 --- a/app/src/main/res/values-ar/strings.xml +++ /dev/null @@ -1,418 +0,0 @@ - - - محفظة - - عن - سياسة الخصوصية - - شارك - ساعدني - استلم - أعد التسمية … - انشئ نسخة احتياطية - غير كلمة المرور - - … أكمل الكتابة - … مه - هيا يمكنك القيام بأفضل من هذا! - تكاد تصل … - أجل، كالمحترفين! - - المحافظ - الاعتمادات - حسناً - إلغاء - أغلق - المس لالتفاصيل - - نجح الإرسال - تم - - المس لرمز استجابة سريعة (qr) - - دفع BTC مفعل، المس لمعلومات أكثر. - لدجر مفعل، المس لمعلومات أكثر. - - أدخلت عنوان بيتكوين.
      - سترسل XMR و سيستلم المستلم BTC باستخدام خدمة Sideshift.ai - ]]>
      - - Sideshift.ai طلب - - %1$s BTC - - التأكيد معلق - الدفع معلق - Sideshift.ai عطل (%1$s) - BTC أرسل - جار الاستعلام … - - يمكنك إرسال %1$s — %2$s BTC.
      - Sideshift.ai يعطيك سعر صرف %3$s BTC حالياً. - ]]>
      - - الرصيد: %2$s BTC (%1$s XMR) - - ✔ معرف الدفع مدمج - تجهيز عمليتك - - جار إنشاء طلب Sideshift.ai - استعلام طلب Sideshift.ai - جار تجهيز معاملة مونيرو - - استعلام ضوابط Sideshift.ai - - Sideshift.ai عطل - رمز: %1$d - - المس لإعادة المحوالة - علقنا هنا! - يبدو أن Sideshift.ai ليس متوفراً حالياً! - - %1$s BTC = %2$s XMR - (الصرف: %1$s BTC/XMR) - - قم بزيارة Sideshift.ai للدعم و التتبع - المفتاح السري\nSideshift.ai - السري Sideshift.ai مفتاح - عنوان الوجهة BTC - المبلغ - - معرف المعاملة - عنوان الوجهة - ملاحظات - - جار إنشاء النسخة الاحتياطية - جار الأرشفة - جار إعادة التسمية - جار تغيير كلمة المرور - - جار اختتام الأمور …\nقد يستغرق هذا برهةً! - - نجح النسخ الاحتياطي - فشل النسخ الاحتياطي! - فشلت إعادة التسمية! - فشل تغيير كلمة السر! - تم تغيير كلمة السر - - العقدة - جار تحميل المحفظة … - حفظت المحفظة - فشل حفظ المحفظة! - جار الاتصال … - فشل الاتصال بالعقدة!\nتأكد من اسم المستخدم/كلمة المرور - نسخة العقدة غير متوافقة - حدث رجاءً! - العقدة غير صحيحة!\nجرب عقدة أخرى. - لا يمكن الوصول للعقدة!\nحاول مجدداً أو جرب عقدة أخرى. - - منقطعة - - فشلت المعاملة: %1$d - - !انتظرت طويلاً يا صاحبي! - - …ما زلت مشغولاً بمحفظتك الأخيرة - - أعد التسمية %1$s - - كلمة مرور جديدة ل %1$s - أعد كلمة المرور ل %1$s - كلمة السر ل%1$s - يمكنك أيضاً فتح المحفظة باستعمال البصمة.\nرجاءً المس الحساس. - جار فتح المحفظة… - لم يتعرف على البصمة. حاول مجدداً. - كلمة السر خاطئة! - كلمة المرور المحفوظة غير صحيحة.\nرجاءً أدخل كلمة المرور يدوياً. - المحفظة غير موجودة! - !يجب ضبط العقدة! - المحفظة لا تطابق الشبكة المختارة - - (مشاهدة فقط) - - استلم - أعط - - + %1$s XMR غير مأكد - - خدمة مونيرويو - - تزامن؛ - الكتل التبقية - جار مسح: - - التخرين الخارجي غير قابل للكتابة! افزع! - نحتاج إلى صلاحيات التزين الخارجي فعلاً! - لا كاميرا = لا مسح لرموز الاستجابة السريعة (QR)! - - مفتاح الرؤية - العنوان العام - Sideshift.ai مفتاح - نسخ مفتاح الرؤية إلى الحافظة! - نسخ مفتاح Sideshift.ai إلى الناسخة! - نسخ عنوان المحفظة للحافظة! - نسخ معرف المعاملة إلى الحافظة! - النسخ معطل لأسباب أمنية! - - لا يمكن الحصول على سعر الصرف!\nاستعمل XMR/XMR أو حاول مجدداً - - أنشئ محفظة - اسم المحفظة - كلمة مرور المحفظة - اسمح لفتح المحفظة بالبصمة - التوثيق بالبصمة -

      عند تفعيل التوثيق بالبصمة، يمكنك رؤية رصيد المحفظة و استلام المال دون ادخال كلمة السر.

      -

      لكن لزيادة الأمان، مونيرويو سيتطلب منك أن تدخل كلمةالمرور عند رؤية تفاصيل المحفضة أو إرسال المال.

      - تحذير أمني - -

      مثلا، ينكن لشخص خبيث فتح محفظتك و أنت نائم.

      - هل أنت متأكد أنك تريد تفعيل هذه ال - ]]>
      - السر لا تتطابق - لا يمكن لعبارة المرور أن تكون فارغة - انشئ لي محفظة و خلصنا! - دونت بذرة الذاكرة - - أعطني اسماً - المحفظة موجودة! - لا يمكن البدء ب. - جار إنشاء المحفظة - أنشأت المحفظة - - أدخل رقماً أو تاريخاً (سسسس-شش-يي) - - المفاتيح - جديد - بذرة - رؤية - - العنوان العام - مفتاح الرؤية - مفاح الإنفاق - بذرة الذاكرة ذات 25 كلمة - استرجع الارتفاع أو التاريخ (سسسس-شش-يي) - - العنوان العام - مفتاح الرؤية - مفتاح الإنفاق - بذرة الذاكرة - ملفات المحفظة استرجع كلمة المرور - - أدخل مفتاحاً صحيحاً - أدخل عنواناً صحيحاً - أدخل بذرتك ذات 25 كلمة - - الملاحظات الخاصة (اختياري) - ولد - أنفق مونيرواتي الحبيبة - أرسل مونيرواتي الحبيبة (%1$s) - ليس رمز استجابة سريعة (QR) - ليس رمزاً حصيحاً - ليس عنواناً صحيحاً - عنوان OpenAlias ليس متوفر - آمن ✔ - حل OpenAlias… - OpenAlias دون DNSSEC - قد يكون العنوان منتحل - أرسل - الرصيد: %1$s XMR - العنوان - المبلغ - أكد - تم - - المبلغ - الرسوم (xmr) - الرسوم - المجموع (xmr) - المجموع - - %1$s XMR - +%1$s رسوم - - عطل إنشاء المعاملة - - - رسوم %1$s - (%1$s) - فشل - - %1$s - + %1$s - - الختم الزمني - TX ID - TX Key - الوجهة - معرف الدفع - الكتلة - المبلغ - الرسوم - التحويلات - ملاحظات - (اختياري) - تفاصيل المعاملة - - معلقة - فشلت - - المبلغ - وصف (اختياري) - لم يتمكن من فتح المحفظة! - - %1$s أقصى - 0 أدنى - XMR ليس رقماً - - ستظهر بيانات حساسة.\nتفحص خلف ظهرك! - أنا في أمان - أرجعني! - التفاصيل - - أنشئ محفظة جديدة - استرجع محفظة رؤية-فقط - استرجع محفظة من المفاتيح الخاصة - استرجع محفظة من بذرة 25 كلمة - - أنشئ حساباً - أضيف حساب جديد #%1$d - الحساب # - - أرسل كل المال المؤكد في هذا الحساب! - العنوان الفرعي #%1$d - العنوان الفرعي العام #%1$d - - اللغة - استخدم لغة النظام - - استرجع من لدجر نانو اس - - جار التواصل مع اللدجر - التأكيد على اللدجر مطلوب! - استلام العناوين الفرعية - التأكد من صحة المفاتيح - القيام بحسابات مجنونة - تشفير الأشياء - رجاءً (إعادة) إيصال جهاز لدجر - - جار إنشاء الحساب - - %1$s اربط - %1$s فصل - - جار كتابة العلامة - فشلت كتابة العلامة - نجحت كتابة العلامة - العلامة لا تدعم NDEF! - العلامة تزود %1$dلأ بايتاً، لكننا نحتاج %2$ل! - لا أفهم العلامة! - لا أعرف ماذا تريد! - NFC متوفر! - - أظهر أسراري! - وضع الشارع - - Node-o-matiC مفعل، المس لمعلومات أكثر. - آخر كتلة تحدثت: %1$s - العقد - اسم العقدة (اختياري) - اسم المضيف - المنفظ - اسم المستخدم (اختياري) - كلمة المرور (اختياري) - لا يمكن حل المضيف - نحتاج لهذا! - يجب أن يكون رقماً - 1–65535 يجب أن يكون - أضف عقدة - المس لإعادة التحميل - %1$d عطل إطصال - عطل في الاتصال - فشل التوثيق - نتيجة الاختبار: - الارتفاع: %1$s (v%2$d), Ping: %3$.0fms, IP: %4$s - اختبار IP: %1$s … - رجاءً انتظر انتهاء المسح - المس لاختيار أو إضافة العقد - أضف العقد يدوياً أو اسحب للأسفل للمسح - جار مسح الشبكة… - علمت أفضل %1$d عقد تلقائياً - اختبر - - المستلم - - كل شيء! - - حول بذرة اللدجر - كلمات بذرة اللدجر - عبارة دخول اللدجر (متقدم) - بذرة اللدجر غير صحيحة! - إدخال بذرة اللدجر هنا خطر أمني كبير! - - استرجع الارتفاع - - ابدأ تطبيق مونيرو في %1$s - - أعد المسح! - - فهمت! - التالي - أنا جاهز! - - مرحباً بك في مونيرويو! - هذا التطبيق يسمح لك بإنشاء و استخدام محافظ مونيرو. يمكنك الاحتفاظ بالحبيب مونيرو فيهم. - أبق بذرتك آمنة - البذرة تمنح وصولاً كاملاً لمن يمتلكها.إذا ما أضعتها لا يمكننا مساعدتك في استرجاعها و ستخسر مونيرواتك الحبيبة. - أرسل بيتكوين - لدى مونيرويو دعم داخلي لSideshift.ai. فقط الصق أو امسح عنوان بيتكوين و سترسل بيتكون بانفاق مونيرو. - العقد، كما تشاء - العقد تصلك بشبكة مونيرو. اختر ما بين العقد العامة أو كن متمرداً سبرانياً و استخدم خاصتك. - أرسل بالبصمة - يمكنك الآن إرسال XMR فقط ببصمتك إذا فعلتها. لطلب كلمة المرور، فقط عطل الدخول بالبصمة. - - الوضع الليلي - - تلقائي - يوم - ليل - - لا شيء هنا\nالرجاء إنشاء أو استعادة محفظة - - أرجع العقد الافتراضية - الاسترجاع يتقدم بالفعل... - - الكتلة الأخيرة: منذ %1$d ثوان - الكتلة الخيرة: منذ %1$d ساعة - الكتلة الأخيرة: منذ %1$d ساعة - الكتلة الأخيرة: منذ %1$d أيام - - لا يمكن الحصول على سعر - تأكد من البلغ و حاول مجدداً - عنوان مبهم.
      - رجاء حدد النوع أعلاه. - ]]>
      - - رجاء أدخل أو امسح عنوان %1$s
      - سترسل XMR و سيتلقى المستلم %2$s باستعمال خدمة SideShift.ai - ]]>
      - - رجاء أدخل أو امسح عنوان مونيرو - ]]> - - العناوين الفرعية - اسم العنوان الفرعي - عناوين غير مستعملة كثيرة - استعمل بعضها لتتمكن من إنشاء المزيد! - حسابات غير مستعملة كثيرة - استعمل بعضها لتتمكن من إنشاء المزيد! - المعاملات لهذا العنوان الفرعي: - لا معاملات لهذا العنوان الفرعي بعد - اختر عنواناً فرعياً - المس طويلاً للتفاصيل - - استورد محفظة - فشل الاستيراد - - أعد ضبط المحفظة! - ستتم إعادة ضبط هذه المحفظة ، وفقدان جميع البيانات خارج السلسلة (مثل الملاحظات ، وأسماء الحسابات والعناوين الفرعية ، ومفاتيح المعاملات الخاصة ، ...)! استخدم هذا فقط إذا كانت هذه المحفظة تالفة و لا تحمل! -
      From cdc2b2325715144bc445a6231b38d489ba45015d Mon Sep 17 00:00:00 2001 From: Diego Delmondes <61468499+diegodelmondes@users.noreply.github.com> Date: Sun, 5 Dec 2021 14:23:03 -0400 Subject: [PATCH 12/18] Improve Brazillian Portuguese translation (#778) * Improve translation Fix typos, improve the translation in general and translate some English strings. * Update strings.xml --- app/src/main/res/values-pt-rBR/strings.xml | 31 +++++++++++----------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 7c684030..4c9af7aa 100755 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -74,7 +74,7 @@ %1$s %3$s = %2$s XMR (Cotação: %1$s %2$s/XMR) - Visite o SideShift.ai para suporte & rastreio da ordem + Visite SideShift.ai para suporte & rastreio da ordem Chave secreta\nSideShift.ai Chave secreta SideShift.ai Endereço %1$s de destino @@ -156,9 +156,9 @@ Não foi possível obter a cotação!\nUse XMR/XMR ou tente novamente - Criar Carteira - Nome da Carteira - Senha da Carteira + Criar carteira + Nome da carteira + Senha da carteira Permitir abrir a carteira com impressão digital Autenticação por impressão digital @@ -358,12 +358,13 @@ Próximo Estou pronto! - Bem-vindo a Monerujo! - Esse aplicativo permite que você crie e use carteiras Monero. Você poderá guardar seus queridos moneroj aqui. + Bem-vindo à Monerujo! + Este aplicativo permite que você crie e use carteiras Monero. Você poderá guardar seus queridos moneroj +aqui. Mantenha sua semente em segurança A semente dá acesso total a qualquer pessoa que a tenha. Se você perdê-la, nós não conseguiremos lhe ajudar a recuperá-la e você perderá seus amados moneroj. - Enviar Crypto - A Monerujo possui o SideShift.ai integrado. Basta colar ou escaner um endereço BTC, LTC, ETH, DASH ou DOGE e você estará enviando cripto, mas gastando em XMR. + Enviar Cripto + A Monerujo possui o SideShift.ai integrado. Basta colar ou escanear um endereço BTC, LTC, ETH, DASH ou DOGE e você estará enviando cripto, mas gastando em XMR. "Nós", do seu jeito Os nós conectam você à rede Monero. Escolha entre nós públicos ou seja completamente "cypherpunk" e utilize seu próprio nó. Enviar usando a digital @@ -411,13 +412,13 @@ Selecione um subendereço Toque e segure para mais detalhes - This wallet will be deleted. Your funds will be gone forever unless you have your seed or a working backup to recover it. - Delete - Delete failed! + Esta carteira será excluída. Seus fundos desaparecerão para sempre, a não ser que você tenha sua semente guardada ou um backup funcional para recuperá-la. + Excluir + Exclusão falhou! - Import wallet - Import failed! + Importar carteira + Importação falhou! - Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + Resetar carteira! + Esta carteira será resetada, perdendo todos os dados "off-chain" (como notas, contas & nomes de subendereços, chaves de transações privadas, ...)! Use isso SOMENTE se esta carteira estiver corrompida e não carrega! From 05720e63aba9ab368b95cdb962caa4f8f07de7df Mon Sep 17 00:00:00 2001 From: m2049r Date: Sun, 5 Dec 2021 22:24:26 +0100 Subject: [PATCH 13/18] onion stuff (#796) --- app/build.gradle | 23 +- app/src/main/AndroidManifest.xml | 18 + app/src/main/cpp/monerujo.cpp | 21 + .../com/m2049r/levin/scanner/Dispatcher.java | 2 +- .../com/m2049r/xmrwallet/LoginActivity.java | 67 +++ .../com/m2049r/xmrwallet/LoginFragment.java | 125 +++- .../com/m2049r/xmrwallet/NodeFragment.java | 60 +- .../com/m2049r/xmrwallet/WalletFragment.java | 8 +- .../xmrwallet/XmrWalletApplication.java | 10 +- .../m2049r/xmrwallet/data/DefaultNodes.java | 6 +- .../java/com/m2049r/xmrwallet/data/Node.java | 79 ++- .../com/m2049r/xmrwallet/data/NodeInfo.java | 108 ++-- .../m2049r/xmrwallet/dialog/HelpFragment.java | 55 +- .../send/SendAddressWizardFragment.java | 27 +- .../send/SendBtcAmountWizardFragment.java | 4 +- .../send/SendBtcConfirmWizardFragment.java | 4 +- .../send/SendBtcSuccessWizardFragment.java | 4 +- .../xmrwallet/layout/NodeInfoAdapter.java | 48 +- .../layout/TransactionInfoAdapter.java | 16 +- .../com/m2049r/xmrwallet/model/Wallet.java | 4 +- .../m2049r/xmrwallet/model/WalletManager.java | 2 + .../xmrwallet/service/WalletService.java | 2 + .../service/exchange/ecb/ExchangeApiImpl.java | 24 +- .../exchange/kraken/ExchangeApiImpl.java | 25 +- .../exchange/krakenEcb/ExchangeApiImpl.java | 11 +- .../sideshift/network/SideShiftApiImpl.java | 25 +- .../com/m2049r/xmrwallet/util/Helper.java | 28 +- .../xmrwallet/util/NetCipherHelper.java | 389 +++++++++++++ .../m2049r/xmrwallet/util/OkHttpHelper.java | 72 --- .../m2049r/xmrwallet/util/OnionHelper.java | 24 + .../m2049r/xmrwallet/util/ServiceHelper.java | 2 +- .../xmrwallet/widget/ExchangeEditText.java | 4 +- .../m2049r/xmrwallet/widget/ExchangeView.java | 21 +- .../client/StrongOkHttpClientBuilder.java | 115 ++++ app/src/main/res/color/btn_color_selector.xml | 4 +- .../drawable/ic_info_outline_black_24dp.xml | 9 + .../main/res/drawable/ic_network_clearnet.xml | 9 + .../main/res/drawable/ic_network_tor_on.xml | 10 + app/src/main/res/layout/fragment_help.xml | 28 +- app/src/main/res/layout/fragment_login.xml | 52 +- app/src/main/res/layout/fragment_receive.xml | 5 +- .../main/res/layout/fragment_send_address.xml | 39 +- app/src/main/res/layout/item_node.xml | 2 +- app/src/main/res/layout/item_transaction.xml | 4 +- app/src/main/res/values-cat/help.xml | 139 +++-- app/src/main/res/values-cat/strings.xml | 11 +- app/src/main/res/values-de/help.xml | 21 + app/src/main/res/values-de/strings.xml | 9 +- app/src/main/res/values-el/help.xml | 21 + app/src/main/res/values-el/strings.xml | 9 +- app/src/main/res/values-eo/help.xml | 23 +- app/src/main/res/values-eo/strings.xml | 9 +- app/src/main/res/values-es/help.xml | 21 + app/src/main/res/values-es/strings.xml | 9 +- app/src/main/res/values-et/help.xml | 21 + app/src/main/res/values-et/strings.xml | 9 +- app/src/main/res/values-fr/help.xml | 21 + app/src/main/res/values-fr/strings.xml | 9 +- app/src/main/res/values-hu/help.xml | 21 + app/src/main/res/values-hu/strings.xml | 9 +- app/src/main/res/values-it/help.xml | 21 + app/src/main/res/values-it/strings.xml | 7 +- app/src/main/res/values-ja/help.xml | 21 + app/src/main/res/values-ja/strings.xml | 9 +- app/src/main/res/values-nb/help.xml | 21 + app/src/main/res/values-nb/strings.xml | 9 +- app/src/main/res/values-night/styles.xml | 1 - app/src/main/res/values-nl/help.xml | 21 + app/src/main/res/values-nl/strings.xml | 9 +- app/src/main/res/values-pt-rBR/help.xml | 21 + app/src/main/res/values-pt-rBR/strings.xml | 7 +- app/src/main/res/values-pt/help.xml | 21 + app/src/main/res/values-pt/strings.xml | 9 +- app/src/main/res/values-ro/help.xml | 21 + app/src/main/res/values-ro/strings.xml | 9 +- app/src/main/res/values-ru/help.xml | 21 + app/src/main/res/values-ru/strings.xml | 9 +- app/src/main/res/values-sk/about.xml | 104 ++-- app/src/main/res/values-sk/help.xml | 545 +++++++++--------- app/src/main/res/values-sk/strings.xml | 9 +- app/src/main/res/values-sr/help.xml | 21 + app/src/main/res/values-sr/strings.xml | 9 +- app/src/main/res/values-sv/help.xml | 21 + app/src/main/res/values-sv/strings.xml | 9 +- app/src/main/res/values-uk/help.xml | 45 +- app/src/main/res/values-uk/strings.xml | 9 +- app/src/main/res/values-zh-rCN/help.xml | 27 +- app/src/main/res/values-zh-rCN/strings.xml | 9 +- app/src/main/res/values-zh-rTW/help.xml | 21 + app/src/main/res/values-zh-rTW/strings.xml | 9 +- app/src/main/res/values/help.xml | 21 + app/src/main/res/values/strings.xml | 13 +- app/src/main/res/values/styles.xml | 3 +- build.gradle | 1 - 94 files changed, 2210 insertions(+), 860 deletions(-) create mode 100644 app/src/main/java/com/m2049r/xmrwallet/util/NetCipherHelper.java delete mode 100644 app/src/main/java/com/m2049r/xmrwallet/util/OkHttpHelper.java create mode 100644 app/src/main/java/com/m2049r/xmrwallet/util/OnionHelper.java create mode 100644 app/src/main/java/info/guardianproject/netcipher/client/StrongOkHttpClientBuilder.java create mode 100644 app/src/main/res/drawable/ic_info_outline_black_24dp.xml create mode 100644 app/src/main/res/drawable/ic_network_clearnet.xml create mode 100644 app/src/main/res/drawable/ic_network_tor_on.xml diff --git a/app/build.gradle b/app/build.gradle index d0912531..cad4f198 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -8,8 +8,8 @@ android { applicationId "com.m2049r.xmrwallet" minSdkVersion 21 targetSdkVersion 30 - versionCode 1102 - versionName "2.1.2 'Vertant'" + versionCode 1201 + versionName "2.2.1 'René'" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { @@ -113,27 +113,30 @@ android { } } -def getId(name) { - def Properties props = new Properties() +static def getId(name) { + Properties props = new Properties() props.load(new FileInputStream(new File('monerujo.id'))) return props[name] } dependencies { - implementation 'androidx.core:core:1.3.2' - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'com.google.android.material:material:1.3.0' + implementation 'androidx.core:core:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.recyclerview:recyclerview:1.2.0' + implementation 'androidx.recyclerview:recyclerview:1.2.1' implementation 'androidx.cardview:cardview:1.0.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01' - implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.constraintlayout:constraintlayout:2.1.1' implementation 'me.dm7.barcodescanner:zxing:1.9.8' implementation "com.squareup.okhttp3:okhttp:4.9.0" implementation "io.github.rburgst:okhttp-digest:2.5" implementation "com.jakewharton.timber:timber:4.7.1" + implementation 'info.guardianproject.netcipher:netcipher:2.1.0' + //implementation 'info.guardianproject.netcipher:netcipher-okhttp3:2.1.0' + implementation fileTree(dir: 'libs/classes', include: ['*.jar']) implementation 'com.nulab-inc:zxcvbn:1.3.0' implementation 'dnsjava:dnsjava:2.1.9' @@ -141,6 +144,7 @@ dependencies { implementation 'org.slf4j:slf4j-nop:1.7.30' implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2' + //noinspection GradleDependency testImplementation "junit:junit:$rootProject.ext.junitVersion" testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion" testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0" @@ -150,3 +154,4 @@ dependencies { compileOnly 'org.projectlombok:lombok:1.18.16' annotationProcessor 'org.projectlombok:lombok:1.18.16' } + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4902ec0a..017212ec 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,24 @@ + + + + + + + + + + + + + + + + + + NewStringUTF(resolvedAlias.c_str()); } +JNIEXPORT jboolean JNICALL +Java_com_m2049r_xmrwallet_model_WalletManager_setProxy(JNIEnv *env, jobject instance, + jstring address) { + const char *_address = env->GetStringUTFChars(address, nullptr); + bool rc = + Bitmonero::WalletManagerFactory::getWalletManager()->setProxy(std::string(_address)); + env->ReleaseStringUTFChars(address, _address); + return rc; +} + + //TODO static std::tuple checkUpdates(const std::string &software, const std::string &subdir); JNIEXPORT jboolean JNICALL @@ -727,6 +738,16 @@ Java_com_m2049r_xmrwallet_model_Wallet_getConnectionStatusJ(JNIEnv *env, jobject //TODO virtual void setTrustedDaemon(bool arg) = 0; //TODO virtual bool trustedDaemon() const = 0; +JNIEXPORT jboolean JNICALL +Java_com_m2049r_xmrwallet_model_Wallet_setProxy(JNIEnv *env, jobject instance, + jstring address) { + const char *_address = env->GetStringUTFChars(address, nullptr); + Bitmonero::Wallet *wallet = getHandle(env, instance); + bool rc = wallet->setProxy(std::string(_address)); + env->ReleaseStringUTFChars(address, _address); + return rc; +} + JNIEXPORT jlong JNICALL Java_com_m2049r_xmrwallet_model_Wallet_getBalance(JNIEnv *env, jobject instance, jint accountIndex) { diff --git a/app/src/main/java/com/m2049r/levin/scanner/Dispatcher.java b/app/src/main/java/com/m2049r/levin/scanner/Dispatcher.java index 536ba195..b9f8be57 100644 --- a/app/src/main/java/com/m2049r/levin/scanner/Dispatcher.java +++ b/app/src/main/java/com/m2049r/levin/scanner/Dispatcher.java @@ -77,7 +77,7 @@ public class Dispatcher implements PeerRetriever.OnGetPeers { final NodeInfo nodeInfo = retrievedPeer.getNodeInfo(); Timber.d("Retrieved %s", nodeInfo); if ((nodeInfo.isValid() || nodeInfo.isFavourite())) { - nodeInfo.setName(); + nodeInfo.setDefaultName(); rpcNodes.add(nodeInfo); Timber.d("RPC: %s", nodeInfo); // the following is not totally correct but it works (otherwise we need to diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java index 539095a6..d6ba1108 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java +++ b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java @@ -65,6 +65,7 @@ import com.m2049r.xmrwallet.util.KeyStoreHelper; import com.m2049r.xmrwallet.util.LegacyStorageHelper; import com.m2049r.xmrwallet.util.LocaleHelper; import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor; +import com.m2049r.xmrwallet.util.NetCipherHelper; import com.m2049r.xmrwallet.util.NightmodeHelper; import com.m2049r.xmrwallet.util.ThemeHelper; import com.m2049r.xmrwallet.util.ZipBackup; @@ -701,6 +702,7 @@ public class LoginActivity extends BaseActivity new AsyncWaitForService().execute(); } if (!Ledger.isConnected()) attachLedger(); + registerTor(); } private class AsyncWaitForService extends AsyncTask { @@ -1469,4 +1471,69 @@ public class LoginActivity extends BaseActivity } return usbManager; } + + // + // Tor (Orbot) stuff + // + + void torNotify() { + final Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container); + if (fragment == null) return; + + if (fragment instanceof LoginFragment) { + runOnUiThread(((LoginFragment) fragment)::showNetwork); + } + } + + private void deregisterTor() { + NetCipherHelper.deregister(); + } + + private void registerTor() { + NetCipherHelper.register(new NetCipherHelper.OnStatusChangedListener() { + @Override + public void connected() { + Timber.d("CONNECTED"); + WalletManager.getInstance().setProxy(NetCipherHelper.getProxy()); + torNotify(); + if (waitingUiTask != null) { + Timber.d("RUN"); + runOnUiThread(waitingUiTask); + waitingUiTask = null; + } + } + + @Override + public void disconnected() { + Timber.d("DISCONNECTED"); + WalletManager.getInstance().setProxy(""); + torNotify(); + } + + @Override + public void notInstalled() { + Timber.d("NOT INSTALLED"); + WalletManager.getInstance().setProxy(""); + torNotify(); + } + + @Override + public void notEnabled() { + Timber.d("NOT ENABLED"); + notInstalled(); + } + }); + } + + private Runnable waitingUiTask; + + @Override + public void runOnNetCipher(Runnable uiTask) { + if (waitingUiTask != null) throw new IllegalStateException("only one tor task at a time"); + if (NetCipherHelper.hasClient()) { + runOnUiThread(uiTask); + } else { + waitingUiTask = uiTask; + } + } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java b/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java index 34939c8f..4841639d 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/LoginFragment.java @@ -19,6 +19,8 @@ package com.m2049r.xmrwallet; import android.content.Context; import android.os.AsyncTask; import android.os.Bundle; +import android.text.Html; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -28,22 +30,27 @@ import android.view.ViewGroup; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; +import android.widget.ImageButton; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.floatingactionbutton.FloatingActionButton; +import com.google.android.material.progressindicator.CircularProgressIndicator; import com.m2049r.xmrwallet.data.NodeInfo; -import com.m2049r.xmrwallet.layout.NodeInfoAdapter; +import com.m2049r.xmrwallet.dialog.HelpFragment; import com.m2049r.xmrwallet.layout.WalletInfoAdapter; import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.KeyStoreHelper; +import com.m2049r.xmrwallet.util.NetCipherHelper; import com.m2049r.xmrwallet.util.NodePinger; import com.m2049r.xmrwallet.util.Notice; import com.m2049r.xmrwallet.widget.Toolbar; @@ -66,9 +73,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter private View tvGuntherSays; private ImageView ivGunther; private TextView tvNodeName; - private TextView tvNodeAddress; - private View pbNode; - private View llNode; + private TextView tvNodeInfo; + private ImageButton ibNetwork; + private CircularProgressIndicator pbNetwork; private Listener activityCallback; @@ -109,6 +116,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter Set getOrPopulateFavourites(); boolean hasLedger(); + + void runOnNetCipher(Runnable runnable); } @Override @@ -125,6 +134,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter @Override public void onPause() { Timber.d("onPause()"); + torStatus = null; super.onPause(); } @@ -135,7 +145,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter activityCallback.setTitle(null); activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS); activityCallback.showNet(); - pingSelectedNode(); + showNetwork(); + //activityCallback.runOnNetCipher(this::pingSelectedNode); } @Override @@ -183,12 +194,14 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter ViewGroup llNotice = view.findViewById(R.id.llNotice); Notice.showAll(llNotice, ".*_login"); - pbNode = view.findViewById(R.id.pbNode); - llNode = view.findViewById(R.id.llNode); - llNode.setOnClickListener(v -> startNodePrefs()); + view.findViewById(R.id.llNode).setOnClickListener(v -> startNodePrefs()); tvNodeName = view.findViewById(R.id.tvNodeName); - tvNodeAddress = view.findViewById(R.id.tvNodeAddress); + tvNodeInfo = view.findViewById(R.id.tvInfo); view.findViewById(R.id.ibRenew).setOnClickListener(v -> findBestNode()); + ibNetwork = view.findViewById(R.id.ibNetwork); + ibNetwork.setOnClickListener(v -> changeNetwork()); + ibNetwork.setEnabled(false); + pbNetwork = view.findViewById(R.id.pbNetwork); Helper.hideKeyboard(getActivity()); @@ -387,15 +400,29 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter return nodeList.get(0); } + private void setSubtext(String status) { + final Context ctx = getContext(); + final Spanned text = Html.fromHtml(ctx.getString(R.string.status, + Integer.toHexString(ContextCompat.getColor(ctx, R.color.monerujoGreen) & 0xFFFFFF), + Integer.toHexString(ContextCompat.getColor(ctx, R.color.monerujoBackground) & 0xFFFFFF), + status, "")); + tvNodeInfo.setText(text); + } + private class AsyncFindBestNode extends AsyncTask { final static int PING_SELECTED = 0; final static int FIND_BEST = 1; + private boolean netState; + @Override protected void onPreExecute() { super.onPreExecute(); - pbNode.setVisibility(View.VISIBLE); - llNode.setVisibility(View.INVISIBLE); + tvNodeName.setVisibility(View.GONE); + pbNetwork.setVisibility(View.VISIBLE); + netState = ibNetwork.isClickable(); + ibNetwork.setClickable(false); + setSubtext(getString(R.string.node_waiting)); } @Override @@ -417,8 +444,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter } if (selectedNode == null) { // autoselect selectedNode = autoselect(favourites); - } else + } else { selectedNode.testRpcService(); + } } else throw new IllegalStateException(); if ((selectedNode != null) && selectedNode.isValid()) { activityCallback.setNode(selectedNode); @@ -432,16 +460,17 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter @Override protected void onPostExecute(NodeInfo result) { if (!isAdded()) return; - pbNode.setVisibility(View.INVISIBLE); - llNode.setVisibility(View.VISIBLE); + tvNodeName.setVisibility(View.VISIBLE); + pbNetwork.setVisibility(View.INVISIBLE); + ibNetwork.setClickable(netState); if (result != null) { Timber.d("found a good node %s", result.toString()); showNode(result); } else { tvNodeName.setText(getResources().getText(R.string.node_create_hint)); tvNodeName.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); - tvNodeAddress.setText(null); - tvNodeAddress.setVisibility(View.GONE); + tvNodeInfo.setText(null); + tvNodeInfo.setVisibility(View.GONE); } } @@ -453,12 +482,70 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter private void showNode(NodeInfo nodeInfo) { tvNodeName.setText(nodeInfo.getName()); - tvNodeName.setCompoundDrawablesWithIntrinsicBounds(NodeInfoAdapter.getPingIcon(nodeInfo), 0, 0, 0); - Helper.showTimeDifference(tvNodeAddress, nodeInfo.getTimestamp()); - tvNodeAddress.setVisibility(View.VISIBLE); + nodeInfo.showInfo(tvNodeInfo); + tvNodeInfo.setVisibility(View.VISIBLE); } private void startNodePrefs() { activityCallback.onNodePrefs(); } + + // Network (Tor) stuff + + private void changeNetwork() { + Timber.d("S: %s", NetCipherHelper.getStatus()); + final NetCipherHelper.Status status = NetCipherHelper.getStatus(); + if (status == NetCipherHelper.Status.NOT_INSTALLED) { + HelpFragment.display(requireActivity().getSupportFragmentManager(), R.string.help_tor); + } else if (status == NetCipherHelper.Status.NOT_ENABLED) { + Toast.makeText(getActivity(), getString(R.string.tor_enable_background), Toast.LENGTH_LONG).show(); + } else { + pbNetwork.setVisibility(View.VISIBLE); + ibNetwork.setEnabled(false); + NetCipherHelper.getInstance().toggle(); + } + } + + private NetCipherHelper.Status torStatus = null; + + void showNetwork() { + final NetCipherHelper.Status status = NetCipherHelper.getStatus(); + Timber.d("SHOW %s", status); + if (status == torStatus) return; + torStatus = status; + switch (status) { + case ENABLED: + ibNetwork.setImageResource(R.drawable.ic_network_tor_on); + ibNetwork.setEnabled(true); + ibNetwork.setClickable(true); + pbNetwork.setVisibility(View.INVISIBLE); + break; + case NOT_ENABLED: + case DISABLED: + ibNetwork.setImageResource(R.drawable.ic_network_clearnet); + ibNetwork.setEnabled(true); + ibNetwork.setClickable(true); + pbNetwork.setVisibility(View.INVISIBLE); + break; + case STARTING: + ibNetwork.setImageResource(R.drawable.ic_network_clearnet); + ibNetwork.setEnabled(false); + pbNetwork.setVisibility(View.VISIBLE); + break; + case STOPPING: + ibNetwork.setImageResource(R.drawable.ic_network_clearnet); + ibNetwork.setEnabled(false); + pbNetwork.setVisibility(View.VISIBLE); + break; + case NOT_INSTALLED: + ibNetwork.setEnabled(true); + ibNetwork.setClickable(true); + pbNetwork.setVisibility(View.INVISIBLE); + ibNetwork.setImageResource(R.drawable.ic_network_clearnet); + break; + default: + return; + } + activityCallback.runOnNetCipher(this::pingSelectedNode); + } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/NodeFragment.java b/app/src/main/java/com/m2049r/xmrwallet/NodeFragment.java index 2f52f21c..89106287 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/NodeFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/NodeFragment.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.DialogInterface; import android.os.AsyncTask; import android.os.Bundle; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -59,7 +58,6 @@ import java.text.NumberFormat; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; -import java.util.Objects; import java.util.Set; import timber.log.Timber; @@ -219,8 +217,8 @@ public class NodeFragment extends Fragment activityCallback.setNode(nodeItem); // this marks it as selected & saves it as well nodeItem.setSelecting(false); try { - Objects.requireNonNull(getActivity()).runOnUiThread(() -> nodesAdapter.allowClick(true)); - } catch (NullPointerException ex) { + requireActivity().runOnUiThread(() -> nodesAdapter.allowClick(true)); + } catch (IllegalStateException ex) { // it's ok } }); @@ -403,16 +401,12 @@ public class NodeFragment extends Fragment etNodeHost.setError(getString(R.string.node_host_empty)); return false; } - final boolean setHostSuccess = Helper.runWithNetwork(new Helper.Action() { - @Override - public boolean run() { - try { - nodeInfo.setHost(host); - return true; - } catch (UnknownHostException ex) { - etNodeHost.setError(getString(R.string.node_host_unresolved)); - return false; - } + final boolean setHostSuccess = Helper.runWithNetwork(() -> { + try { + nodeInfo.setHost(host); + return true; + } catch (UnknownHostException ex) { + return false; } }); if (!setHostSuccess) { @@ -421,14 +415,7 @@ public class NodeFragment extends Fragment } etNodeHost.setError(null); nodeInfo.setRpcPort(port); - // setName() may trigger reverse DNS - Helper.runWithNetwork(new Helper.Action() { - @Override - public boolean run() { - nodeInfo.setName(etNodeName.getEditText().getText().toString().trim()); - return true; - } - }); + nodeInfo.setName(etNodeName.getEditText().getText().toString().trim()); nodeInfo.setUsername(etNodeUser.getEditText().getText().toString().trim()); nodeInfo.setPassword(etNodePass.getEditText().getText().toString()); // no trim for pw return true; @@ -532,20 +519,10 @@ public class NodeFragment extends Fragment @Override public void onShow(final DialogInterface dialog) { Button testButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEUTRAL); - testButton.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - test(); - } - }); + testButton.setOnClickListener(view -> test()); Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE); - button.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View view) { - apply(); - } - }); + button.setOnClickListener(view -> apply()); } }); @@ -553,15 +530,13 @@ public class NodeFragment extends Fragment editDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); } - etNodePass.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { - public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { - if (actionId == EditorInfo.IME_ACTION_DONE) { - editDialog.getButton(DialogInterface.BUTTON_NEUTRAL).requestFocus(); - test(); - return true; - } - return false; + etNodePass.getEditText().setOnEditorActionListener((v, actionId, event) -> { + if (actionId == EditorInfo.IME_ACTION_DONE) { + editDialog.getButton(DialogInterface.BUTTON_NEUTRAL).requestFocus(); + test(); + return true; } + return false; }); } @@ -589,6 +564,7 @@ public class NodeFragment extends Fragment } else { nodesAdapter.setNodes(); } + nodesAdapter.notifyItemChanged(nodeInfo); } } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java index 35a93981..58566144 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java @@ -223,11 +223,13 @@ public class WalletFragment extends Fragment } void showUnconfirmed(double unconfirmedAmount) { - if (!activityCallback.isStreetMode()) { + if (activityCallback.isStreetMode() || unconfirmedAmount == 0) { + tvUnconfirmedAmount.setText(null); + tvUnconfirmedAmount.setVisibility(View.GONE); + } else { String unconfirmed = Helper.getFormattedAmount(unconfirmedAmount, true); tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed)); - } else { - tvUnconfirmedAmount.setText(null); + tvUnconfirmedAmount.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/XmrWalletApplication.java b/app/src/main/java/com/m2049r/xmrwallet/XmrWalletApplication.java index 16059f6f..5257f141 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/XmrWalletApplication.java +++ b/app/src/main/java/com/m2049r/xmrwallet/XmrWalletApplication.java @@ -21,14 +21,17 @@ import android.content.Context; import android.content.res.Configuration; import android.os.Build; -import com.m2049r.xmrwallet.BuildConfig; +import androidx.annotation.NonNull; + import com.m2049r.xmrwallet.model.NetworkType; import com.m2049r.xmrwallet.util.LocaleHelper; +import com.m2049r.xmrwallet.util.NetCipherHelper; import com.m2049r.xmrwallet.util.NightmodeHelper; import timber.log.Timber; public class XmrWalletApplication extends Application { + @Override public void onCreate() { super.onCreate(); @@ -36,7 +39,10 @@ public class XmrWalletApplication extends Application { if (BuildConfig.DEBUG) { Timber.plant(new Timber.DebugTree()); } + NightmodeHelper.setPreferredNightmode(this); + + NetCipherHelper.createInstance(this); } @Override @@ -45,7 +51,7 @@ public class XmrWalletApplication extends Application { } @Override - public void onConfigurationChanged(Configuration configuration) { + public void onConfigurationChanged(@NonNull Configuration configuration) { super.onConfigurationChanged(configuration); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { LocaleHelper.updateSystemDefaultLocale(configuration.getLocales().get(0)); diff --git a/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java b/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java index 31490e22..49aab3ed 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java +++ b/app/src/main/java/com/m2049r/xmrwallet/data/DefaultNodes.java @@ -28,7 +28,11 @@ public enum DefaultNodes { SUPPORTXMR("node.supportxmr.com:18081"), HASHVAULT("nodes.hashvault.pro:18081"), MONEROWORLD("node.moneroworld.com:18089"), - XMRTW("opennode.xmr-tw.org:18089"); + XMRTW("opennode.xmr-tw.org:18089"), + MONERUJO_ONION("monerujods7mbghwe6cobdr6ujih6c22zu5rl7zshmizz2udf7v7fsad.onion:18081/mainnet/monerujo.onion"), + Criminales78("56wl7y2ebhamkkiza4b7il4mrzwtyvpdym7bm2bkg3jrei2je646k3qd.onion:18089/mainnet/Criminales78.onion"), + xmrfail("mxcd4577fldb3ppzy7obmmhnu3tf57gbcbd4qhwr2kxyjj2qi3dnbfqd.onion:18081/mainnet/xmrfail.onion"), + boldsuck("6dsdenp6vjkvqzy4wzsnzn6wixkdzihx3khiumyzieauxuxslmcaeiad.onion:18081/mainnet/boldsuck.onion"); @Getter private final String uri; diff --git a/app/src/main/java/com/m2049r/xmrwallet/data/Node.java b/app/src/main/java/com/m2049r/xmrwallet/data/Node.java index 65011e1c..0f011530 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/data/Node.java +++ b/app/src/main/java/com/m2049r/xmrwallet/data/Node.java @@ -18,6 +18,7 @@ package com.m2049r.xmrwallet.data; import com.m2049r.xmrwallet.model.NetworkType; import com.m2049r.xmrwallet.model.WalletManager; +import com.m2049r.xmrwallet.util.OnionHelper; import java.io.UnsupportedEncodingException; import java.net.InetAddress; @@ -35,11 +36,63 @@ public class Node { static public final String STAGENET = "stagenet"; static public final String TESTNET = "testnet"; + static class Address { + final private InetAddress inet; + final private String onion; + + public boolean isOnion() { + return onion != null; + } + + public String getHostName() { + if (inet != null) { + return inet.getHostName(); + } else { + return onion; + } + } + + public String getHostAddress() { + if (inet != null) { + return inet.getHostAddress(); + } else { + return onion; + } + } + + private Address(InetAddress address, String onion) { + this.inet = address; + this.onion = onion; + } + + static Address of(InetAddress address) { + return new Address(address, null); + } + + static Address of(String host) throws UnknownHostException { + if (OnionHelper.isOnionHost(host)) { + return new Address(null, host); + } else { + return new Address(InetAddress.getByName(host), null); + } + } + + @Override + public int hashCode() { + return getHostAddress().hashCode(); + } + + @Override + public boolean equals(Object other) { + return (other instanceof Address) && (getHostAddress().equals(((Address) other).getHostAddress())); + } + } + @Getter private String name = null; @Getter final private NetworkType networkType; - InetAddress hostAddress; + Address hostAddress; @Getter private String host; @Getter @@ -74,6 +127,10 @@ public class Node { && (networkType == anotherNode.networkType)); } + public boolean isOnion() { + return hostAddress.isOnion(); + } + static public Node fromString(String nodeString) { try { return new Node(nodeString); @@ -205,7 +262,7 @@ public class Node { // constructor used for created nodes from retrieved peer lists public Node(InetSocketAddress socketAddress) { this(); - this.hostAddress = socketAddress.getAddress(); + this.hostAddress = Address.of(socketAddress.getAddress()); this.host = socketAddress.getHostString(); this.rpcPort = 0; // unknown this.levinPort = socketAddress.getPort(); @@ -225,17 +282,25 @@ public class Node { if ((host == null) || (host.isEmpty())) throw new UnknownHostException("loopback not supported (yet?)"); this.host = host; - this.hostAddress = InetAddress.getByName(host); + this.hostAddress = Address.of(host); } - public void setName() { - if (name == null) - this.name = hostAddress.getHostName(); + public void setDefaultName() { + if (name != null) return; + String nodeName = hostAddress.getHostName(); + if (hostAddress.isOnion()) { + nodeName = nodeName.substring(0, nodeName.length() - ".onion".length()); + if (nodeName.length() > 16) { + nodeName = nodeName.substring(0, 8) + "…" + nodeName.substring(nodeName.length() - 6); + } + nodeName = nodeName + ".onion"; + } + this.name = nodeName; } public void setName(String name) { if ((name == null) || (name.isEmpty())) - this.name = hostAddress.getHostName(); + setDefaultName(); else this.name = name; } diff --git a/app/src/main/java/com/m2049r/xmrwallet/data/NodeInfo.java b/app/src/main/java/com/m2049r/xmrwallet/data/NodeInfo.java index 3884a471..bab0b7ee 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/data/NodeInfo.java +++ b/app/src/main/java/com/m2049r/xmrwallet/data/NodeInfo.java @@ -16,14 +16,19 @@ package com.m2049r.xmrwallet.data; -import com.burgstaller.okhttp.AuthenticationCacheInterceptor; -import com.burgstaller.okhttp.CachingAuthenticatorDecorator; -import com.burgstaller.okhttp.digest.CachingAuthenticator; -import com.burgstaller.okhttp.digest.Credentials; -import com.burgstaller.okhttp.digest.DigestAuthenticator; +import android.content.Context; +import android.text.Html; +import android.text.Spanned; +import android.widget.TextView; + +import androidx.core.content.ContextCompat; + import com.m2049r.levin.scanner.LevinPeer; +import com.m2049r.xmrwallet.R; +import com.m2049r.xmrwallet.util.NetCipherHelper; +import com.m2049r.xmrwallet.util.NetCipherHelper.Request; import com.m2049r.xmrwallet.util.NodePinger; -import com.m2049r.xmrwallet.util.OkHttpHelper; +import com.m2049r.xmrwallet.util.ThemeHelper; import org.json.JSONException; import org.json.JSONObject; @@ -32,17 +37,12 @@ import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.Calendar; import java.util.Comparator; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import lombok.Getter; import lombok.Setter; import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; import okhttp3.Response; import okhttp3.ResponseBody; import timber.log.Timber; @@ -94,7 +94,7 @@ public class NodeInfo extends Node { synchronized public SocketAddress getLevinSocketAddress() { if (levinSocketAddress == null) { // use default peer port if not set - very few peers use nonstandard port - levinSocketAddress = new InetSocketAddress(hostAddress, getDefaultLevinPort()); + levinSocketAddress = new InetSocketAddress(hostAddress.getHostAddress(), getDefaultLevinPort()); } return levinSocketAddress; } @@ -180,7 +180,7 @@ public class NodeInfo extends Node { return sb.toString(); } - private static final int HTTP_TIMEOUT = OkHttpHelper.HTTP_TIMEOUT; + private static final int HTTP_TIMEOUT = 1000; //ms public static final double PING_GOOD = HTTP_TIMEOUT / 3.0; //ms public static final double PING_MEDIUM = 2 * PING_GOOD; //ms public static final double PING_BAD = HTTP_TIMEOUT; @@ -196,32 +196,29 @@ public class NodeInfo extends Node { return result; } + private Request rpcServiceRequest(int port) { + final HttpUrl url = new HttpUrl.Builder() + .scheme("http") + .host(getHost()) + .port(port) + .addPathSegment("json_rpc") + .build(); + final String json = "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"getlastblockheader\"}"; + return new Request(url, json, getUsername(), getPassword()); + } + private boolean testRpcService(int port) { Timber.d("Testing %s", toNodeString()); clear(); + if (hostAddress.isOnion() && !NetCipherHelper.isTor()) { + tested = true; // sortof + responseCode = 418; // I'm a teapot - or I need an Onion - who knows + return false; // autofail + } try { - OkHttpClient client = OkHttpHelper.getEagerClient(); - if (!getUsername().isEmpty()) { - final DigestAuthenticator authenticator = - new DigestAuthenticator(new Credentials(getUsername(), getPassword())); - final Map authCache = new ConcurrentHashMap<>(); - client = client.newBuilder() - .authenticator(new CachingAuthenticatorDecorator(authenticator, authCache)) - .addInterceptor(new AuthenticationCacheInterceptor(authCache)) - .build(); - } - HttpUrl url = new HttpUrl.Builder() - .scheme("http") - .host(getHostAddress()) - .port(port) - .addPathSegment("json_rpc") - .build(); - final RequestBody reqBody = RequestBody - .create(MediaType.parse("application/json"), - "{\"jsonrpc\":\"2.0\",\"id\":\"0\",\"method\":\"getlastblockheader\"}"); - Request request = OkHttpHelper.getPostRequest(url, reqBody); long ta = System.nanoTime(); - try (Response response = client.newCall(request).execute()) { + try (Response response = rpcServiceRequest(port).execute()) { + Timber.d("%s: %s", response.code(), response.request().url()); responseTime = (System.nanoTime() - ta) / 1000000.0; responseCode = response.code(); if (response.isSuccessful()) { @@ -243,7 +240,7 @@ public class NodeInfo extends Node { } } } catch (IOException | JSONException ex) { - Timber.d(ex); + Timber.d("EX: %s", ex.getMessage()); //TODO: do something here (show error?) } finally { tested = true; } @@ -264,4 +261,43 @@ public class NodeInfo extends Node { } return false; } + + static public final int STALE_NODE_HOURS = 2; + + public void showInfo(TextView view, String info, boolean isError) { + final Context ctx = view.getContext(); + final Spanned text = Html.fromHtml(ctx.getString(R.string.status, + Integer.toHexString(ContextCompat.getColor(ctx, R.color.monerujoGreen) & 0xFFFFFF), + Integer.toHexString(ContextCompat.getColor(ctx, R.color.monerujoBackground) & 0xFFFFFF), + (hostAddress.isOnion() ? " .onion  " : ""), " " + info)); + view.setText(text); + if (isError) + view.setTextColor(ThemeHelper.getThemedColor(ctx, R.attr.colorError)); + else + view.setTextColor(ThemeHelper.getThemedColor(ctx, R.attr.colorPrimary)); + } + + public void showInfo(TextView view) { + if (!isTested()) { + showInfo(view, "", false); + return; + } + final Context ctx = view.getContext(); + final long now = Calendar.getInstance().getTimeInMillis() / 1000; + final long secs = (now - timestamp); + final long mins = secs / 60; + final long hours = mins / 60; + final long days = hours / 24; + String info; + if (mins < 2) { + info = ctx.getString(R.string.node_updated_now, secs); + } else if (hours < 2) { + info = ctx.getString(R.string.node_updated_mins, mins); + } else if (days < 2) { + info = ctx.getString(R.string.node_updated_hours, hours); + } else { + info = ctx.getString(R.string.node_updated_days, days); + } + showInfo(view, info, hours >= STALE_NODE_HOURS); + } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java b/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java index e358ba8a..69289372 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/dialog/HelpFragment.java @@ -17,13 +17,17 @@ package com.m2049r.xmrwallet.dialog; import android.app.Dialog; -import android.content.DialogInterface; +import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; import android.text.Html; +import android.text.Spanned; import android.view.LayoutInflater; import android.view.View; import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.core.content.ContextCompat; import androidx.fragment.app.DialogFragment; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; @@ -31,15 +35,20 @@ import androidx.fragment.app.FragmentTransaction; import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.m2049r.xmrwallet.R; +import com.m2049r.xmrwallet.util.NetCipherHelper; public class HelpFragment extends DialogFragment { static final String TAG = "HelpFragment"; private static final String HELP_ID = "HELP_ID"; + private static final String TOR_BUTTON = "TOR"; public static HelpFragment newInstance(int helpResourceId) { HelpFragment fragment = new HelpFragment(); Bundle bundle = new Bundle(); bundle.putInt(HELP_ID, helpResourceId); + // a hack for the tor button + if (helpResourceId == R.string.help_tor) + bundle.putInt(TOR_BUTTON, 7); fragment.setArguments(bundle); return fragment; } @@ -54,27 +63,53 @@ public class HelpFragment extends DialogFragment { HelpFragment.newInstance(helpResourceId).show(ft, TAG); } + private Spanned getHtml(String html, double textSize) { + final Html.ImageGetter imageGetter = source -> { + final int imageId = getResources().getIdentifier(source.replace("/", ""), "drawable", requireActivity().getPackageName()); + // Don't die if we don't find the image - use a heart instead + final Drawable drawable = ContextCompat.getDrawable(requireActivity(), imageId > 0 ? imageId : R.drawable.ic_favorite_24dp); + final double f = textSize / drawable.getIntrinsicHeight(); + drawable.setBounds(0, 0, (int) (f * drawable.getIntrinsicWidth()), (int) textSize); + return drawable; + }; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + return Html.fromHtml(html, Html.FROM_HTML_MODE_LEGACY, imageGetter, null); + } else { + return Html.fromHtml(html, imageGetter, null); + } + } + + @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) { final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_help, null); int helpId = 0; + boolean torButton = false; Bundle arguments = getArguments(); if (arguments != null) { helpId = arguments.getInt(HELP_ID); + torButton = arguments.getInt(TOR_BUTTON) > 0; } + final TextView helpTv = view.findViewById(R.id.tvHelp); if (helpId > 0) - ((TextView) view.findViewById(R.id.tvHelp)).setText(Html.fromHtml(getString(helpId))); + helpTv.setText(getHtml(getString(helpId), helpTv.getTextSize())); - MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(getActivity()) - .setView(view) - .setNegativeButton(R.string.help_ok, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int id) { + MaterialAlertDialogBuilder builder = + new MaterialAlertDialogBuilder(requireActivity()) + .setView(view); + if (torButton) { + builder.setNegativeButton(R.string.help_nok, + (dialog, id) -> dialog.dismiss()) + .setPositiveButton(R.string.help_getorbot, + (dialog, id) -> { dialog.dismiss(); - } - }); + NetCipherHelper.getInstance().installOrbot(requireActivity()); + }); + } else { + builder.setNegativeButton(R.string.help_ok, + (dialog, id) -> dialog.dismiss()); + } return builder.create(); } } \ No newline at end of file diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java index 56a12e39..f25ad19b 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java @@ -22,6 +22,7 @@ import android.os.Bundle; import android.text.Editable; import android.text.Html; import android.text.InputType; +import android.text.Spanned; import android.text.TextWatcher; import android.util.Patterns; import android.view.KeyEvent; @@ -91,6 +92,7 @@ public class SendAddressWizardFragment extends SendWizardFragment { private TextInputLayout etAddress; private TextInputLayout etNotes; private TextView tvXmrTo; + private TextView tvTor; private Map ibCrypto; final private Set possibleCryptos = new HashSet<>(); private Crypto selectedCrypto = null; @@ -117,11 +119,12 @@ public class SendAddressWizardFragment extends SendWizardFragment { View view = inflater.inflate(R.layout.fragment_send_address, container, false); - if (Helper.ALLOW_SHIFT) { - tvXmrTo = view.findViewById(R.id.tvXmrTo); - ibCrypto = new HashMap<>(); - for (Crypto crypto : Crypto.values()) { - final ImageButton button = view.findViewById(crypto.getButtonId()); + tvTor = view.findViewById(R.id.tvTor); + tvXmrTo = view.findViewById(R.id.tvXmrTo); + ibCrypto = new HashMap<>(); + for (Crypto crypto : Crypto.values()) { + final ImageButton button = view.findViewById(crypto.getButtonId()); + if (Helper.ALLOW_SHIFT || (crypto == Crypto.XMR)) { ibCrypto.put(crypto, button); button.setOnClickListener(v -> { if (possibleCryptos.contains(crypto)) { @@ -137,14 +140,21 @@ public class SendAddressWizardFragment extends SendWizardFragment { } else { tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto_help_xmr))); tvXmrTo.setVisibility(View.VISIBLE); + tvTor.setVisibility(View.INVISIBLE); } } }); + } else { + button.setImageResource(crypto.getIconDisabledId()); + button.setImageAlpha(128); + button.setEnabled(false); } - updateCryptoButtons(true); - } else { - view.findViewById(R.id.llExchange).setVisibility(View.GONE); } + if (!Helper.ALLOW_SHIFT) { + tvTor.setVisibility(View.VISIBLE); + } + updateCryptoButtons(true); + etAddress = view.findViewById(R.id.etAddress); etAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); etAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { @@ -455,6 +465,7 @@ public class SendAddressWizardFragment extends SendWizardFragment { Timber.d("BUT ONLY XMR SUPPORTED"); barcodeData = null; sendListener.setBarcodeData(barcodeData); + return; } if (barcodeData.address != null) { etAddress.getEditText().setText(barcodeData.address); diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java index 8f1616fb..72b2e988 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcAmountWizardFragment.java @@ -35,7 +35,6 @@ import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters; import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi; import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl; import com.m2049r.xmrwallet.util.Helper; -import com.m2049r.xmrwallet.util.OkHttpHelper; import com.m2049r.xmrwallet.util.ServiceHelper; import com.m2049r.xmrwallet.widget.ExchangeOtherEditText; import com.m2049r.xmrwallet.widget.SendProgressView; @@ -255,8 +254,7 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment { if (xmrToApi == null) { synchronized (this) { if (xmrToApi == null) { - xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(), - ServiceHelper.getXmrToBaseUrl()); + xmrToApi = new SideShiftApiImpl(ServiceHelper.getXmrToBaseUrl()); } } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java index 94d2e8e6..66a66c2f 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcConfirmWizardFragment.java @@ -37,7 +37,6 @@ import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote; import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi; import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl; import com.m2049r.xmrwallet.util.Helper; -import com.m2049r.xmrwallet.util.OkHttpHelper; import com.m2049r.xmrwallet.util.ServiceHelper; import com.m2049r.xmrwallet.widget.SendProgressView; @@ -543,8 +542,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements if (xmrToApi == null) { synchronized (this) { if (xmrToApi == null) { - xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(), - ServiceHelper.getXmrToBaseUrl()); + xmrToApi = new SideShiftApiImpl(ServiceHelper.getXmrToBaseUrl()); } } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcSuccessWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcSuccessWizardFragment.java index 4156ee56..6c0faf14 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcSuccessWizardFragment.java +++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendBtcSuccessWizardFragment.java @@ -39,7 +39,6 @@ import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderStatus; import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi; import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl; import com.m2049r.xmrwallet.util.Helper; -import com.m2049r.xmrwallet.util.OkHttpHelper; import com.m2049r.xmrwallet.util.ServiceHelper; import java.text.NumberFormat; @@ -245,8 +244,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment { if (xmrToApi == null) { synchronized (this) { if (xmrToApi == null) { - xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(), - ServiceHelper.getXmrToBaseUrl()); + xmrToApi = new SideShiftApiImpl(ServiceHelper.getXmrToBaseUrl()); } } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/layout/NodeInfoAdapter.java b/app/src/main/java/com/m2049r/xmrwallet/layout/NodeInfoAdapter.java index c93911ee..57f02850 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/layout/NodeInfoAdapter.java +++ b/app/src/main/java/com/m2049r/xmrwallet/layout/NodeInfoAdapter.java @@ -23,28 +23,25 @@ import android.view.ViewGroup; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.fragment.app.FragmentActivity; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.data.NodeInfo; -import com.m2049r.xmrwallet.util.ThemeHelper; -import com.m2049r.xmrwallet.util.Helper; +import com.m2049r.xmrwallet.dialog.HelpFragment; +import com.m2049r.xmrwallet.util.NetCipherHelper; import java.net.HttpURLConnection; -import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.List; -import java.util.TimeZone; public class NodeInfoAdapter extends RecyclerView.Adapter { - private final SimpleDateFormat TS_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm"); - public interface OnInteractionListener { void onInteraction(View view, NodeInfo item); @@ -54,14 +51,16 @@ public class NodeInfoAdapter extends RecyclerView.Adapter nodeItems = new ArrayList<>(); private final OnInteractionListener listener; - private final Context context; + private final FragmentActivity activity; - public NodeInfoAdapter(Context context, OnInteractionListener listener) { - this.context = context; + public NodeInfoAdapter(FragmentActivity activity, OnInteractionListener listener) { + this.activity = activity; this.listener = listener; - Calendar cal = Calendar.getInstance(); - TimeZone tz = cal.getTimeZone(); //get the local time zone. - TS_FORMATTER.setTimeZone(tz); + } + + public void notifyItemChanged(NodeInfo nodeInfo) { + final int pos = nodeItems.indexOf(nodeInfo); + if (pos >= 0) notifyItemChanged(pos); } private static class NodeDiff extends DiffCallback { @@ -142,7 +141,7 @@ public class NodeInfoAdapter extends RecyclerView.Adapter { nodeItem.toggleFavourite(); @@ -179,13 +178,12 @@ public class NodeInfoAdapter extends RecyclerView.Adapter 0)) { - String fee = Helper.getDisplayAmount(infoItem.fee, Helper.DISPLAY_DIGITS_INFO); - tvFee.setText(context.getString(R.string.tx_list_fee, fee)); - tvFee.setVisibility(View.VISIBLE); - } else { - tvFee.setText(""); - tvFee.setVisibility(View.GONE); - } + tvFailed.setVisibility(View.GONE); if (infoItem.isFailed) { this.tvAmount.setText(context.getString(R.string.tx_list_amount_failed, displayAmount)); - this.tvFee.setText(context.getString(R.string.tx_list_failed_text)); - tvFee.setVisibility(View.VISIBLE); + tvFailed.setVisibility(View.VISIBLE); setTxColour(failedColour); pbConfirmations.setVisibility(View.GONE); tvConfirmations.setVisibility(View.GONE); diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java index 47df8e08..74053183 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java @@ -75,7 +75,7 @@ public class Wallet { @Override @NonNull public String toString() { - return "Wallet.Status: (" + status + "/" + errorString + ", " + connectionStatus; + return "Wallet.Status: " + status + "/" + errorString + "/" + connectionStatus; } } @@ -247,6 +247,8 @@ public class Wallet { //TODO virtual void setTrustedDaemon(bool arg) = 0; //TODO virtual bool trustedDaemon() const = 0; + public native boolean setProxy(String address); + public long getBalance() { return getBalance(accountIndex); } diff --git a/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java b/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java index 2a6ffd0d..433f7f02 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java +++ b/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java @@ -309,6 +309,8 @@ public class WalletManager { public native String resolveOpenAlias(String address, boolean dnssec_valid); + public native boolean setProxy(String address); + //TODO static std::tuple checkUpdates(const std::string &software, const std::string &subdir); static public native void initLogger(String argv0, String defaultLogBaseName); diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java index 65bf9ef4..e7e694d4 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/WalletService.java @@ -45,6 +45,7 @@ import com.m2049r.xmrwallet.model.WalletListener; import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.LocaleHelper; +import com.m2049r.xmrwallet.util.NetCipherHelper; import timber.log.Timber; @@ -531,6 +532,7 @@ public class WalletService extends Service { Timber.d("Using daemon %s", WalletManager.getInstance().getDaemonAddress()); showProgress(55); wallet.init(0); + wallet.setProxy(NetCipherHelper.getProxy()); showProgress(90); } return wallet; diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/exchange/ecb/ExchangeApiImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/exchange/ecb/ExchangeApiImpl.java index e424a1bf..e355ff5d 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/exchange/ecb/ExchangeApiImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/exchange/ecb/ExchangeApiImpl.java @@ -25,6 +25,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeApi; import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback; import com.m2049r.xmrwallet.service.exchange.api.ExchangeException; import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate; +import com.m2049r.xmrwallet.util.NetCipherHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -48,26 +49,21 @@ import javax.xml.parsers.ParserConfigurationException; import okhttp3.Call; import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; public class ExchangeApiImpl implements ExchangeApi { - @NonNull - private final OkHttpClient okHttpClient; @NonNull private final HttpUrl baseUrl; //so we can inject the mockserver url @VisibleForTesting - public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient, @NonNull final HttpUrl baseUrl) { - this.okHttpClient = okHttpClient; + public ExchangeApiImpl(@NonNull final HttpUrl baseUrl) { this.baseUrl = baseUrl; } - public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) { - this(okHttpClient, HttpUrl.parse("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml")); + public ExchangeApiImpl() { + this(HttpUrl.parse("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml")); // data is daily and is refreshed around 16:00 CET every working day } @@ -122,9 +118,8 @@ public class ExchangeApiImpl implements ExchangeApi { } } - final Request httpRequest = createHttpRequest(baseUrl); - - okHttpClient.newCall(httpRequest).enqueue(new okhttp3.Callback() { + final NetCipherHelper.Request httpRequest = new NetCipherHelper.Request(baseUrl); + httpRequest.enqueue(new okhttp3.Callback() { @Override public void onFailure(final Call call, final IOException ex) { callback.onError(ex); @@ -155,13 +150,6 @@ public class ExchangeApiImpl implements ExchangeApi { }); } - private Request createHttpRequest(final HttpUrl url) { - return new Request.Builder() - .url(url) - .get() - .build(); - } - final private Map fxEntries = new HashMap<>(); private Calendar fxDate = null; private Calendar fetchDate = null; diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/exchange/kraken/ExchangeApiImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/exchange/kraken/ExchangeApiImpl.java index 7d9a038a..ab36259e 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/exchange/kraken/ExchangeApiImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/exchange/kraken/ExchangeApiImpl.java @@ -24,6 +24,7 @@ import com.m2049r.xmrwallet.service.exchange.api.ExchangeCallback; import com.m2049r.xmrwallet.service.exchange.api.ExchangeException; import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate; import com.m2049r.xmrwallet.util.Helper; +import com.m2049r.xmrwallet.util.NetCipherHelper; import org.json.JSONArray; import org.json.JSONException; @@ -33,27 +34,21 @@ import java.io.IOException; import okhttp3.Call; import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; import okhttp3.Response; import timber.log.Timber; public class ExchangeApiImpl implements ExchangeApi { - @NonNull - private final OkHttpClient okHttpClient; - private final HttpUrl baseUrl; //so we can inject the mockserver url @VisibleForTesting - public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient, final HttpUrl baseUrl) { - this.okHttpClient = okHttpClient; + public ExchangeApiImpl(final HttpUrl baseUrl) { this.baseUrl = baseUrl; } - public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) { - this(okHttpClient, HttpUrl.parse("https://api.kraken.com/0/public/Ticker")); + public ExchangeApiImpl() { + this(HttpUrl.parse("https://api.kraken.com/0/public/Ticker")); } @Override @@ -86,9 +81,8 @@ public class ExchangeApiImpl implements ExchangeApi { .addQueryParameter("pair", base + (quote.equals("BTC") ? "XBT" : quote)) .build(); - final Request httpRequest = createHttpRequest(url); - - okHttpClient.newCall(httpRequest).enqueue(new okhttp3.Callback() { + final NetCipherHelper.Request httpRequest = new NetCipherHelper.Request(url); + httpRequest.enqueue(new okhttp3.Callback() { @Override public void onFailure(final Call call, final IOException ex) { callback.onError(ex); @@ -127,11 +121,4 @@ public class ExchangeApiImpl implements ExchangeApi { callback.onError(ex); } } - - private Request createHttpRequest(final HttpUrl url) { - return new Request.Builder() - .url(url) - .get() - .build(); - } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/exchange/krakenEcb/ExchangeApiImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/exchange/krakenEcb/ExchangeApiImpl.java index 69ecafe4..b8021b9e 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/exchange/krakenEcb/ExchangeApiImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/exchange/krakenEcb/ExchangeApiImpl.java @@ -35,13 +35,6 @@ import timber.log.Timber; public class ExchangeApiImpl implements ExchangeApi { static public final String BASE_FIAT = "EUR"; - @NonNull - private final OkHttpClient okHttpClient; - - public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) { - this.okHttpClient = okHttpClient; - } - @Override public void queryExchangeRate(@NonNull final String baseCurrency, @NonNull final String quoteCurrency, @NonNull final ExchangeCallback callback) { @@ -61,13 +54,13 @@ public class ExchangeApiImpl implements ExchangeApi { final String quote = Helper.BASE_CRYPTO.equals(baseCurrency) ? quoteCurrency : baseCurrency; final ExchangeApi krakenApi = - new com.m2049r.xmrwallet.service.exchange.kraken.ExchangeApiImpl(okHttpClient); + new com.m2049r.xmrwallet.service.exchange.kraken.ExchangeApiImpl(); krakenApi.queryExchangeRate(Helper.BASE_CRYPTO, BASE_FIAT, new ExchangeCallback() { @Override public void onSuccess(final ExchangeRate krakenRate) { Timber.d("kraken = %f", krakenRate.getRate()); final ExchangeApi ecbApi = - new com.m2049r.xmrwallet.service.exchange.ecb.ExchangeApiImpl(okHttpClient); + new com.m2049r.xmrwallet.service.exchange.ecb.ExchangeApiImpl(); ecbApi.queryExchangeRate(BASE_FIAT, quote, new ExchangeCallback() { @Override public void onSuccess(final ExchangeRate ecbRate) { diff --git a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java index b27ae60e..c22e3220 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java +++ b/app/src/main/java/com/m2049r/xmrwallet/service/shift/sideshift/network/SideShiftApiImpl.java @@ -30,7 +30,7 @@ import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderParameters; import com.m2049r.xmrwallet.service.shift.sideshift.api.QueryOrderStatus; import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote; import com.m2049r.xmrwallet.service.shift.sideshift.api.SideShiftApi; -import com.m2049r.xmrwallet.util.OkHttpHelper; +import com.m2049r.xmrwallet.util.NetCipherHelper; import org.json.JSONException; import org.json.JSONObject; @@ -39,22 +39,14 @@ import java.io.IOException; import okhttp3.Call; import okhttp3.HttpUrl; -import okhttp3.MediaType; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; import okhttp3.Response; import timber.log.Timber; public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall { - @NonNull - private final OkHttpClient okHttpClient; - private final HttpUrl baseUrl; - public SideShiftApiImpl(@NonNull final OkHttpClient okHttpClient, final HttpUrl baseUrl) { - this.okHttpClient = okHttpClient; + public SideShiftApiImpl(final HttpUrl baseUrl) { this.baseUrl = baseUrl; } @@ -95,9 +87,9 @@ public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall { final HttpUrl url = baseUrl.newBuilder() .addPathSegments(path) .build(); - final Request httpRequest = createHttpRequest(request, url); - okHttpClient.newCall(httpRequest).enqueue(new okhttp3.Callback() { + NetCipherHelper.Request httpRequest = new NetCipherHelper.Request(url, request); + httpRequest.enqueue(new okhttp3.Callback() { @Override public void onFailure(final Call call, final IOException ex) { callback.onError(ex); @@ -127,13 +119,4 @@ public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall { } }); } - - private Request createHttpRequest(final JSONObject request, final HttpUrl url) { - if (request != null) { - final RequestBody body = RequestBody.create(request.toString(), MediaType.parse("application/json")); - return OkHttpHelper.getPostRequest(url, body); - } else { - return OkHttpHelper.getGetRequest(url); - } - } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java index d192f4d4..c5c6c5bf 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java +++ b/app/src/main/java/com/m2049r/xmrwallet/util/Helper.java @@ -84,7 +84,7 @@ public class Helper { static public final long ONE_XMR = Math.round(Math.pow(10, Helper.XMR_DECIMALS)); static public final boolean SHOW_EXCHANGERATES = true; - static public final boolean ALLOW_SHIFT = true; + static public boolean ALLOW_SHIFT = false; static private final String WALLET_DIR = "wallets"; static private final String MONERO_DIR = "monero"; @@ -606,30 +606,4 @@ public class Helper { static public boolean preventScreenshot() { return !(BuildConfig.DEBUG || BuildConfig.FLAVOR_type.equals("alpha")); } - - static public final int STALE_NODE_HOURS = 2; - - static public void showTimeDifference(TextView view, long timeInSeconds) { - final Context ctx = view.getContext(); - final long now = Calendar.getInstance().getTimeInMillis() / 1000; - final long secs = (now - timeInSeconds); - final long mins = secs / 60; // in minutes - final long hours = mins / 60; - final long days = hours / 24; - String msg; - if (mins < 2) { - msg = ctx.getString(R.string.node_updated_now, secs); - } else if (hours < 2) { - msg = ctx.getString(R.string.node_updated_mins, mins); - } else if (days < 2) { - msg = ctx.getString(R.string.node_updated_hours, hours); - } else { - msg = ctx.getString(R.string.node_updated_days, days); - } - view.setText(msg); - if (hours >= STALE_NODE_HOURS) - view.setTextColor(ThemeHelper.getThemedColor(view.getContext(), R.attr.colorError)); - else - view.setTextColor(ThemeHelper.getThemedColor(view.getContext(), android.R.attr.textColorPrimary)); - } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/NetCipherHelper.java b/app/src/main/java/com/m2049r/xmrwallet/util/NetCipherHelper.java new file mode 100644 index 00000000..95bd61e2 --- /dev/null +++ b/app/src/main/java/com/m2049r/xmrwallet/util/NetCipherHelper.java @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2021 m2049r + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.m2049r.xmrwallet.util; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +import com.burgstaller.okhttp.AuthenticationCacheInterceptor; +import com.burgstaller.okhttp.CachingAuthenticatorDecorator; +import com.burgstaller.okhttp.digest.CachingAuthenticator; +import com.burgstaller.okhttp.digest.Credentials; +import com.burgstaller.okhttp.digest.DigestAuthenticator; + +import org.json.JSONObject; + +import java.io.IOException; +import java.net.Proxy; +import java.util.ArrayList; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; + +import info.guardianproject.netcipher.client.StrongOkHttpClientBuilder; +import info.guardianproject.netcipher.proxy.OrbotHelper; +import info.guardianproject.netcipher.proxy.SignatureUtils; +import info.guardianproject.netcipher.proxy.StatusCallback; +import lombok.RequiredArgsConstructor; +import lombok.ToString; +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.HttpUrl; +import okhttp3.MediaType; +import okhttp3.OkHttpClient; +import okhttp3.RequestBody; +import okhttp3.Response; +import timber.log.Timber; + +@RequiredArgsConstructor +public class NetCipherHelper implements StatusCallback { + public static final String USER_AGENT = "Monerujo/1.0"; + public static final int HTTP_TIMEOUT = 1000; //ms + public static final int TOR_TIMEOUT_CONNECT = 5000; //ms + public static final int TOR_TIMEOUT = 2000; //ms + + public interface OnStatusChangedListener { + void connected(); + + void disconnected(); + + void notInstalled(); + + void notEnabled(); + } + + final private Context context; + final private OrbotHelper orbot; + + @SuppressLint("StaticFieldLeak") + private static NetCipherHelper Instance; + + public static void createInstance(Context context) { + if (Instance == null) { + synchronized (NetCipherHelper.class) { + if (Instance == null) { + final Context applicationContext = context.getApplicationContext(); + Instance = new NetCipherHelper(applicationContext, OrbotHelper.get(context).statusTimeout(5000)); + } + } + } + } + + public static NetCipherHelper getInstance() { + if (Instance == null) throw new IllegalStateException("NetCipherHelper is null"); + return Instance; + } + + private OkHttpClient client; + + private void createTorClient(Intent statusIntent) { + String orbotStatus = statusIntent.getStringExtra(OrbotHelper.EXTRA_STATUS); + if (orbotStatus == null) throw new IllegalStateException("status is null"); + if (!orbotStatus.equals(OrbotHelper.STATUS_ON)) + throw new IllegalStateException("Orbot is not ON"); + try { + final OkHttpClient.Builder okBuilder = new OkHttpClient.Builder() + .connectTimeout(TOR_TIMEOUT_CONNECT, TimeUnit.MILLISECONDS) + .writeTimeout(TOR_TIMEOUT, TimeUnit.MILLISECONDS) + .readTimeout(TOR_TIMEOUT, TimeUnit.MILLISECONDS); + client = new StrongOkHttpClientBuilder(context) + .withSocksProxy() + .applyTo(okBuilder, statusIntent) + .build(); + Helper.ALLOW_SHIFT = false; // no shifting with Tor + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + private void createClearnetClient() { + try { + client = new OkHttpClient.Builder() + .connectTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS) + .writeTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS) + .readTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS) + .build(); + Helper.ALLOW_SHIFT = true; + } catch (Exception ex) { + throw new IllegalStateException(ex); + } + } + + private OnStatusChangedListener onStatusChangedListener; + + public static void deregister() { + getInstance().onStatusChangedListener = null; + } + + public static void register(OnStatusChangedListener listener) { + final NetCipherHelper me = getInstance(); + me.onStatusChangedListener = listener; + + // NOT_INSTALLED is dealt with through the callbacks + me.orbot.removeStatusCallback(me) // make sure we are registered just once + .addStatusCallback(me); + + // deal with org.torproject.android.intent.action.STATUS = STARTS_DISABLED + me.context.registerReceiver(orbotStatusReceiver, new IntentFilter(OrbotHelper.ACTION_STATUS)); + + me.startTor(); + } + + // for StatusCallback + public enum Status { + STARTING, + ENABLED, + STOPPING, + DISABLED, + NOT_INSTALLED, + NOT_ENABLED, + UNKNOWN; + } + + private Status status = Status.UNKNOWN; + + @Override + public void onStarting() { + Timber.d("onStarting"); + status = Status.STARTING; + } + + @Override + public void onEnabled(Intent statusIntent) { + Timber.d("onEnabled"); + if (getTorPref() != Status.ENABLED) return; // do we want Tor? + createTorClient(statusIntent); + status = Status.ENABLED; + if (onStatusChangedListener != null) { + new Thread(() -> onStatusChangedListener.connected()).start(); + } + } + + @Override + public void onStopping() { + Timber.d("onStopping"); + status = Status.STOPPING; + } + + @Override + public void onDisabled() { + Timber.d("onDisabled"); + createClearnetClient(); + status = Status.DISABLED; + if (onStatusChangedListener != null) { + new Thread(() -> onStatusChangedListener.disconnected()).start(); + } + } + + @Override + public void onStatusTimeout() { + Timber.d("onStatusTimeout"); + createClearnetClient(); + // (timeout does not not change the status) + if (onStatusChangedListener != null) { + new Thread(() -> onStatusChangedListener.disconnected()).start(); + } + orbotInit = false; // do init() next time we try to open Tor + } + + @Override + public void onNotYetInstalled() { + Timber.d("onNotYetInstalled"); + // never mind then + orbot.removeStatusCallback(this); + createClearnetClient(); + status = Status.NOT_INSTALLED; + if (onStatusChangedListener != null) { + new Thread(() -> onStatusChangedListener.notInstalled()).start(); + } + } + + // user has not enabled background Orbot starts + public void onNotEnabled() { + Timber.d("onNotEnabled"); + // keep the callback in case they turn it on manually + setTorPref(Status.DISABLED); + createClearnetClient(); + status = Status.NOT_ENABLED; + if (onStatusChangedListener != null) { + new Thread(() -> onStatusChangedListener.notEnabled()).start(); + } + } + + static public Status getStatus() { + return getInstance().status; + } + + public void toggle() { + switch (getStatus()) { + case ENABLED: + onDisabled(); + setTorPref(Status.DISABLED); + break; + case DISABLED: + setTorPref(Status.ENABLED); + startTor(); + break; + } + } + + private boolean orbotInit = false; + + private void startTor() { + if (!isOrbotInstalled()) { + onNotYetInstalled(); + } else if (getTorPref() == Status.DISABLED) { + onDisabled(); + } else if (!orbotInit) { + orbotInit = orbot.init(); + } else { + orbot.requestStart(context); + } + } + + // extracted from OrbotHelper + private boolean isOrbotInstalled() { + ArrayList hashes = new ArrayList<>(); + // Tor Project signing key + hashes.add("A4:54:B8:7A:18:47:A8:9E:D7:F5:E7:0F:BA:6B:BA:96:F3:EF:29:C2:6E:09:81:20:4F:E3:47:BF:23:1D:FD:5B"); + // f-droid.org signing key + hashes.add("A7:02:07:92:4F:61:FF:09:37:1D:54:84:14:5C:4B:EE:77:2C:55:C1:9E:EE:23:2F:57:70:E1:82:71:F7:CB:AE"); + + return null != SignatureUtils.validateBroadcastIntent(context, + OrbotHelper.getOrbotStartIntent(context), + hashes, false); + } + + + static public boolean hasClient() { + return getInstance().client != null; + } + + static public boolean isTor() { + return getStatus() == Status.ENABLED; + } + + static public String getProxy() { + if (!isTor()) return ""; + final Proxy proxy = getInstance().client.proxy(); + if (proxy == null) return ""; + return proxy.address().toString().substring(1); + } + + @ToString + static public class Request { + final HttpUrl url; + final String json; + final String username; + final String password; + + public Request(final HttpUrl url, final String json, final String username, final String password) { + this.url = url; + this.json = json; + this.username = username; + this.password = password; + } + + public Request(final HttpUrl url, final JSONObject json) { + this(url, json == null ? null : json.toString(), null, null); + } + + public Request(final HttpUrl url) { + this(url, null, null, null); + } + + public void enqueue(Callback callback) { + newCall().enqueue(callback); + } + + public Response execute() throws IOException { + return newCall().execute(); + } + + private Call newCall() { + return getClient().newCall(getRequest()); + } + + private OkHttpClient getClient() { + final OkHttpClient client = getInstance().client; + if ((username != null) && (!username.isEmpty())) { + final DigestAuthenticator authenticator = new DigestAuthenticator(new Credentials(username, password)); + final Map authCache = new ConcurrentHashMap<>(); + return client.newBuilder() + .authenticator(new CachingAuthenticatorDecorator(authenticator, authCache)) + .addInterceptor(new AuthenticationCacheInterceptor(authCache)) + .build(); + // TODO: maybe cache & reuse the client for these credentials? + } else { + return client; + } + } + + private okhttp3.Request getRequest() { + final okhttp3.Request.Builder builder = + new okhttp3.Request.Builder() + .url(url) + .header("User-Agent", USER_AGENT); + if (json != null) { + builder.post(RequestBody.create(json, MediaType.parse("application/json"))); + } else { + builder.get(); + } + return builder.build(); + } + } + + private static final String PREFS_NAME = "tor"; + private static final String PREFS_STATUS = "status"; + private Status currentPref = Status.UNKNOWN; + + private Status getTorPref() { + if (currentPref != Status.UNKNOWN) return currentPref; + currentPref = Status.valueOf(context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + .getString(PREFS_STATUS, "DISABLED")); + return currentPref; + } + + private void setTorPref(Status status) { + if (getTorPref() == status) return; // no change + context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE) + .edit() + .putString(PREFS_STATUS, status.name()) + .apply(); + currentPref = status; + } + + private static final BroadcastReceiver orbotStatusReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Timber.d("%s/%s", intent.getAction(), intent.getStringExtra(OrbotHelper.EXTRA_STATUS)); + if (OrbotHelper.ACTION_STATUS.equals(intent.getAction())) { + if (OrbotHelper.STATUS_STARTS_DISABLED.equals(intent.getStringExtra(OrbotHelper.EXTRA_STATUS))) { + getInstance().onNotEnabled(); + } + } + } + }; + + public void installOrbot(Activity host) { + host.startActivity(OrbotHelper.getOrbotInstallIntent(context)); + } +} diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/OkHttpHelper.java b/app/src/main/java/com/m2049r/xmrwallet/util/OkHttpHelper.java deleted file mode 100644 index ecaa5e6b..00000000 --- a/app/src/main/java/com/m2049r/xmrwallet/util/OkHttpHelper.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2017 m2049r - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.m2049r.xmrwallet.util; - -import java.util.concurrent.TimeUnit; - -import okhttp3.HttpUrl; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.RequestBody; - -public class OkHttpHelper { - static private OkHttpClient Singleton; - - static public OkHttpClient getOkHttpClient() { - if (Singleton == null) { - synchronized (OkHttpHelper.class) { - if (Singleton == null) { - Singleton = new OkHttpClient(); - } - } - } - return Singleton; - } - - public static final int HTTP_TIMEOUT = 1000; //ms - - static private OkHttpClient EagerSingleton; - - static public OkHttpClient getEagerClient() { - if (EagerSingleton == null) { - synchronized (OkHttpHelper.class) { - if (EagerSingleton == null) { - EagerSingleton = new OkHttpClient.Builder() - .connectTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS) - .writeTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS) - .readTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS) - .build(); - } - } - } - return EagerSingleton; - } - - static final public String USER_AGENT = "Monerujo/1.0"; - - static public Request getPostRequest(HttpUrl url, RequestBody requestBody) { - return new Request.Builder().url(url).post(requestBody) - .header("User-Agent", USER_AGENT) - .build(); - } - - static public Request getGetRequest(HttpUrl url) { - return new Request.Builder().url(url).get() - .header("User-Agent", USER_AGENT) - .build(); - } -} diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/OnionHelper.java b/app/src/main/java/com/m2049r/xmrwallet/util/OnionHelper.java new file mode 100644 index 00000000..f5a416a5 --- /dev/null +++ b/app/src/main/java/com/m2049r/xmrwallet/util/OnionHelper.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 m2049r + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.m2049r.xmrwallet.util; + +public class OnionHelper { + + public static boolean isOnionHost(String hostname) { + return hostname.endsWith(".onion"); + } +} diff --git a/app/src/main/java/com/m2049r/xmrwallet/util/ServiceHelper.java b/app/src/main/java/com/m2049r/xmrwallet/util/ServiceHelper.java index 6221682b..27622916 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/util/ServiceHelper.java +++ b/app/src/main/java/com/m2049r/xmrwallet/util/ServiceHelper.java @@ -19,6 +19,6 @@ public class ServiceHelper { } static public ExchangeApi getExchangeApi() { - return new com.m2049r.xmrwallet.service.exchange.krakenEcb.ExchangeApiImpl(OkHttpHelper.getOkHttpClient()); + return new com.m2049r.xmrwallet.service.exchange.krakenEcb.ExchangeApiImpl(); } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeEditText.java b/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeEditText.java index deeabc6a..26ff14b7 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeEditText.java +++ b/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeEditText.java @@ -344,8 +344,8 @@ public class ExchangeEditText extends LinearLayout { if (rate > 0) { tvAmountB.setText(Helper.getFormattedAmount(rate * amount, getCurrencyB() == 0)); } else { - tvAmountB.setText(null); - Timber.w("No rate!"); + tvAmountB.setText("--"); + Timber.d("No rate!"); } } diff --git a/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeView.java b/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeView.java index aacce64c..3208f720 100644 --- a/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeView.java +++ b/app/src/main/java/com/m2049r/xmrwallet/widget/ExchangeView.java @@ -321,23 +321,13 @@ public class ExchangeView extends LinearLayout { @Override public void onSuccess(final ExchangeRate exchangeRate) { if (isAttachedToWindow()) - new Handler(Looper.getMainLooper()).post(new Runnable() { - @Override - public void run() { - exchange(exchangeRate); - } - }); + new Handler(Looper.getMainLooper()).post(() -> exchange(exchangeRate)); } @Override public void onError(final Exception e) { Timber.e(e.getLocalizedMessage()); - new Handler(Looper.getMainLooper()).post(new Runnable() { - @Override - public void run() { - exchangeFailed(); - } - }); + new Handler(Looper.getMainLooper()).post(() -> exchangeFailed()); } }); } @@ -362,11 +352,10 @@ public class ExchangeView extends LinearLayout { } tvAmountB.setText(xmrAmount); } else { // no XMR currency - cannot happen! - Timber.e("No XMR currency!"); - setXmr(null); - notXmrAmount = null; - return; + throw new IllegalStateException("No XMR currency!"); } + if (rate == 0) + tvAmountB.setText("--"); } boolean prepareExchange() { diff --git a/app/src/main/java/info/guardianproject/netcipher/client/StrongOkHttpClientBuilder.java b/app/src/main/java/info/guardianproject/netcipher/client/StrongOkHttpClientBuilder.java new file mode 100644 index 00000000..60ee5a43 --- /dev/null +++ b/app/src/main/java/info/guardianproject/netcipher/client/StrongOkHttpClientBuilder.java @@ -0,0 +1,115 @@ +/* + * Copyright 2012-2016 Nathan Freitas + * Copyright 2015 str4d + * Portions Copyright (c) 2016 CommonsWare, LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package info.guardianproject.netcipher.client; + +import android.content.Context; +import android.content.Intent; +import javax.net.ssl.SSLSocketFactory; +import okhttp3.OkHttpClient; +import okhttp3.Request; + +/** + * Creates an OkHttpClient using NetCipher configuration. Use + * build() if you have no other OkHttpClient configuration + * that you need to perform. Or, use applyTo() to augment an + * existing OkHttpClient.Builder with NetCipher. + */ +public class StrongOkHttpClientBuilder extends + StrongBuilderBase { + /** + * Creates a StrongOkHttpClientBuilder using the strongest set + * of options for security. Use this if the strongest set of + * options is what you want; otherwise, create a + * builder via the constructor and configure it as you see fit. + * + * @param context any Context will do + * @return a configured StrongOkHttpClientBuilder + * @throws Exception + */ + static public StrongOkHttpClientBuilder forMaxSecurity(Context context) + throws Exception { + return(new StrongOkHttpClientBuilder(context) + .withBestProxy()); + } + + /** + * Creates a builder instance. + * + * @param context any Context will do; builder will hold onto + * Application context + */ + public StrongOkHttpClientBuilder(Context context) { + super(context); + } + + /** + * Copy constructor. + * + * @param original builder to clone + */ + public StrongOkHttpClientBuilder(StrongOkHttpClientBuilder original) { + super(original); + } + + /** + * OkHttp3 does not support SOCKS proxies: + * https://github.com/square/okhttp/issues/2315 + * + * @return false + */ + @Override + public boolean supportsSocksProxy() { + return(true); + } + + /** + * {@inheritDoc} + */ + @Override + public OkHttpClient build(Intent status) { + return(applyTo(new OkHttpClient.Builder(), status).build()); + } + + /** + * Adds NetCipher configuration to an existing OkHttpClient.Builder, + * in case you have additional configuration that you wish to + * perform. + * + * @param builder a new or partially-configured OkHttpClient.Builder + * @return the same builder + */ + public OkHttpClient.Builder applyTo(OkHttpClient.Builder builder, Intent status) { + SSLSocketFactory factory=buildSocketFactory(); + + if (factory!=null) { + builder.sslSocketFactory(factory); + } + + return(builder + .proxy(buildProxy(status))); + } + + @Override + protected String get(Intent status, OkHttpClient connection, + String url) throws Exception { + Request request=new Request.Builder().url(url).build(); + + return(connection.newCall(request).execute().body().string()); + } +} diff --git a/app/src/main/res/color/btn_color_selector.xml b/app/src/main/res/color/btn_color_selector.xml index 046edf03..3a736463 100644 --- a/app/src/main/res/color/btn_color_selector.xml +++ b/app/src/main/res/color/btn_color_selector.xml @@ -1,5 +1,5 @@ - - + + diff --git a/app/src/main/res/drawable/ic_info_outline_black_24dp.xml b/app/src/main/res/drawable/ic_info_outline_black_24dp.xml new file mode 100644 index 00000000..f9423167 --- /dev/null +++ b/app/src/main/res/drawable/ic_info_outline_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_network_clearnet.xml b/app/src/main/res/drawable/ic_network_clearnet.xml new file mode 100644 index 00000000..bc817b36 --- /dev/null +++ b/app/src/main/res/drawable/ic_network_clearnet.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_network_tor_on.xml b/app/src/main/res/drawable/ic_network_tor_on.xml new file mode 100644 index 00000000..23640f02 --- /dev/null +++ b/app/src/main/res/drawable/ic_network_tor_on.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/fragment_help.xml b/app/src/main/res/layout/fragment_help.xml index bce7ea17..7ad2eac2 100644 --- a/app/src/main/res/layout/fragment_help.xml +++ b/app/src/main/res/layout/fragment_help.xml @@ -7,26 +7,14 @@ android:paddingTop="8dp" android:paddingEnd="16dp"> - - - - - - - + android:layout_marginTop="@dimen/header_top" + android:autoLink="web" + android:gravity="start" + android:textSize="14sp" + tools:text="@string/menu_help" /> diff --git a/app/src/main/res/layout/fragment_login.xml b/app/src/main/res/layout/fragment_login.xml index 7e65c361..652115f9 100644 --- a/app/src/main/res/layout/fragment_login.xml +++ b/app/src/main/res/layout/fragment_login.xml @@ -29,28 +29,49 @@ + + + + - - + android:layout_height="0dp" + android:layout_alignTop="@+id/ibNetwork" + android:layout_alignBottom="@id/ibNetwork" + android:layout_toStartOf="@+id/ibRenew" + android:layout_toEndOf="@+id/ibNetwork"> + tools:text="Last Block: 2 minutes ago" /> diff --git a/app/src/main/res/layout/fragment_receive.xml b/app/src/main/res/layout/fragment_receive.xml index 0290b015..c712cf58 100644 --- a/app/src/main/res/layout/fragment_receive.xml +++ b/app/src/main/res/layout/fragment_receive.xml @@ -111,8 +111,9 @@ android:text="@string/label_receive_info_gen_qr_code" android:textAlignment="center" android:textSize="16sp" - android:visibility="gone" - card_view:drawableStartCompat="@drawable/ic_info_outline_gray_24dp" /> + android:textColor="#2D1A2E" + android:visibility="visible" + card_view:drawableStartCompat="@drawable/ic_info_outline_black_24dp" /> - + android:layout_marginBottom="16dp"> + + + + + + android:text="@string/tx_list_failed_text" /> diff --git a/app/src/main/res/values-cat/help.xml b/app/src/main/res/values-cat/help.xml index 3b3635c0..a72ebbdd 100644 --- a/app/src/main/res/values-cat/help.xml +++ b/app/src/main/res/values-cat/help.xml @@ -4,11 +4,11 @@

      Crear Portamonedes - New

      Per si necessiteu una nova adreça de Monero!

      Introduïu un nom i contrasenya únics del portamonedes. -         La contrasenya s’utilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.

      + La contrasenya s’utilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.

      Apunteu la vostra llavor mnemotècnica!

      A la pantalla següent trobareu la vostra "Llavor Mnemotècnica" de 25 paraules. -         Aquestes són les úniques dades necessàries per a recuperar el vostre portamonedes i obtenir accés total als vostres fons. -         Mantenir-la segura i privada és molt important ja que permet que qualsevol persona tingui accés total als vostres fons!.

      + Aquestes són les úniques dades necessàries per a recuperar el vostre portamonedes i obtenir accés total als vostres fons. + Mantenir-la segura i privada és molt important ja que permet que qualsevol persona tingui accés total als vostres fons!.

      Si perdeu la contrasenya del portamonedes encara podrieu recuperar-lo amb la llavor Mnemotècnica.

      La llavor Mnemotècnica tampoc no es pot canviar mai, i si és robada o compromesa d’alguna manera haureu de traslladar els vostres fons a un nou portamonedes (amb una nova llavor mnemotècnica). Per tant, es recomana que feu còpies de seguretat de la vostra llavor mnemotècnica escrivint-la i emmagatzemant-la a múltiple llocs de forma segura.

      ]]>
      @@ -17,7 +17,7 @@

      Crear Portamonedes - Llavor

      Si ja teniu una adreça Monero i voleu recuperar les transaccions de la blockchain!

      Introduïu un nom i contrasenya únics del portamonedes. -         La contrasenya s’utilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.

      + La contrasenya s’utilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.

      Introduïu la Llavor en el camp \"Llavor Mnemotècnica\".

      Introduïu el número de bloc de la primera transacció realitzada en aquesta adreça en el camp "Restaurar Alçada". També podeu utilitzar una data en el format AAAA-MM-DD. Si no esteu segurs, introduïu una data / alçada de bloc aproximada abans d’haver fer servir aquesta adreça del portamonedes.

      ]]>
      @@ -36,7 +36,7 @@

      Introduïu un nom i contrasenya únics del portamonedes. La contrasenya s’utilitza per protegir les dades de la seva cartera al dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.

      Introduïu la vostra Adreça Monero en el camp \"Adreça Pública\" i ompliu \"Clau de Visualització\" i \"Clau de Despesa\"

      Introduïu el número de bloc de la primera transacció realitzada en aquesta adreça en el -         camp "Restaurar Alçada". També podeu utilitzar una data en el format AAAA-MM-DD. Si no esteu segurs, introduïu una data / alçada de bloc aproximada abans d’haver fer servir aquesta adreça del portamonedes.

      + camp "Restaurar Alçada". També podeu utilitzar una data en el format AAAA-MM-DD. Si no esteu segurs, introduïu una data / alçada de bloc aproximada abans d’haver fer servir aquesta adreça del portamonedes.

      ]]>
      Clau Mnemotècnica Aquestes són les úniques dades necessàries per a recuperar el vostre portamonedes i obtenir accés total als vostres fons. -         Mantenir-la segura i privada és molt important ja que permet que qualsevol persona tingui accés total als vostres fons! Si no us heu escrit en cap lloc segur, feu-ho! + Mantenir-la segura i privada és molt important ja que permet que qualsevol persona tingui accés total als vostres fons! Si no us heu escrit en cap lloc segur, feu-ho!

      Contrasenya de Recuperació d’Arxius del Portamonedes

      - Assegureu-vos que heu escrit aquesta contrasenya. Si restabliu el dispositiu o desinstal·leu l’aplicació, la necessitarà per tornar a accedir al seu portamonedes.
      + Assegureu-vos que heu escrit aquesta contrasenya. Si restabliu el dispositiu o desinstal·leu l’aplicació, la necessitarà per tornar a accedir al seu portamonedes.

      CrAzYsenya

      Si la contrasenya que es mostra aquí és de 52 caràcters alfanumèrics en grups de 4 - felicitats! -        Els fitxers del portamonedes estan protegits amb una clau de 256 bits generada per la funció de seguretat del vostre dispositiu basades en la contrasenya que heu triat (durant la creació o al canviar-la). Això ho fa extremadament difícil de piratejar!
      + Els fitxers del portamonedes estan protegits amb una clau de 256 bits generada per la funció de seguretat del vostre dispositiu basades en la contrasenya que heu triat (durant la creació o al canviar-la). Això ho fa extremadament difícil de piratejar!
      Aquesta opció és obligatoria per a tots els nous portamonedes.

      Contrasenya de Llegat

      - Si veieu la vostra contrasenya aquí, els fitxers del portamonedes no estan tan segurs com quan s’utilitza la CrAzYsenya. Per solucionar-ho, seleccioneu \"Canviar Contrasenya\" des del menú. Després d’entrar una nova contrasenya (potser fins i tot la mateixa que abans) l’aplicació generarà una CrAzYsenya per a protegir els vostres arxius del portamonedes. Anoteu-la! + Si veieu la vostra contrasenya aquí, els fitxers del portamonedes no estan tan segurs com quan s’utilitza la CrAzYsenya. Per solucionar-ho, seleccioneu \"Canviar Contrasenya\" des del menú. Després d’entrar una nova contrasenya (potser fins i tot la mateixa que abans) l’aplicació generarà una CrAzYsenya per a protegir els vostres arxius del portamonedes. Anoteu-la!

      CrAzYsenya del Portamonedes

      - Si mai necessiteu tornar a instal·lar Monerujo (per exemple, després de restablir el telèfon o canviar-lo per un de nou) o voleu utilitzar els arxius del portamonedes en un altre dispositiu o PC, cal que ho feu utilitzant aquesta Contrasenya de Recuperació (CrAzYsenya) per tornar a accedir al vostre portamonedes.
      -        En seleccionar \"Canviar Contrasenya\" des del menú, podeu triar una nova contrasenya. Aneu amb compte que això generarà una nova Contrasenya de Recuperació (CrAzYsenya). Anoteu-la! + Si mai necessiteu tornar a instal·lar Monerujo (per exemple, després de restablir el telèfon o canviar-lo per un de nou) o voleu utilitzar els arxius del portamonedes en un altre dispositiu o PC, cal que ho feu utilitzant aquesta Contrasenya de Recuperació (CrAzYsenya) per tornar a accedir al vostre portamonedes.
      + En seleccionar \"Canviar Contrasenya\" des del menú, podeu triar una nova contrasenya. Aneu amb compte que això generarà una nova Contrasenya de Recuperació (CrAzYsenya). Anoteu-la!

      Clau de Visualització

      - La vostra clau de visualització es pot utilitzar per monitoritzar les transaccions entrants al vostre portamonedes sense donar-ne permís per gastar els fons a dins seu. + La vostra clau de visualització es pot utilitzar per monitoritzar les transaccions entrants al vostre portamonedes sense donar-ne permís per gastar els fons a dins seu.

      Clau de Despesa

      La vostra clau de despesa permet a qualsevol persona gastar els Monero associats al seu portamonedes, així que no ho compartiu amb ningú, mantingueu-la segura com la vostra Llavor Mnemotècnica. ]]>
      @@ -75,13 +75,13 @@

      Llista de Portamonedes

      Node

      Monerujo utilitza un node remot per comunicar-se amb la xarxa Monero sense necessitat -         de descarregar i emmagatzemar una còpia de tota la blockchain sencera. Podeu trobar una llista dels nodes remots més populars o aprendre a configurar el vostre propi node remot aquí https://moneroworld.com/

      + de descarregar i emmagatzemar una còpia de tota la blockchain sencera. Podeu trobar una llista dels nodes remots més populars o aprendre a configurar el vostre propi node remot aquí https://moneroworld.com/

      Monerujo té alguns Nodes remots incorporats. Se’n recorda dels últims cinc nodes empleats.

      Portamonedes

      Aquí podeu veure els portamonedes. Es troben a la carpeta monerujo -         dins l’emmagatzematge intern del dispositiu. Podeu utilitzar una aplicació d’exploració d’arxius per veure’ls. Haurieu de fer còpies de seguretat d’aquesta carpeta de manera regular en un emmagatzematge extern al dispositiu en cas que el vostre dispositiu exploti o el robin.

      + dins l’emmagatzematge intern del dispositiu. Podeu utilitzar una aplicació d’exploració d’arxius per veure’ls. Haurieu de fer còpies de seguretat d’aquesta carpeta de manera regular en un emmagatzematge extern al dispositiu en cas que el vostre dispositiu exploti o el robin.

      Seleccioneu una portamonedes per obrir-lo o premeu el botó "+" per crear-ne un de nou. -         O seleccioneu una de les operacions del portamonedes:

      + O seleccioneu una de les operacions del portamonedes:

      Detalls

      Mostra els detalls del portamonedes, la llavor i les seves claus.

      Rebre

      @@ -90,7 +90,7 @@

      Canvia el nom del portamonedes. El canvi de nom no afecta a les còpies de seguretat.

      Còpia de Seguretat

      Feu una còpia del portamonedes en la carpeta backups dins del monerujo -         per a sobreescriure còpies anteriors.

      + per a sobreescriure còpies anteriors.

      Arxiu

      Feu una còpia de seguretat i a continuació elimineu el portamonedes. La còpia es mantindrà a la carpeta backups . Si ja no necessiteu les vostres còpies de seguretat les haureu d’eliminar amb un explorador d’arxius o una aplicació segura.

      ]]> @@ -100,9 +100,9 @@

      Destí

      Aquesta és l’adreça pública del portamonedes on esteu enviant els Monero.

      ID de Pagament

      - Podeu utilitzar un ID de pagament per identificar el motiu pel qual heu enviat a Monero entre dues parts. Això és totalment opcional i privat. Per exemple, això pot permetre a una empresa associar la transacció amb un article que heu comprat. + Podeu utilitzar un ID de pagament per identificar el motiu pel qual heu enviat a Monero entre dues parts. Això és totalment opcional i privat. Per exemple, això pot permetre a una empresa associar la transacció amb un article que heu comprat.

      ID de Transacció

      - Aquest és el vostre ID de transacció que podeu utilitzar per identificar la vostra transacció oculta en un Explorador de Blockchain de Monero com https://xmrchain.net/ + Aquest és el vostre ID de transacció que podeu utilitzar per identificar la vostra transacció oculta en un Explorador de Blockchain de Monero com https://xmrchain.net/

      Clau de Transacció

      Aquesta és la vostra clau privada de transacció, manteniu-la segureta ja que mostrar-la a tercers els revelia quina signatura dins un anell és la vostra, fent que la vostra transacció sigui transparent.

      Bloc

      @@ -122,14 +122,14 @@

      Enviant BTC

      SideShift.ai

      SideShift.ai és un servei de tercers que fa proporciona el canvi de Monero a Bitcoin. -         Nosaltres fem servir l’API SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop d’ull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. L’equip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.

      + Nosaltres fem servir l’API SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop d’ull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. L’equip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.

      Tipus de Canvi SideShift.ai

      A la pantalla \"Quantitat\" es mostraran els paràmetres actuals del servei SideShift.ai. Aquests -         inclouen el tipus de canvi actual, així com els límits de BTC superiors i inferiors. Tingueu en compte que la tarifa no està garantida en aquell mateix moment.

      + inclouen el tipus de canvi actual, així com els límits de BTC superiors i inferiors. Tingueu en compte que la tarifa no està garantida en aquell mateix moment.

      Ordre de compra SideShift.ai

      A la pantalla \"Confirmar\", veureu l’ordre de compra SideShift.ai real. Aquesta comanda és vàlida per a -         un temps limitat: és possible que veieu un compte enrere en el botó \"Gastar\". El tipus de canvi pot -         ser diferent del mostrat en pantalles anteriors.

      + un temps limitat: és possible que veieu un compte enrere en el botó \"Gastar\". El tipus de canvi pot + ser diferent del mostrat en pantalles anteriors.

      Clau Secreta SideShift.ai

      Com que Monerujo només gestiona la part Monero de la vostra transacció, la vostra clau secreta per SideShift.ai es pot utilitzar per fer el seguiment de la part de Bitcoin de la vostra comanda a la pàgina principal de SideShift.ai.

      Compte enrere SideShift.ai!

      @@ -140,14 +140,14 @@

      Enviant BTC

      SideShift.ai

      SideShift.ai és un servei de tercers que fa proporciona el canvi de Monero a Bitcoin. -         Nosaltres fem servir l’API SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop d’ull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. L’equip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.

      + Nosaltres fem servir l’API SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop d’ull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. L’equip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.

      Tipus de Canvi SideShift.ai

      A la pantalla \"Quantitat\" es mostraran els paràmetres actuals del servei SideShift.ai. Aquests -         inclouen el tipus de canvi actual, així com els límits de BTC superiors i inferiors. Tingueu en compte que la tarifa no està garantida en aquell mateix moment.

      + inclouen el tipus de canvi actual, així com els límits de BTC superiors i inferiors. Tingueu en compte que la tarifa no està garantida en aquell mateix moment.

      Ordre de compra SideShift.ai

      A la pantalla \"Confirmar\", veureu l’ordre de compra SideShift.ai real. Aquesta comanda és vàlida per a -         un temps limitat: és possible que veieu un compte enrere en el botó \"Gastar\". El tipus de canvi pot -         ser diferent del mostrat en pantalles anteriors.

      + un temps limitat: és possible que veieu un compte enrere en el botó \"Gastar\". El tipus de canvi pot + ser diferent del mostrat en pantalles anteriors.

      Clau Secreta SideShift.ai

      Com que Monerujo només gestiona la part Monero de la vostra transacció, la vostra clau secreta per SideShift.ai es pot utilitzar per fer el seguiment de la part de Bitcoin de la vostra comanda a la pàgina principal de SideShift.ai.

      Compte enrere SideShift.ai!

      @@ -163,8 +163,8 @@

      El Balanç

      Ajuda! El balanç del meu portamonedes ha desaparegut o consta com a no confirmat!
      No patiu! Quan envieu fons desde el vostre portamonedes part del balanç apareixerà com a no confirmat de forma temporal. - Això succeeix pel fet de com Monero és intercanviat a través de la blockchain i com es produeix el canvi. -        Podeu llegir més sobre el canvi a https://getmonero.org/resources/moneropedia/change.html + Això succeeix pel fet de com Monero és intercanviat a través de la blockchain i com es produeix el canvi. + Podeu llegir més sobre el canvi a https://getmonero.org/resources/moneropedia/change.html

      Llista de Transacció

      Llistat de les transaccions del portamonedes. Els portamonedes de visualització només mostraran les transaccions entrants.

      ]]> @@ -173,49 +173,49 @@

      Nodes

      TL;DR

      Actualitzeu la llista de nodes prement cap avall; marqueu 3–5 nodes per permetre a Monerujo -         triar el millor per a tu!

      + triar el millor per a tu!

      Què és un Node?

      Monerujo utilitza un Node Remot (de vegades també anomenat daemon) per comunicar-se -         la xarxa Monero sense haver de descarregar i emmagatzemar una còpia de -         tota la blockchain mateixa.

      + la xarxa Monero sense haver de descarregar i emmagatzemar una còpia de + tota la blockchain mateixa.

      Llista de Nodes

      Si la llista està buida, podeu afegir nous nodes manualment o deixar que Monerujo -         escanegi la xarxa per vostè. O ambdós. Llegiu …

      + escanegi la xarxa per vostè. O ambdós. Llegiu …

      La llista de nodes mostra tots els nodes coneguts. A més, la marca de temps -         de l’últim bloc conegut per a cada node es mostra sota el nom del node. La icona -         que representa el temps de resposta del node -         (que indica el nivell de connectivitat estimat) -         es mostra al costat de cada node.

      + de l’últim bloc conegut per a cada node es mostra sota el nom del node. La icona + que representa el temps de resposta del node + (que indica el nivell de connectivitat estimat) + es mostra al costat de cada node.

      Es pot marcar qualsevol node de la llista per utilitzar-lo més endevant. -         Es descartaràn els nodes que no hagin estat seleccionats.

      + Es descartaràn els nodes que no hagin estat seleccionats.

      Monerujo escollirà el node òptim (marcat) cada vegada que l’utilitzeu. -         Això ho fa mitjançant la comprovació de l’alçada de bloc (com d’actualitzat -         està el node?), així com el temps de resposta (què tan ràpidament respon el node a les peticions?).

      + Això ho fa mitjançant la comprovació de l’alçada de bloc (com d’actualitzat + està el node?), així com el temps de resposta (què tan ràpidament respon el node a les peticions?).

      La llista s’ordena per aquestes característiques, de manera que el node superior seria el que Monerujo -         triaria ara mateix. La part inferior de la llista mostraria els nodes més lents o no disponibles.

      + triaria ara mateix. La part inferior de la llista mostraria els nodes més lents o no disponibles.

      Afegir Node

      Si premeu el botó "Afegir Node" a la part inferior, se us demanarà -        que introduïu els detalls del node al següent diàleg. -        El "Adreça" és el nom del servidor o adreça IP del node - aquesta és la única -        entrada obligatòria. -        Introduïu el "Port" si el node s’executa en un port no predeterminat (per exemple, 18089). -        També podeu anomenar opcionalment el node, de manera que el pugueu identificar més fàcilment més endavant. -        Alguns nodes necessiten credencials per utilitzar-los. Introduïu el nom d’usuari i -        contrasenya proporcionats als camps corresponents. Ara podeu "Test" aquesta configuració. -        Els "Resultats de les Proves" mostraran l’alçada de bloc, el temps de resposta i l’IP real. -        El resultat també pot ser un error - generalment perquè el nom del servidor proporcionat no és -        accessible dins d’un temps raonable o les credencials són incorrectes. -        O la combinació de nom del servidor/port no apunta cap a un node real de Monero! -        Un cop aprovada la prova (sense error), ja estás llest per prémer "D’acord" per desar iamp; -        marcar aquest node.

      + que introduïu els detalls del node al següent diàleg. + El "Adreça" és el nom del servidor o adreça IP del node - aquesta és la única + entrada obligatòria. + Introduïu el "Port" si el node s’executa en un port no predeterminat (per exemple, 18089). + També podeu anomenar opcionalment el node, de manera que el pugueu identificar més fàcilment més endavant. + Alguns nodes necessiten credencials per utilitzar-los. Introduïu el nom d’usuari i + contrasenya proporcionats als camps corresponents. Ara podeu "Test" aquesta configuració. + Els "Resultats de les Proves" mostraran l’alçada de bloc, el temps de resposta i l’IP real. + El resultat també pot ser un error - generalment perquè el nom del servidor proporcionat no és + accessible dins d’un temps raonable o les credencials són incorrectes. + O la combinació de nom del servidor/port no apunta cap a un node real de Monero! + Un cop aprovada la prova (sense error), ja estás llest per prémer "D’acord" per desar iamp; + marcar aquest node.

      Escanejar Nodes

      A més, podeu escanejar la xarxa per buscar nodes. Monerujo començarà -         escanejant la xarxa per als nodes remots al port 18089. Començarà per preguntar als vostres -         nodes marcats per altres companys de la xarxa P2P de Monero, i després continuarà -         preguntant-los per als seus companys, etc. Si no teniu cap node marcat -         (o no ens informen sobre els seus companys), -         Monerujo anirà directament als nodes de llavor de Monero codificats a dins de Monero. -         L’escaneig s’atura quan troba un total de 10 nodes remots.

      + escanejant la xarxa per als nodes remots al port 18089. Començarà per preguntar als vostres + nodes marcats per altres companys de la xarxa P2P de Monero, i després continuarà + preguntant-los per als seus companys, etc. Si no teniu cap node marcat + (o no ens informen sobre els seus companys), + Monerujo anirà directament als nodes de llavor de Monero codificats a dins de Monero. + L’escaneig s’atura quan troba un total de 10 nodes remots.

      ]]> Ja ho tinc! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-cat/strings.xml b/app/src/main/res/values-cat/strings.xml index 43045e00..d373da1e 100644 --- a/app/src/main/res/values-cat/strings.xml +++ b/app/src/main/res/values-cat/strings.xml @@ -13,7 +13,7 @@ Canvi de contrasenya Segueix escrivint … - Més o menys... … + Més o menys… Vinga, ho pots fer millor! Força bé, pero millorbale … Genial, ets tot un hacker! @@ -236,7 +236,7 @@ Error creant la transacció - - Comissió %1$s + Comissió %1$s (%1$s) fallit - %1$s @@ -425,5 +425,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-de/help.xml b/app/src/main/res/values-de/help.xml index b5828d0d..058272bc 100644 --- a/app/src/main/res/values-de/help.xml +++ b/app/src/main/res/values-de/help.xml @@ -290,4 +290,25 @@ ]]> Hab\'s verstanden! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index f3f4a260..d52df95e 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -232,7 +232,7 @@ Fehler bei Transaktionserstellung - - Gebühr %1$s + Gebühr %1$s (%1$s) fehlgeschlagen - %1$s @@ -426,5 +426,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-el/help.xml b/app/src/main/res/values-el/help.xml index 53374dda..9683ba59 100644 --- a/app/src/main/res/values-el/help.xml +++ b/app/src/main/res/values-el/help.xml @@ -272,4 +272,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 42128fca..1f5b1fcd 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -205,7 +205,7 @@ Σφάλμα Δημιουργίας Συναλλαγής - - Κόμιστρο %1$s + Κόμιστρο %1$s (%1$s) απέτυχε - %1$s @@ -427,5 +427,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-eo/help.xml b/app/src/main/res/values-eo/help.xml index 9ed1f8da..601cd27e 100644 --- a/app/src/main/res/values-eo/help.xml +++ b/app/src/main/res/values-eo/help.xml @@ -45,7 +45,7 @@ ]]> - Krei monujon - Ŝlosiloj

      Se vi restaŭras vian monujon per viaj ŝlosiloj!

      Entajpu unikan monujnomon kaj pasvorton. @@ -316,4 +316,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index 62a1afd8..6f23bed5 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -236,7 +236,7 @@ Krei transakci-eraron - - Kosto %1$s + Kosto %1$s (%1$s) masukcesis - %1$s @@ -427,5 +427,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-es/help.xml b/app/src/main/res/values-es/help.xml index 435cfe78..b816928f 100644 --- a/app/src/main/res/values-es/help.xml +++ b/app/src/main/res/values-es/help.xml @@ -312,4 +312,25 @@ ]]> ¡Entendido! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index f493af9a..1f638e84 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -173,7 +173,7 @@ Error creando la transacción - - Comisión %1$s + Comisión %1$s (%1$s) fallido - %1$s @@ -418,5 +418,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-et/help.xml b/app/src/main/res/values-et/help.xml index 69fd6518..cf7e47a0 100644 --- a/app/src/main/res/values-et/help.xml +++ b/app/src/main/res/values-et/help.xml @@ -292,4 +292,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index fc6a770f..3aeb44f9 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -231,7 +231,7 @@ Viga ülekande genereerimisel - - teenustasu %1$s + teenustasu %1$s (%1$s) ebaõnnestus - %1$s @@ -425,5 +425,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-fr/help.xml b/app/src/main/res/values-fr/help.xml index ee0eb640..58aa78ad 100644 --- a/app/src/main/res/values-fr/help.xml +++ b/app/src/main/res/values-fr/help.xml @@ -310,4 +310,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 70873ffc..09b628f8 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -233,7 +233,7 @@ Erreur de Création de Transaction - - Frais %1$s + Frais %1$s (%1$s) Echoué - %1$s @@ -431,5 +431,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-hu/help.xml b/app/src/main/res/values-hu/help.xml index 94cc8e99..af34a451 100644 --- a/app/src/main/res/values-hu/help.xml +++ b/app/src/main/res/values-hu/help.xml @@ -294,4 +294,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index f83faa0c..0d691ea0 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -230,7 +230,7 @@ Tranzakciólétrehozási hiba - - %1$s díj + %1$s díj (%1$s) sikertelen - %1$s @@ -429,5 +429,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-it/help.xml b/app/src/main/res/values-it/help.xml index ad07df03..84e772f4 100644 --- a/app/src/main/res/values-it/help.xml +++ b/app/src/main/res/values-it/help.xml @@ -295,4 +295,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index ab128ab6..2b2caa3d 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -232,7 +232,7 @@ Errore nella creazione della transazione - - Commissione %1$s + Commissione %1$s (%1$s) fallita - %1$s @@ -431,4 +431,9 @@ Resetta portafogli! Il reset del portafogli cancellerà tutte le informazioni locali (note, nomi di account & sottoindirizzi, chiavi di transazione private, ...)! Procedi solo se il portafogli è corrotto e non si carica! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-ja/help.xml b/app/src/main/res/values-ja/help.xml index 49a8034f..cbc0d117 100644 --- a/app/src/main/res/values-ja/help.xml +++ b/app/src/main/res/values-ja/help.xml @@ -423,4 +423,25 @@ ]]> 分かりました! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index 81bfcb02..da64c028 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -236,7 +236,7 @@ 取引作成エラー - - 手数料 %1$s + 手数料 %1$s (%1$s) 失敗 - %1$s @@ -430,5 +430,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-nb/help.xml b/app/src/main/res/values-nb/help.xml index c02afe55..70cdab6d 100644 --- a/app/src/main/res/values-nb/help.xml +++ b/app/src/main/res/values-nb/help.xml @@ -292,4 +292,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index c47fa2fe..bfe1afc1 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -230,7 +230,7 @@ Error med å lage transaksjon - - Avgift %1$s + Avgift %1$s (%1$s) feila - %1$s @@ -427,5 +427,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-night/styles.xml b/app/src/main/res/values-night/styles.xml index 890a04d8..74ce628b 100644 --- a/app/src/main/res/values-night/styles.xml +++ b/app/src/main/res/values-night/styles.xml @@ -29,7 +29,6 @@ \ No newline at end of file diff --git a/app/src/main/res/values-nl/help.xml b/app/src/main/res/values-nl/help.xml index 2af578dc..60ff8f6b 100644 --- a/app/src/main/res/values-nl/help.xml +++ b/app/src/main/res/values-nl/help.xml @@ -230,4 +230,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 1bd80c76..3fbb6572 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -227,7 +227,7 @@ Fout bij transactie maken - - kosten %1$s + kosten %1$s (%1$s) mislukt - %1$s @@ -427,5 +427,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-pt-rBR/help.xml b/app/src/main/res/values-pt-rBR/help.xml index a290c31f..f1ecf142 100755 --- a/app/src/main/res/values-pt-rBR/help.xml +++ b/app/src/main/res/values-pt-rBR/help.xml @@ -291,4 +291,25 @@ ]]> Entendi! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 4c9af7aa..e44f0712 100755 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -229,7 +229,7 @@ Erro ao criar a transação - - taxa de %1$s + taxa de %1$s (%1$s) falhou - %1$s @@ -421,4 +421,9 @@ aqui. Resetar carteira! Esta carteira será resetada, perdendo todos os dados "off-chain" (como notas, contas & nomes de subendereços, chaves de transações privadas, ...)! Use isso SOMENTE se esta carteira estiver corrompida e não carrega! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-pt/help.xml b/app/src/main/res/values-pt/help.xml index bddcfa72..8d2ada45 100644 --- a/app/src/main/res/values-pt/help.xml +++ b/app/src/main/res/values-pt/help.xml @@ -291,4 +291,25 @@ ]]> Entendido! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index c9395a73..2a122365 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -229,7 +229,7 @@ Erro ao criar a transacção - - Taxa %1$s + Taxa %1$s (%1$s) falhou - %1$s @@ -431,5 +431,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-ro/help.xml b/app/src/main/res/values-ro/help.xml index 88d325ba..5509965f 100644 --- a/app/src/main/res/values-ro/help.xml +++ b/app/src/main/res/values-ro/help.xml @@ -298,4 +298,25 @@ ]]> Am înțeles! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index ecd406ce..fdf965ed 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -205,7 +205,7 @@ Eroare creare tranzacție - - Comision %1$s + Comision %1$s (%1$s) eșuat - %1$s @@ -427,5 +427,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-ru/help.xml b/app/src/main/res/values-ru/help.xml index 26df4809..3d2ebff8 100644 --- a/app/src/main/res/values-ru/help.xml +++ b/app/src/main/res/values-ru/help.xml @@ -297,4 +297,25 @@ ]]> Я понял! + + Nah… + Get Orbot! + Tor +

      Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

      +

      Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

      +

      In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

      +

      If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

      + ]]>
      + + Tor Node +

      This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

      + ]]>
      diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 7412f32d..9f5e60e3 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -231,7 +231,7 @@ Ошибка создания транзакции - - Комиссия %1$s + Комиссия %1$s (%1$s) Не удалось - %1$s @@ -431,5 +431,10 @@ Ошибка импорта! Сбросить кошелек - Этот кошелек будет сброшен, вы потеряете все данные, которые не находятся в блокчейне (например примечания, имена подадресов, приватные ключи транзакций, ...)! Используйте это ТОЛЬКО если ваш кошелек поврежден и не загружается! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-sk/about.xml b/app/src/main/res/values-sk/about.xml index 1f1a3ba5..ff6e9ede 100644 --- a/app/src/main/res/values-sk/about.xml +++ b/app/src/main/res/values-sk/about.xml @@ -1,52 +1,52 @@ - - - Zatvoriť - ja som monerujo - Verzia %1$s (%2$d) - - Zásluhy -
      - m2049r, baltsar777, anhdres, keejef, - rehrar, EarlOfEgo et al. -

      - monerujo.io - ]]>
      - - Zásady ochrany osobných údajov -

      Na tejto stránke nájdete informácie o zásadách ochrany v súvislosti so zbieraním a spracovávaním osobných údajov, - ktoré získame od užívateľov našej apky (monerujo: Monero Wallet). -

      -

      Používaním tejto aplikácie súhlasíš so zbieraním a spracovávaním informácií v súlade s týmito pravidlami. -

      -

      Zbierané Dáta

      -

      Osobné dáta sú také dáta, na základe ktorých by bolo možné identifikovať jedinca.

      -

      Monero kľúče a verejné adresy sú zbierané a spracovávané aplikáciou lokálne na účely - spracovania a prenosu transakcie v Monero sieti.

      -

      Iné osobné data nie sú zbierané a spracovávané.

      -

      Pokiaľ používaš (voliteľnú) funkciu zmenárne, monerujo vyhľadá výmenný kurz cez verejné API portálu coinmarketcap.com. - Pre viac detailov pozri zásady ochrany osobných údajov na https://coinmarketcap.com/privacy kde je uvedené aké dáta zbierajú

      -

      Pokiaľ používaš aplikáciu pre platby na BTC adresy, využívaš služby SideShift.ai. - Pre viac detailov pozri zásady ochrany osobných údajov na https://sideshift.ai/ . Monerujo im posiela cieľovú BTC - addresu príjemcu a posielané množstvo. Tvoju IP bude tiež možné zaznamenať.

      -

      Povolenia

      -
        -
      • INTERNET : Pripojiť do Monero siete cez vzdialený Monero uzol
      • -
      • READ_EXTERNAL_STORAGE : Čítať súbory peňaženky uložené v zariadení
      • -
      • WRITE_EXTERNAL_STORAGE : Zapisovať do súborov peňaženky uložených v zariadení
      • -
      • WAKE_LOCK : Udržať zariadenie prebudené počas synchronizácie
      • -
      • CAMERA : Snímať QR kódy na posielanie a obdržanie Monero
      • -
      -

      Zmeny v týchto zásadách

      -

      Je možné, že z času načas sa tieto zásady upravia, či doplnia, na čo budete včas upozornení aplikáciou - a na našich webových stránkach (www.monerujo.io). - Doporučujeme tieto zásady periodicky kontrolovať kôli prípadným zmenám. -

      tieto zásady ochrany údajov boli naposledy upravené: 10. November, 2017. -

      -

      Kontaktuj Nás

      -

      Ak máš akékoľvek otázky ohľadom zásad ochrany osobných údajov, alebo ako sú data spracovávané, - pošli email na privacy@monerujo.io. -

      - ]]>
      -
      + + + Zatvoriť + ja som monerujo + Verzia %1$s (%2$d) + + Zásluhy +
      + m2049r, baltsar777, anhdres, keejef, + rehrar, EarlOfEgo et al. +

      + monerujo.io + ]]>
      + + Zásady ochrany osobných údajov +

      Na tejto stránke nájdete informácie o zásadách ochrany v súvislosti so zbieraním a spracovávaním osobných údajov, + ktoré získame od užívateľov našej apky (monerujo: Monero Wallet). +

      +

      Používaním tejto aplikácie súhlasíš so zbieraním a spracovávaním informácií v súlade s týmito pravidlami. +

      +

      Zbierané Dáta

      +

      Osobné dáta sú také dáta, na základe ktorých by bolo možné identifikovať jedinca.

      +

      Monero kľúče a verejné adresy sú zbierané a spracovávané aplikáciou lokálne na účely + spracovania a prenosu transakcie v Monero sieti.

      +

      Iné osobné data nie sú zbierané a spracovávané.

      +

      Pokiaľ používaš (voliteľnú) funkciu zmenárne, monerujo vyhľadá výmenný kurz cez verejné API portálu coinmarketcap.com. + Pre viac detailov pozri zásady ochrany osobných údajov na https://coinmarketcap.com/privacy kde je uvedené aké dáta zbierajú

      +

      Pokiaľ používaš aplikáciu pre platby na BTC adresy, využívaš služby SideShift.ai. + Pre viac detailov pozri zásady ochrany osobných údajov na https://sideshift.ai/ . Monerujo im posiela cieľovú BTC + addresu príjemcu a posielané množstvo. Tvoju IP bude tiež možné zaznamenať.

      +

      Povolenia

      +
        +
      • INTERNET : Pripojiť do Monero siete cez vzdialený Monero uzol
      • +
      • READ_EXTERNAL_STORAGE : Čítať súbory peňaženky uložené v zariadení
      • +
      • WRITE_EXTERNAL_STORAGE : Zapisovať do súborov peňaženky uložených v zariadení
      • +
      • WAKE_LOCK : Udržať zariadenie prebudené počas synchronizácie
      • +
      • CAMERA : Snímať QR kódy na posielanie a obdržanie Monero
      • +
      +

      Zmeny v týchto zásadách

      +

      Je možné, že z času načas sa tieto zásady upravia, či doplnia, na čo budete včas upozornení aplikáciou + a na našich webových stránkach (www.monerujo.io). + Doporučujeme tieto zásady periodicky kontrolovať kôli prípadným zmenám. +

      tieto zásady ochrany údajov boli naposledy upravené: 10. November, 2017. +

      +

      Kontaktuj Nás

      +

      Ak máš akékoľvek otázky ohľadom zásad ochrany osobných údajov, alebo ako sú data spracovávané, + pošli email na privacy@monerujo.io. +

      + ]]>
      +
      diff --git a/app/src/main/res/values-sk/help.xml b/app/src/main/res/values-sk/help.xml index 32105563..93c46725 100644 --- a/app/src/main/res/values-sk/help.xml +++ b/app/src/main/res/values-sk/help.xml @@ -1,262 +1,283 @@ - - - Vytvoriť Peňaženku - Novú -

      Ak Ti treba novú Monero adresu!

      -

      Vlož unikátny názov a heslo peňaženky. - Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. - Používaj silné heslo - alebo ešte lepšie je použiť frázu.

      -

      Zapíš si mnemotechnický Seed!

      -

      Na nasledujúcej obrazovke uvidíš svoj 25-slovný \"Mnemotechnický Seed\". - Sú to dáta potrebné na obnovenie peňaženky a získanie prístupu k Tvojim prostriedkom. - Bezpečné uloženie a utajenie týchto dát je veľmi dôležité, keďže pomocou nich hocikto môže získať kontrolu nad vašimi XMR!

      -

      Ak stratíš heslo do peňaženky, ešte stále si môžeš obnoviť peňaženku so svojím mnemotechnickým Seedom.

      -

      Ak stratíš mnemotechnický Seed, neexistuje spôsob ako ho odvodiť a všetky Tvoje mince sú navždy stratené! - Tento Seed sa nikdy nemôže zmeniť a v prípade, že je ukradnutý, alebo inak skompromitovaný, budeš musieť presunúť svoje mince do novej peňaženky (s novým mnemotechnickým Seedom). - Preto je najlepšie ak si svoj Seed zálohuješ zapísaním na papier a uložíš na niekoľko bezpečných a utajených miest.

      - ]]>
      - - Vytvoriť Peňaženku - Seed -

      Ak už máš Monero adresu a chceš obnoviť transakcie z blockchain!

      -

      Vlož unikátny názov a heslo peňaženky. - Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. - Používaj silné heslo - alebo ešte lepšie je použiť frázu.

      -

      Vlož svoj Seed do políčka \"Mnemotechnický Seed\".

      -

      Ak poznáš číslo bloku svojej prvej transakcie pre túto adresu, vlož ho do poľa \"Obnov Výšku\" - zanechaním prázdneho poľa budeš skenovať celú blockchain, - aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať veľmi dlho.

      - ]]>
      - - Vytvoriť Peňaženku - Kľúče -

      Ak obnovuješ svoju peňaženku pomocou kľúčov!

      -

      Vlož unikátny názov a heslo peňaženky. - Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. - Používaj silné heslo - alebo ešte lepšie je použiť frázu.

      -

      Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\" and \"Platobný Kľúč\".

      -

      Ak poznáš číslo bloku svojej prvej transakcie pre túto adresu, vlož ho do poľa \"Obnov Výšku\" - zanechaním prázdneho poľa budeš skenovať celú blockchain, - aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať veľmi dlho.

      -

      Vlož sem číslo bloku prvej transakcie pre túto adresu do políčka \"Obnov Výšku\". Môžeš tiež použiť dátum vo formáte YYYY-MM-DD. - Ak to nevieš naisto, vlož približný dátum/číslo bloku pred tým ako si prvýkrát použil danú adresu.

      - ]]>
      - - Vytvoriť Peňaženku - Ledger -

      Obnovenie peňaženky zo zariadenia Ledger Nano S.

      -

      Tvoj tajný kľúč nikdy neunikne zo zariadenia Ledger, takže budeš musieť mať Ledger pripojený vždy, keď budeš chcieť pristupovať k svojej peňaženke.

      -

      Vlož unikátny názov a heslo peňaženky. Heslo je určené na zabezpečenie dát peňaženky na Android zariadení. - Používaj silné heslo - alebo ešte lepšie je použiť frázu.

      -

      Do políčka \"Obnov Výšku\" vlož číslo bloku prvej transakcie pre túto adresu . Môžeš tiež použiť dátum vo formáte YYYY-MM-DD. - Ak to nevieš presne, vlož približný dátum/číslo bloku pred tým ako si prvýkrát použil danú adresu. Urýchli to prehľadávanie blockchain.

      - ]]>
      - - Vytvoriť Peňaženku - Prezeracia Peňaženka -

      Ak chceš iba sledovať prichádzajúce transakcie!

      -

      Vlož unikátny názov a heslo peňaženky. Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. - Používaj silné heslo - alebo ešte lepšie je použiť frázu.

      -

      Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\".

      -

      Ak poznáš číslo bloku svojej prvej transakcie pre túto adresu, vlož ho do poľa \"Obnov Výšku\". Môžeš tiež použiť dátum vo formáte YYYY-MM-DD. - Ak to nevieš naisto, vlož približný dátum/číslo bloku pred tým ako si prvýkrát použil danú adresu. - Zanechaním prázdneho poľa budeš skenovať celú blockchain, aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať veľmi dlho.

      - ]]>
      - - Detaily Peňaženky -

      Verejná Adresa

      - Vaša verejná adresa je niečo ako číslo bakového účtu, ktoré môžte zdieľať bez toho aby ste sa báli, - že prídete o svoje Monero. Ľudia vám budú posielať Monero práve na túto adresu. -

      Mnemotechnický Seed

      - Tieto dáta sú potrebné len na obnovu peňaženky a získanie plného prístupu k vašim prostriedkom. - Bezpečné uloženie a utajenie týchto dát je veľmi dôležité, keďže pomocou nich hocikto môže získať kontrolu nad vašimi XMR! - Ak to ešte nemáš zapísané a uložené niekde na bezpečnom mieste, urob tak čo najskôr! -

      Heslo pre súbory peňaženky

      - Uisti sa, že si si heslo zapísal. Ak resetuješ zariadenie, alebo odinštaluješ appku, budeš ho potrebovať na prístup do peňaženky. -
      -

      CrAzYpass

      - Pokiaľ tu zobrazené heslo tvorí 52 alfanumerických znakov v skupinách po 4 - gratulujem! - Tvoje súbory peňaženky sú zabezpečené 256-bit kľúčom vygenerovaným bezpečnostnými funkciami Tvojho zariadenia. - Extrémne to zťažuje hacknutie týchto súborov!
      - Táto funkcia je povinná pre všetky novo-vytvorené peňaženky. -

      Legacy Password

      - Ak vidíš svoju prístupovú frázu na tomto mieste, Tvoja peňaženka nie je zabezpečená tak, - ako by bola pri použití CrAzYpass. Napraviť to môžeš označením \"Zmeň Frázu\" v menu. - Po vložení novej prístupovej frázy (aj pri tej istej ako predtým), aplikácia ti vygeneruje - CrAzYpass a zabezpečí s ním súbory peňaženky. Zapísať! -

      CrAzYpass peňaženky

      - Ak budeš potrebovať niekedy preinštalovať Monerujo (napríklad po resetovaní telefónu alebo pri výmene za iný), - alebo ak chceš použiť súbory peňaženky na inom zariadení či PC, budeš musieť - použiť toto heslo pre obnovu na opätovný prístup do svojej peňaženky.
      - Označením \"Zmeň Frázu\ z menu, môžeš vybrať inú prístupovú frázu. Tu pozor, pretože to vygenereuje nové heslo pre obnovu. - Zapísať! -

      Prezerací Kľúč

      - Tvoj prezerací kľúč (view key) môžeš používať na sledovanie prichádzajúcich transakcií do peňaženky, - zatiaľ čo míňať prostriedky tento prezerací kľúč neumožňuje. -

      Platobný Kľúč

      - Platobný Kľúč (spend key) umožňuje míňať Monero prislúchajúce danej peňaženke, - takže ho nikomu nepredrádzaj a uchovaj rovnako bezpečne ako svoj mnemotechnický seed. - ]]>
      - - Zoznam Peňaženiek -

      Uzol

      -

      Monerujo používa vzdialené uzly na komunikáciu so sieťou Monero. Nie je tak potrebné sťahovať - a ukladať celú blockchain ako takú. Zoznam populárnych uzlov spolu s návodmi ako ich rozbehať môžeš nájsť na - https://moneroworld.com/

      -

      Monerujo prichádza s niekoľkými prednastavenými uzlami. Pamätá si posledných 5 použitých uzlov.

      -

      Peňaženky

      -

      Tu vidíš svoje peňaženky. Sú umiestnené v adresári monerujo na internom úložisku Tvojho zariadenia. - Môžeš použiť súborový manažér telefónu na ich vyhľadanuie a zobrazenie. - Mal by si robiť pravidelné zálohy týchto adresárov a umiestniť ich mimo zariadenie pre prípad straty, či poškodenia.

      -

      Označ Peňaženku alebo stlač \"+\" pre vytvorenie novej. - Alebo označ jednu z možností:

      -

      Detaily

      -

      ukáže detaily peňaženky, seed & kľúče.

      -

      Prijať

      -

      Vytvorí QR kód na prijímanie Moneroj.

      -

      Premenuj

      -

      Premenuje peňaženku. Zálohy nie sú premenované.

      -

      Záloha

      -

      Vytvorí kópiu peňaženky v adresári backups vnútri monerujo - prepísaním predchádzajúcich kópií.

      -

      Archivovať

      -

      Vytvorí zálohu s následným zmazaním peňaženky. Kópia zostáva v adresári backups - Pokiaľ už nepotrebuješ zálohy, mal by si ich vymazať zo svojho telefónu pomocou súborového manažéra, - alebo inej aplikácie na bezpečné mazanie. -

      - ]]>
      - - Detaily Transakcie -

      Destinácia

      - Toto je verejná adresa peňaženky kde chceš poslať Monero. -

      ID Platby

      - Môžeš použiť ID Platby na identifikáciu platby medzi dvoma stranami. Nie je to síce povinný, ale je to súkromný údaj. - Tak napríklad s týmto môžeš zosúladiť svoj biznis s kúpenou položkou. Táto funkcia bude v Monero nahradená podadresami. -

      TX ID

      - Toto je ID transakcie, ktoré slúži na identifikáciu transakcie v Monero blockchain exploreri, ako napr. https://xmrchain.net/ -

      TX KĽÚČ (Transaction Key)

      - Toto je Tvoj súkromný kľúč transakcie, uchovaj ho bezpečne a neposkytuj ho tretím stranám, - aby nemohli identifikovať tvoj podpis v kruhovom podpise a spraviť tak transakciu verejnú a transparentnú. -

      Blok

      - Blok do ktorého je zaradená vaša transakcia. - - ]]>
      - - Poslať -

      Adresa Príjemcu

      -

      Toto je verejná adresa peňaženky kam posielaš Monero. Môžeš ju kopírovať zo schránky, skenovať QR kód alebo vložiť manuálne. - Trikrát sa uisti, že neposielaš mince na zlú adresu.

      -

      Okrem XMR adries, môžte použiť tiež -

        -
      • OpenAlias pre XMR či BTC
      • -
      • BTC adresu
      • - - Nezabúdajte, že posielanie BTC prebieha cez službu SideShift.ai (detaily na https://sideshift.ai). Pozri sekciu nižšie o posielaní BTC

        -

        Posielanie BTC

        -

        SideShift.ai

        -

        SideShift.ai je služba tretej strany, ktorá umožňuje zámenu z Monero na Bitcoin. - Používame SideShift.ai API na integráciu Bitcoin platieb do Monerujo. Prosím mrkni na - https://sideshift.ai a rozhodni sa sám, či je to naozaj služba, ktorú chceš používať. - Tím Monerujo nie je nijako spojený so službou SideShift.ai a teda nemôže pomôcť s prípadnými problémami s touto službou.

        -

        SideShift.ai Výmenný Kurz

        -

        Na obrazovke \"Množstvo\" uvidíš aktuálne parametre služby SideShift.ai, vrátane aktuálneho kurzu BTC, hornej a dolnej hranice. - Podotýkame, že tento kurz nie je garantovaný.

        -

        SideShift.ai Objednávka

        -

        Na obrazovke \"Potvrdiť\", uvidíš aktuálnu objednávku v SideShift.ai. Táto objednávka je platná iba obmedzený čas - ako si môžeš všimnúť odpočítavanie na tlačítku \"Minúť\". - Výmenný kurz sa môže líšiť od toho, ktorý bol na predošlých obrazovkách.

        -

        SideShift.ai Tajný Kľúč

        -

        Keďže Monerujo dbá len na tú časť transakcie, ktorá pracuje s Monero, - tento SideShift.ai Tajný Kľúč sa môže využívať na sledovanie Bitcoinovej časti transakcie a objednávky - na domovskej stránke SideShift.ai

        -

        SideShift.ai Odpočítavanie!

        -

        Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .

        - ]]> - - Posielanie BTC -

        SideShift.ai

        -

        SideShift.ai je služba tretej strany, ktorá umožňuje zámenu z Monero na Bitcoin. - Používame SideShift.ai API na integráciu Bitcoin platieb do Monerujo. Prosím mrkni na - https://sideshift.ai a rozhodni sa sám, či je to naozaj služba, ktorú chceš používať. - Tím Monerujo nie je nijako spojený so službou SideShift.ai a teda nemôže pomôcť s prípadnými problémami s touto službou.

        -

        SideShift.ai Výmenný Kurz

        -

        Na obrazovke \"Množstvo\" uvidíš aktuálne parametre služby SideShift.ai, vrátane aktuálneho kurzu BTC, hornej a dolnej hranice. - Podotýkame, že tento kurz nie je garantovaný.

        -

        SideShift.ai Objednávka

        -

        Na obrazovke \"Potvrdiť\", uvidíš aktuálnu objednávku v SideShift.ai. Táto objednávka je platná iba obmedzený čas - ako si môžeš všimnúť odpočítavanie na tlačítku \"Minúť\". - Výmenný kurz sa môže líšiť od toho, ktorý bol na predošlých obrazovkách.

        -

        SideShift.ai Tajný Kľúč

        -

        Keďže Monerujo dbá len na tú časť transakcie, ktorá pracuje s Monero, - tento SideShift.ai Tajný Kľúč sa môže využívať na sledovanie Bitcoinovej časti transakcie a objednávky - na domovskej stránke SideShift.ai

        -

        SideShift.ai Odpočítavanie!

        -

        Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .

        - ]]>
        - - Peňaženka - -

        Mód Ulica

        -

        Mód Ulica sa povoľuje a vypína v menu, alebo klepnutím na ikonu Guntherovej hlavy. V tomto móde sa váš zostatok nezobrazuje na žiadnej obrazovke, - takže svoju peňaženku môžte smelo používať na ulici, v krčme, či na inom verejnom mieste. Po nastavení sú skryté aj predchádzajúce transakcie, zatiaľ čo nové budú zobrazené, - aby ste mohli vidieť či vám odoslalo a dorazilo všetko správne.

        - -

        Skenovanie

        - Keďže Monero obľubuje súkromie, zakaždým pri otváraní Monerujo musíme skenovať blockchain aby sme videli, či nedorazili nové Monerá. - Monerujo uchováva len tie informácie, ktoré prislúchajú vašej peňaženke. Pokiaľ nemáte sychronizovanú peňaženku dlhší čas, synchronizácia môže trvať dlho. -

        Zostatok

        -

        Pomóc! Zostatok v mojej peňaženke zmizol, alebo je nepotvrdený!
        - Nestresuj! Keď odosielaš prostriedky zo svojej peňaženky, časť zostatku sa dočasne ukáže ako nepotvrdená. - - Súvisí to s tým, ako je Monero navrhnuté a ako funguje zmena v blockchain. - - Viac o zmenách sa dočítaš (anglicky) na https://getmonero.org/resources/moneropedia/change.html -

        Zoznam Transakcií

        -

        Zoznam transakcií v peňaženke. V prípade prezeracej peňaženky budú zobrazené iba prichádzajúce transakcie.

        - ]]>
        - - Uzly -

        TL;DR

        -

        Aktuálny zoznam uzlov získaš tak, že potiahneš a pridáš do záložiek 5 uzlov, z ktorých si Monerujo jeden vyberie.

        -

        Čo je Uzol?

        -

        Monerujo používa vzdialený uzol (Remote Node, niekedy nazývaný aj Daemon) a peňaženka tak môže komunikovať so sieťou Monero bez toho, aby bolo potrebné sťahovať celú blockchain.

        -

        Zoznam Uzlov

        -

        Ak je zoznam prázdny, môžeš zadať adresu uzla manuálne, alebo môžeš nechať Monerujo preskúmať celú sieť. Prípadne oboje. Čítaj ďalej…

        -

        Zoznam uzlov zobrazuje všetky momentálne známe uzly. Pod každým uzlom je zobrazená časová pečiatka jeho posledného bloku. - Vedľa je ikonka nodu, ktorá indikuje úroveň pripojenia.

        -

        Ktorýkoľvek uzol v zozname si môžte pridať do záložiek pre budúce použitie. Uzly, ktoré nebudú uložené, sa z pamäte vymažú.

        -

        Monerujo vyberie jeden z uložených uzlov pri každom použití. Skontroluje výšku bloku (blockheight) týchto uzlov a zistí, ktorý uzol je ako aktualizovaný, ako dlho trvá odpoveď a podľa toho vyberie pre vás optimálny uzol.

        -

        Podľa týchto charakteristík je dané aj zoradenie v zozname. Prvý uzol bude ten, ktorý Monerujo vybral práve teraz. Naspodku bude veľmi pomalý uzol s pomalou odozvou, alebo nedostupné uzly.

        -

        Pridať Uzol

        -

        Dotykom na tlačítko "Pridať Uzol" vložíte detaily vlastného uzla. - "Adresa" je hostname alebo IP-adresa uzla. Je to jediné povinné pole. - "Port" ak uzol používa iný ako predvolený port (napr. 18089). - Môžte si aj pomenovať svoje uzly pre budúce použitie. Je to voliteľné. - Niektoré uzly vyžadujú na používanie aj prihlasovacie údaje. V tom prípade napíšte užívateľské meno a heslo do príslušných polí. - To by malo stačiť na testovanie týchto nastavení. "Test" - "Výsledky Testu" zobrazia výšku, čas odozvy a aktuálnu IP adresu uzla. - Vo výsledku môže byť tiež chyba - zvyčajne preto, že uzol nie je dostupný, neodpovedá v požadovanom čase, alebo prihlasovacie údaje nie sú správne. - Prípadne kombinácia zadanej adresy a portu neprislúcha žiadnemu uzlu Monero siete! - Akonáhle test skončí úspešne (žiadna chyba sa neobjaví) - klepni na "OK" a ulož si daný uzol.

        -

        Vyhľadať Uzol

        -

        Táto funkcia umožní vyhľadať uzol skenovaním Monero siete. Monerujo začne skenovať sieť a vyhľadávať vzdialené uzly na porte 18089. - Začína tým, že sa opýta uzlov vo vašich záložkách na ďalšie uzly v P2P sieti Monero, ktoré sú s nimi spojené, tých sa opýta zas na ďalšie uzly atď. - V prípade, že nemáte žiadne uzly vo svojich záložkách, Monerujo bude skúšať uzly (seed nodes) natvrdo zapísané v kóde Monero. Vyhľadávanie končí ak Monerujo nájde aspoň 10 vzdialených uzlov.

        - ]]>
        - - Používanie platobného linku -

        Monerujo je spustené z platobného linku. Ak chceš posielať prostriedky, postupuj nasledovne:

        -

        - 1. Otvor peňaženku z ktorej chceš platiť
        - 2. Počkaj kým sa peňaženka zosynchronizuje a zobrazí sa tlačítko "Poslať"
        - 3. Stlač tlačidlo "Poslať" -

        -

        Detaily platby budú vložené automaticky. Skontroluj ich a pokračuj ako obvykle pri ostatných transakciách.

        - ]]>
        - - Rozumiem! - + + + Vytvoriť Peňaženku - Novú +

        Ak Ti treba novú Monero adresu!

        +

        Vlož unikátny názov a heslo peňaženky. + Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. + Používaj silné heslo - alebo ešte lepšie je použiť frázu.

        +

        Zapíš si mnemotechnický Seed!

        +

        Na nasledujúcej obrazovke uvidíš svoj 25-slovný \"Mnemotechnický Seed\". + Sú to dáta potrebné na obnovenie peňaženky a získanie prístupu k Tvojim prostriedkom. + Bezpečné uloženie a utajenie týchto dát je veľmi dôležité, keďže pomocou nich hocikto môže získať kontrolu nad vašimi XMR!

        +

        Ak stratíš heslo do peňaženky, ešte stále si môžeš obnoviť peňaženku so svojím mnemotechnickým Seedom.

        +

        Ak stratíš mnemotechnický Seed, neexistuje spôsob ako ho odvodiť a všetky Tvoje mince sú navždy stratené! + Tento Seed sa nikdy nemôže zmeniť a v prípade, že je ukradnutý, alebo inak skompromitovaný, budeš musieť presunúť svoje mince do novej peňaženky (s novým mnemotechnickým Seedom). + Preto je najlepšie ak si svoj Seed zálohuješ zapísaním na papier a uložíš na niekoľko bezpečných a utajených miest.

        + ]]>
        + + Vytvoriť Peňaženku - Seed +

        Ak už máš Monero adresu a chceš obnoviť transakcie z blockchain!

        +

        Vlož unikátny názov a heslo peňaženky. + Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. + Používaj silné heslo - alebo ešte lepšie je použiť frázu.

        +

        Vlož svoj Seed do políčka \"Mnemotechnický Seed\".

        +

        Ak poznáš číslo bloku svojej prvej transakcie pre túto adresu, vlož ho do poľa \"Obnov Výšku\" - zanechaním prázdneho poľa budeš skenovať celú blockchain, + aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať veľmi dlho.

        + ]]>
        + + Vytvoriť Peňaženku - Kľúče +

        Ak obnovuješ svoju peňaženku pomocou kľúčov!

        +

        Vlož unikátny názov a heslo peňaženky. + Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. + Používaj silné heslo - alebo ešte lepšie je použiť frázu.

        +

        Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\" and \"Platobný Kľúč\".

        +

        Ak poznáš číslo bloku svojej prvej transakcie pre túto adresu, vlož ho do poľa \"Obnov Výšku\" - zanechaním prázdneho poľa budeš skenovať celú blockchain, + aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať veľmi dlho.

        +

        Vlož sem číslo bloku prvej transakcie pre túto adresu do políčka \"Obnov Výšku\". Môžeš tiež použiť dátum vo formáte YYYY-MM-DD. + Ak to nevieš naisto, vlož približný dátum/číslo bloku pred tým ako si prvýkrát použil danú adresu.

        + ]]>
        + + Vytvoriť Peňaženku - Ledger +

        Obnovenie peňaženky zo zariadenia Ledger Nano S.

        +

        Tvoj tajný kľúč nikdy neunikne zo zariadenia Ledger, takže budeš musieť mať Ledger pripojený vždy, keď budeš chcieť pristupovať k svojej peňaženke.

        +

        Vlož unikátny názov a heslo peňaženky. Heslo je určené na zabezpečenie dát peňaženky na Android zariadení. + Používaj silné heslo - alebo ešte lepšie je použiť frázu.

        +

        Do políčka \"Obnov Výšku\" vlož číslo bloku prvej transakcie pre túto adresu . Môžeš tiež použiť dátum vo formáte YYYY-MM-DD. + Ak to nevieš presne, vlož približný dátum/číslo bloku pred tým ako si prvýkrát použil danú adresu. Urýchli to prehľadávanie blockchain.

        + ]]>
        + + Vytvoriť Peňaženku - Prezeracia Peňaženka +

        Ak chceš iba sledovať prichádzajúce transakcie!

        +

        Vlož unikátny názov a heslo peňaženky. Heslo je určené na zabezpečenie dát peňaženky v tomto zariadení. + Používaj silné heslo - alebo ešte lepšie je použiť frázu.

        +

        Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\".

        +

        Ak poznáš číslo bloku svojej prvej transakcie pre túto adresu, vlož ho do poľa \"Obnov Výšku\". Môžeš tiež použiť dátum vo formáte YYYY-MM-DD. + Ak to nevieš naisto, vlož približný dátum/číslo bloku pred tým ako si prvýkrát použil danú adresu. + Zanechaním prázdneho poľa budeš skenovať celú blockchain, aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať veľmi dlho.

        + ]]>
        + + Detaily Peňaženky +

        Verejná Adresa

        + Vaša verejná adresa je niečo ako číslo bakového účtu, ktoré môžte zdieľať bez toho aby ste sa báli, + že prídete o svoje Monero. Ľudia vám budú posielať Monero práve na túto adresu. +

        Mnemotechnický Seed

        + Tieto dáta sú potrebné len na obnovu peňaženky a získanie plného prístupu k vašim prostriedkom. + Bezpečné uloženie a utajenie týchto dát je veľmi dôležité, keďže pomocou nich hocikto môže získať kontrolu nad vašimi XMR! + Ak to ešte nemáš zapísané a uložené niekde na bezpečnom mieste, urob tak čo najskôr! +

        Heslo pre súbory peňaženky

        + Uisti sa, že si si heslo zapísal. Ak resetuješ zariadenie, alebo odinštaluješ appku, budeš ho potrebovať na prístup do peňaženky. +
        +

        CrAzYpass

        + Pokiaľ tu zobrazené heslo tvorí 52 alfanumerických znakov v skupinách po 4 - gratulujem! + Tvoje súbory peňaženky sú zabezpečené 256-bit kľúčom vygenerovaným bezpečnostnými funkciami Tvojho zariadenia. + Extrémne to zťažuje hacknutie týchto súborov!
        + Táto funkcia je povinná pre všetky novo-vytvorené peňaženky. +

        Legacy Password

        + Ak vidíš svoju prístupovú frázu na tomto mieste, Tvoja peňaženka nie je zabezpečená tak, + ako by bola pri použití CrAzYpass. Napraviť to môžeš označením \"Zmeň Frázu\" v menu. + Po vložení novej prístupovej frázy (aj pri tej istej ako predtým), aplikácia ti vygeneruje + CrAzYpass a zabezpečí s ním súbory peňaženky. Zapísať! +

        CrAzYpass peňaženky

        + Ak budeš potrebovať niekedy preinštalovať Monerujo (napríklad po resetovaní telefónu alebo pri výmene za iný), + alebo ak chceš použiť súbory peňaženky na inom zariadení či PC, budeš musieť + použiť toto heslo pre obnovu na opätovný prístup do svojej peňaženky.
        + Označením \"Zmeň Frázu\ z menu, môžeš vybrať inú prístupovú frázu. Tu pozor, pretože to vygenereuje nové heslo pre obnovu. + Zapísať! +

        Prezerací Kľúč

        + Tvoj prezerací kľúč (view key) môžeš používať na sledovanie prichádzajúcich transakcií do peňaženky, + zatiaľ čo míňať prostriedky tento prezerací kľúč neumožňuje. +

        Platobný Kľúč

        + Platobný Kľúč (spend key) umožňuje míňať Monero prislúchajúce danej peňaženke, + takže ho nikomu nepredrádzaj a uchovaj rovnako bezpečne ako svoj mnemotechnický seed. + ]]>
        + + Zoznam Peňaženiek +

        Uzol

        +

        Monerujo používa vzdialené uzly na komunikáciu so sieťou Monero. Nie je tak potrebné sťahovať + a ukladať celú blockchain ako takú. Zoznam populárnych uzlov spolu s návodmi ako ich rozbehať môžeš nájsť na + https://moneroworld.com/

        +

        Monerujo prichádza s niekoľkými prednastavenými uzlami. Pamätá si posledných 5 použitých uzlov.

        +

        Peňaženky

        +

        Tu vidíš svoje peňaženky. Sú umiestnené v adresári monerujo na internom úložisku Tvojho zariadenia. + Môžeš použiť súborový manažér telefónu na ich vyhľadanuie a zobrazenie. + Mal by si robiť pravidelné zálohy týchto adresárov a umiestniť ich mimo zariadenie pre prípad straty, či poškodenia.

        +

        Označ Peňaženku alebo stlač \"+\" pre vytvorenie novej. + Alebo označ jednu z možností:

        +

        Detaily

        +

        ukáže detaily peňaženky, seed & kľúče.

        +

        Prijať

        +

        Vytvorí QR kód na prijímanie Moneroj.

        +

        Premenuj

        +

        Premenuje peňaženku. Zálohy nie sú premenované.

        +

        Záloha

        +

        Vytvorí kópiu peňaženky v adresári backups vnútri monerujo + prepísaním predchádzajúcich kópií.

        +

        Archivovať

        +

        Vytvorí zálohu s následným zmazaním peňaženky. Kópia zostáva v adresári backups + Pokiaľ už nepotrebuješ zálohy, mal by si ich vymazať zo svojho telefónu pomocou súborového manažéra, + alebo inej aplikácie na bezpečné mazanie. +

        + ]]>
        + + Detaily Transakcie +

        Destinácia

        + Toto je verejná adresa peňaženky kde chceš poslať Monero. +

        ID Platby

        + Môžeš použiť ID Platby na identifikáciu platby medzi dvoma stranami. Nie je to síce povinný, ale je to súkromný údaj. + Tak napríklad s týmto môžeš zosúladiť svoj biznis s kúpenou položkou. Táto funkcia bude v Monero nahradená podadresami. +

        TX ID

        + Toto je ID transakcie, ktoré slúži na identifikáciu transakcie v Monero blockchain exploreri, ako napr. https://xmrchain.net/ +

        TX KĽÚČ (Transaction Key)

        + Toto je Tvoj súkromný kľúč transakcie, uchovaj ho bezpečne a neposkytuj ho tretím stranám, + aby nemohli identifikovať tvoj podpis v kruhovom podpise a spraviť tak transakciu verejnú a transparentnú. +

        Blok

        + Blok do ktorého je zaradená vaša transakcia. + + ]]>
        + + Poslať +

        Adresa Príjemcu

        +

        Toto je verejná adresa peňaženky kam posielaš Monero. Môžeš ju kopírovať zo schránky, skenovať QR kód alebo vložiť manuálne. + Trikrát sa uisti, že neposielaš mince na zlú adresu.

        +

        Okrem XMR adries, môžte použiť tiež +

          +
        • OpenAlias pre XMR či BTC
        • +
        • BTC adresu
        • + + Nezabúdajte, že posielanie BTC prebieha cez službu SideShift.ai (detaily na https://sideshift.ai). Pozri sekciu nižšie o posielaní BTC

          +

          Posielanie BTC

          +

          SideShift.ai

          +

          SideShift.ai je služba tretej strany, ktorá umožňuje zámenu z Monero na Bitcoin. + Používame SideShift.ai API na integráciu Bitcoin platieb do Monerujo. Prosím mrkni na + https://sideshift.ai a rozhodni sa sám, či je to naozaj služba, ktorú chceš používať. + Tím Monerujo nie je nijako spojený so službou SideShift.ai a teda nemôže pomôcť s prípadnými problémami s touto službou.

          +

          SideShift.ai Výmenný Kurz

          +

          Na obrazovke \"Množstvo\" uvidíš aktuálne parametre služby SideShift.ai, vrátane aktuálneho kurzu BTC, hornej a dolnej hranice. + Podotýkame, že tento kurz nie je garantovaný.

          +

          SideShift.ai Objednávka

          +

          Na obrazovke \"Potvrdiť\", uvidíš aktuálnu objednávku v SideShift.ai. Táto objednávka je platná iba obmedzený čas - ako si môžeš všimnúť odpočítavanie na tlačítku \"Minúť\". + Výmenný kurz sa môže líšiť od toho, ktorý bol na predošlých obrazovkách.

          +

          SideShift.ai Tajný Kľúč

          +

          Keďže Monerujo dbá len na tú časť transakcie, ktorá pracuje s Monero, + tento SideShift.ai Tajný Kľúč sa môže využívať na sledovanie Bitcoinovej časti transakcie a objednávky + na domovskej stránke SideShift.ai

          +

          SideShift.ai Odpočítavanie!

          +

          Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .

          + ]]> + + Posielanie BTC +

          SideShift.ai

          +

          SideShift.ai je služba tretej strany, ktorá umožňuje zámenu z Monero na Bitcoin. + Používame SideShift.ai API na integráciu Bitcoin platieb do Monerujo. Prosím mrkni na + https://sideshift.ai a rozhodni sa sám, či je to naozaj služba, ktorú chceš používať. + Tím Monerujo nie je nijako spojený so službou SideShift.ai a teda nemôže pomôcť s prípadnými problémami s touto službou.

          +

          SideShift.ai Výmenný Kurz

          +

          Na obrazovke \"Množstvo\" uvidíš aktuálne parametre služby SideShift.ai, vrátane aktuálneho kurzu BTC, hornej a dolnej hranice. + Podotýkame, že tento kurz nie je garantovaný.

          +

          SideShift.ai Objednávka

          +

          Na obrazovke \"Potvrdiť\", uvidíš aktuálnu objednávku v SideShift.ai. Táto objednávka je platná iba obmedzený čas - ako si môžeš všimnúť odpočítavanie na tlačítku \"Minúť\". + Výmenný kurz sa môže líšiť od toho, ktorý bol na predošlých obrazovkách.

          +

          SideShift.ai Tajný Kľúč

          +

          Keďže Monerujo dbá len na tú časť transakcie, ktorá pracuje s Monero, + tento SideShift.ai Tajný Kľúč sa môže využívať na sledovanie Bitcoinovej časti transakcie a objednávky + na domovskej stránke SideShift.ai

          +

          SideShift.ai Odpočítavanie!

          +

          Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .

          + ]]>
          + + Peňaženka + +

          Mód Ulica

          +

          Mód Ulica sa povoľuje a vypína v menu, alebo klepnutím na ikonu Guntherovej hlavy. V tomto móde sa váš zostatok nezobrazuje na žiadnej obrazovke, + takže svoju peňaženku môžte smelo používať na ulici, v krčme, či na inom verejnom mieste. Po nastavení sú skryté aj predchádzajúce transakcie, zatiaľ čo nové budú zobrazené, + aby ste mohli vidieť či vám odoslalo a dorazilo všetko správne.

          + +

          Skenovanie

          + Keďže Monero obľubuje súkromie, zakaždým pri otváraní Monerujo musíme skenovať blockchain aby sme videli, či nedorazili nové Monerá. + Monerujo uchováva len tie informácie, ktoré prislúchajú vašej peňaženke. Pokiaľ nemáte sychronizovanú peňaženku dlhší čas, synchronizácia môže trvať dlho. +

          Zostatok

          +

          Pomóc! Zostatok v mojej peňaženke zmizol, alebo je nepotvrdený!
          + Nestresuj! Keď odosielaš prostriedky zo svojej peňaženky, časť zostatku sa dočasne ukáže ako nepotvrdená. + + Súvisí to s tým, ako je Monero navrhnuté a ako funguje zmena v blockchain. + + Viac o zmenách sa dočítaš (anglicky) na https://getmonero.org/resources/moneropedia/change.html +

          Zoznam Transakcií

          +

          Zoznam transakcií v peňaženke. V prípade prezeracej peňaženky budú zobrazené iba prichádzajúce transakcie.

          + ]]>
          + + Uzly +

          TL;DR

          +

          Aktuálny zoznam uzlov získaš tak, že potiahneš a pridáš do záložiek 5 uzlov, z ktorých si Monerujo jeden vyberie.

          +

          Čo je Uzol?

          +

          Monerujo používa vzdialený uzol (Remote Node, niekedy nazývaný aj Daemon) a peňaženka tak môže komunikovať so sieťou Monero bez toho, aby bolo potrebné sťahovať celú blockchain.

          +

          Zoznam Uzlov

          +

          Ak je zoznam prázdny, môžeš zadať adresu uzla manuálne, alebo môžeš nechať Monerujo preskúmať celú sieť. Prípadne oboje. Čítaj ďalej…

          +

          Zoznam uzlov zobrazuje všetky momentálne známe uzly. Pod každým uzlom je zobrazená časová pečiatka jeho posledného bloku. + Vedľa je ikonka nodu, ktorá indikuje úroveň pripojenia.

          +

          Ktorýkoľvek uzol v zozname si môžte pridať do záložiek pre budúce použitie. Uzly, ktoré nebudú uložené, sa z pamäte vymažú.

          +

          Monerujo vyberie jeden z uložených uzlov pri každom použití. Skontroluje výšku bloku (blockheight) týchto uzlov a zistí, ktorý uzol je ako aktualizovaný, ako dlho trvá odpoveď a podľa toho vyberie pre vás optimálny uzol.

          +

          Podľa týchto charakteristík je dané aj zoradenie v zozname. Prvý uzol bude ten, ktorý Monerujo vybral práve teraz. Naspodku bude veľmi pomalý uzol s pomalou odozvou, alebo nedostupné uzly.

          +

          Pridať Uzol

          +

          Dotykom na tlačítko "Pridať Uzol" vložíte detaily vlastného uzla. + "Adresa" je hostname alebo IP-adresa uzla. Je to jediné povinné pole. + "Port" ak uzol používa iný ako predvolený port (napr. 18089). + Môžte si aj pomenovať svoje uzly pre budúce použitie. Je to voliteľné. + Niektoré uzly vyžadujú na používanie aj prihlasovacie údaje. V tom prípade napíšte užívateľské meno a heslo do príslušných polí. + To by malo stačiť na testovanie týchto nastavení. "Test" + "Výsledky Testu" zobrazia výšku, čas odozvy a aktuálnu IP adresu uzla. + Vo výsledku môže byť tiež chyba - zvyčajne preto, že uzol nie je dostupný, neodpovedá v požadovanom čase, alebo prihlasovacie údaje nie sú správne. + Prípadne kombinácia zadanej adresy a portu neprislúcha žiadnemu uzlu Monero siete! + Akonáhle test skončí úspešne (žiadna chyba sa neobjaví) - klepni na "OK" a ulož si daný uzol.

          +

          Vyhľadať Uzol

          +

          Táto funkcia umožní vyhľadať uzol skenovaním Monero siete. Monerujo začne skenovať sieť a vyhľadávať vzdialené uzly na porte 18089. + Začína tým, že sa opýta uzlov vo vašich záložkách na ďalšie uzly v P2P sieti Monero, ktoré sú s nimi spojené, tých sa opýta zas na ďalšie uzly atď. + V prípade, že nemáte žiadne uzly vo svojich záložkách, Monerujo bude skúšať uzly (seed nodes) natvrdo zapísané v kóde Monero. Vyhľadávanie končí ak Monerujo nájde aspoň 10 vzdialených uzlov.

          + ]]>
          + + Používanie platobného linku +

          Monerujo je spustené z platobného linku. Ak chceš posielať prostriedky, postupuj nasledovne:

          +

          + 1. Otvor peňaženku z ktorej chceš platiť
          + 2. Počkaj kým sa peňaženka zosynchronizuje a zobrazí sa tlačítko "Poslať"
          + 3. Stlač tlačidlo "Poslať" +

          +

          Detaily platby budú vložené automaticky. Skontroluj ich a pokračuj ako obvykle pri ostatných transakciách.

          + ]]>
          + + Rozumiem! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          + diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index dc44703b..341a72b4 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -228,7 +228,7 @@ Vytvor Chybu Transakcie - - poplatok %1$s + poplatok %1$s (%1$s) zlyhala - %1$s @@ -428,5 +428,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-sr/help.xml b/app/src/main/res/values-sr/help.xml index 7d8f1169..d8b92bbc 100644 --- a/app/src/main/res/values-sr/help.xml +++ b/app/src/main/res/values-sr/help.xml @@ -290,4 +290,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index b70094ff..ecaa26ad 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -237,7 +237,7 @@ Kreiraj transakcijsku grešku - - naknada %1$s + naknada %1$s (%1$s) neuspelo - %1$s @@ -426,5 +426,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-sv/help.xml b/app/src/main/res/values-sv/help.xml index fe21ebf8..e3f80d88 100644 --- a/app/src/main/res/values-sv/help.xml +++ b/app/src/main/res/values-sv/help.xml @@ -279,4 +279,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index eb8b5536..7fc6e546 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -218,7 +218,7 @@ Ett fel uppstod när transaktion skapades - - Avgift %1$s + Avgift %1$s (%1$s) misslyckades - %1$s @@ -419,5 +419,10 @@ Importeringen misslyckad! Återställ plånbok! - Denna plånbok kommer att återställas och förlorar all off-chain data (som anteckningar, konto- och subadresser, privata transaktionsnycklar, ...)! Använd ENDAST detta om den här plånboken är skadad och inte laddas! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-uk/help.xml b/app/src/main/res/values-uk/help.xml index 12b3ec93..c968fea9 100644 --- a/app/src/main/res/values-uk/help.xml +++ b/app/src/main/res/values-uk/help.xml @@ -4,18 +4,18 @@

          Створити гаманець - Новий

          Якщо вам потрібна нова адреса Monero!

          Введіть унікальне і\'мя та пароль гаманця. -        Пароль використовується для захисту даних вашого гаманця на Android пристрої. + Пароль використовується для захисту даних вашого гаманця на Android пристрої. Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль.

          Запишіть вашу мнемонічну фразу!

          Наступний екран буде містити вашу \"мнемонічну фразу\", що складається з 25 слів. -        Це єдині дані, які необхідні для відновлення вашого гаманця в -        майбутньому і отримання доступу до ваших коштів. -        Підтримувати її безпеку і конфіденційність дуже важливо, так як це -     гарантує, що ніхто не зможе отримати доступ до ваших коштів!

          + Це єдині дані, які необхідні для відновлення вашого гаманця в + майбутньому і отримання доступу до ваших коштів. + Підтримувати її безпеку і конфіденційність дуже важливо, так як це + гарантує, що ніхто не зможе отримати доступ до ваших коштів!

          Якщо ви втратите пароль від вашого гаманця, ви зможете відновити його, використовуючи мнемонічну фразу.

          Спосіб відновлення мнемонічної фрази відсутній. У разі її втрати - будуть втрачені -     і всі ваші кошти! Також ви ніколи не зможете змінити мнемонічну фразу, і якщо вона + і всі ваші кошти! Також ви ніколи не зможете змінити мнемонічну фразу, і якщо вона буде вкрадена або розкрита будь-яким іншим чином, то вам доведеться перенести ваші кошти в новий гаманець (з новою мнемонічною фразою). Тому рекомендується створити резервну копію вашої мнемонічною фрази, записавши її, і зберігати декілька копій в безпечному місці.

          @@ -61,7 +61,7 @@ не боячись втратити свої Monero. Monero відправлятимуть на ваш гаманець, використовуючи саме цю адресу.

          Мнемонічна фраза

          Це єдині дані, які необхідні для відновлення вашого гаманця в майбутньому, і отримання -        доступу до ваших коштів. Підтримувати її безпеку і конфіденційність дуже важливо, + доступу до ваших коштів. Підтримувати її безпеку і конфіденційність дуже важливо, так як це гарантує, що ніхто не зможе отримати доступ до ваших коштів! Якщо ви не записали цю фразу, і не зберегли її в безпечному місці, зробіть це негайно!

          Файли відновлення паролю гаманця

          @@ -207,10 +207,10 @@

          Ваші секретні ключі ніколи не покинуть пристрій Ledger. Вам потрібен пристрій кожен раз, коли ви хочете отримати доступ до свого гаманця.

          Необхідно ввести унікальні і&apos:мя і пароль гаманця. Пароль використовується для захисту даних вашого -         гаманця на пристрої. Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль.

          + гаманця на пристрої. Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль.

          Якщо вам відомий номер блоку першої транзакції, який використовувався з цією адресою, слід -         ввести його в поле \"Відновити висоту\". Ви також можете використовувати дату в форматі YYYY-MM-DD. -  Якщо ви не впевнені, введіть приблизну дату/висоту блоку до того, як ви вперше використали цей гаманець.

          + ввести його в поле \"Відновити висоту\". Ви також можете використовувати дату в форматі YYYY-MM-DD. + Якщо ви не впевнені, введіть приблизну дату/висоту блоку до того, як ви вперше використали цей гаманець.

          ]]> Допоможіть! Баланс мого гаманця кудись зник або не підтверджений!
          Не панікуйте! Якщо ви відправляєте кошти з вашого гаманця, ваш баланс тимчасово залишається непідтвердженим. Це відбувається в результаті процесу обміну Monero в блокчейні, і роботи механізму -        решти. Подробиці обміну можна дізнатися за посиланням: + решти. Подробиці обміну можна дізнатися за посиланням: https://getmonero.org/resources/moneropedia/change.html

          Список транзакцій

          Список транзакцій, проведених з використанням цього гаманця. У гаманцях перегляду можна побачити @@ -278,8 +278,6 @@ Сканування зупиниться, як тільки буде знайдено 10 віддалених вузлів.

          ]]>
          - - Використання плажіного посилання

          Ви почали використовувати Monerujo з платіжним посиланням. Для надсилання коштів, будь ласка, виконайте найступне:

          @@ -292,4 +290,25 @@ ]]>
          Я зрозумів! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 73d31a92..6c33563f 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -231,7 +231,7 @@ Помилка створення транзакції - - Комісія %1$s + Комісія %1$s (%1$s) Не вдалося - %1$s @@ -431,5 +431,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-zh-rCN/help.xml b/app/src/main/res/values-zh-rCN/help.xml index de084104..2d508d27 100644 --- a/app/src/main/res/values-zh-rCN/help.xml +++ b/app/src/main/res/values-zh-rCN/help.xml @@ -26,7 +26,7 @@ 选择输入一个估算的日期或区块高度,但这个日期或区块高度对应的时间必须在你第一次使用该地址之前

          ]]> -用Ledger恢复钱包

          如果你已经拥有一个钱包地址,并想用Ledger Nano S来恢复你的钱包。

          因为你的密钥时刻存储在Ledger设备中,所以你每次访问钱包的时候,都需要插入Ledger设备。

          @@ -35,8 +35,8 @@

          请在\"恢复高度\"中输入你在这个地址上的第一笔交易所在的区块高度。你也可以使用YYYY-MM-DD的格式来输入日期。如果你不是十分确定,也可以 选择输入一个估算的日期或区块高度,但这个日期或区块高度对应的时间必须在你第一次使用该地址之前

          ]]>
          - - 用密钥恢复钱包

          如果你已经拥有一个钱包地址,并想用密钥恢复它。

          请输入钱包名称(不得重复)和密码。 @@ -230,4 +230,25 @@ ]]> 我明白了! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 084f3595..dc5dbd77 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -182,7 +182,7 @@ %1$s XMR +%1$s 手续费 创建交易发生错误 - - 手续费 %1$s + 手续费 %1$s (%1$s) 失败 - %1$s @@ -351,5 +351,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values-zh-rTW/help.xml b/app/src/main/res/values-zh-rTW/help.xml index a7bfd65c..6613b5e3 100644 --- a/app/src/main/res/values-zh-rTW/help.xml +++ b/app/src/main/res/values-zh-rTW/help.xml @@ -231,4 +231,25 @@ ]]> 我知道了! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 61991b52..e0e6c944 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -229,7 +229,7 @@ 建立交易錯誤 - - 手續費 %1$s + 手續費 %1$s (%1$s) 失敗 - %1$s @@ -426,5 +426,10 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values/help.xml b/app/src/main/res/values/help.xml index 6d5de44d..14571e07 100644 --- a/app/src/main/res/values/help.xml +++ b/app/src/main/res/values/help.xml @@ -290,4 +290,25 @@ ]]> Got it! + + Nah… + Get Orbot! + Tor +

          Tor, short for The Onion Router, is free and open-source software for enabling anonymous + communication.

          +

          Enabling Tor will route your connection through several relays and hide your IP address + from the node. Keep in mind this is more private but also slower.

          +

          In order to use Tor with Monerujo, you\'ll need Orbot installed on your phone. After + installing Orbot, make sure to enable it by clicking the network icon on the wallet list + screen.

          +

          If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon + on the top right).

          + ]]>
          + + Tor Node +

          This is an .onion node. In order to use it, you must enable Tor mode by touching the + icon near the top of the Wallet List page.

          + ]]>
          diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 161e49de..acad7c7f 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -100,7 +100,7 @@ Change Password failed! Password changed - Node + Network Stagenet Testnet Loading Wallet … @@ -243,7 +243,7 @@ Create Transaction Error - - Fee %1$s + Fee %1$s (%1$s) failed - %1$s @@ -499,5 +499,12 @@ Import failed! Reset wallet! - This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load! + This wallet will be reset, losing all off-chain data (like notes, account & subaddress names, private transaction keys, …)! Use this ONLY if this wallet is corrupt and does not load! + + <span style=\"background-color: #%1$s; color: #%2$s;\">%3$s</span>%4$s + + Tor required + \u00A0WAITING FOR NODE\u00A0 + "Allow Background Starts" in Orbot Settings to use Tor! + SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR. diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index f254d698..f1427dc0 100644 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -36,8 +36,7 @@