From 8f3d64405df10d81e54bf85e7992ca5056130c6b Mon Sep 17 00:00:00 2001
From: Paxriel
Date: Wed, 2 Mar 2022 14:54:14 +0800
Subject: [PATCH] Closes PR #1
---
app/CMakeLists.txt | 5 +
app/build.gradle | 25 +-
app/src/main/AndroidManifest.xml | 18 +
app/src/main/cpp/monerujo.cpp | 40 +-
.../com/m2049r/levin/scanner/Dispatcher.java | 2 +-
.../m2049r/xmrwallet/GenerateFragment.java | 332 +++++------
.../xmrwallet/GenerateReviewFragment.java | 214 +++++--
.../com/m2049r/xmrwallet/LoginActivity.java | 72 ++-
.../com/m2049r/xmrwallet/LoginFragment.java | 125 +++-
.../com/m2049r/xmrwallet/NodeFragment.java | 60 +-
.../m2049r/xmrwallet/SubaddressFragment.java | 6 +-
.../com/m2049r/xmrwallet/WalletActivity.java | 5 +-
.../com/m2049r/xmrwallet/WalletFragment.java | 12 +-
.../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 | 28 +-
.../xmrwallet/model/TransactionHistory.java | 16 +-
.../xmrwallet/model/TransactionInfo.java | 6 +
.../com/m2049r/xmrwallet/model/Wallet.java | 20 +-
.../m2049r/xmrwallet/model/WalletManager.java | 16 +-
.../xmrwallet/service/WalletService.java | 6 +-
.../service/exchange/ecb/ExchangeApiImpl.java | 24 +-
.../exchange/kraken/ExchangeApiImpl.java | 25 +-
.../exchange/krakenEcb/ExchangeApiImpl.java | 11 +-
.../sideshift/network/RequestQuoteImpl.java | 20 +-
.../sideshift/network/SideShiftApiImpl.java | 25 +-
.../com/m2049r/xmrwallet/util/Helper.java | 28 +-
.../xmrwallet/util/NetCipherHelper.java | 393 +++++++++++++
.../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 +-
.../res/drawable/ic_baseline_cancel_24.xml | 10 +
.../ic_baseline_keyboard_arrow_down_24.xml | 10 +
.../ic_baseline_keyboard_arrow_up_24.xml | 10 +
.../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_generate.xml | 44 +-
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 +-
app/src/main/res/layout/fragment_review.xml | 58 +-
.../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 | 6 +-
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 | 427 --------------
app/src/main/res/values-cat/help.xml | 139 +++--
app/src/main/res/values-cat/strings.xml | 18 +-
app/src/main/res/values-de/help.xml | 21 +
app/src/main/res/values-de/strings.xml | 16 +-
app/src/main/res/values-el/help.xml | 21 +
app/src/main/res/values-el/strings.xml | 16 +-
app/src/main/res/values-eo/help.xml | 23 +-
app/src/main/res/values-eo/strings.xml | 16 +-
app/src/main/res/values-es/help.xml | 21 +
app/src/main/res/values-es/strings.xml | 16 +-
app/src/main/res/values-et/help.xml | 21 +
app/src/main/res/values-et/strings.xml | 16 +-
app/src/main/res/values-fr/help.xml | 21 +
app/src/main/res/values-fr/strings.xml | 16 +-
app/src/main/res/values-hu/help.xml | 21 +
app/src/main/res/values-hu/strings.xml | 16 +-
app/src/main/res/values-it/help.xml | 42 +-
app/src/main/res/values-it/strings.xml | 101 ++--
app/src/main/res/values-ja/help.xml | 21 +
app/src/main/res/values-ja/strings.xml | 16 +-
app/src/main/res/values-nb/help.xml | 21 +
app/src/main/res/values-nb/strings.xml | 16 +-
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 | 16 +-
app/src/main/res/values-pt-rBR/help.xml | 21 +
app/src/main/res/values-pt-rBR/strings.xml | 44 +-
app/src/main/res/values-pt/help.xml | 21 +
app/src/main/res/values-pt/strings.xml | 16 +-
app/src/main/res/values-ro/help.xml | 21 +
app/src/main/res/values-ro/strings.xml | 16 +-
app/src/main/res/values-ru/help.xml | 19 +
app/src/main/res/values-ru/strings.xml | 16 +-
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 | 16 +-
app/src/main/res/values-sr/help.xml | 21 +
app/src/main/res/values-sr/strings.xml | 16 +-
app/src/main/res/values-sv/help.xml | 21 +
app/src/main/res/values-sv/strings.xml | 16 +-
app/src/main/res/values-uk/help.xml | 45 +-
app/src/main/res/values-uk/strings.xml | 16 +-
app/src/main/res/values-zh-rCN/help.xml | 27 +-
app/src/main/res/values-zh-rCN/strings.xml | 16 +-
app/src/main/res/values-zh-rTW/help.xml | 21 +
app/src/main/res/values-zh-rTW/strings.xml | 16 +-
app/src/main/res/values/help.xml | 21 +
app/src/main/res/values/strings.xml | 18 +-
app/src/main/res/values/styles.xml | 3 +-
.../exchange/ecb/ExchangeRateTest.java | 6 +-
.../exchange/kraken/ExchangeRateTest.java | 6 +-
.../SideShiftApiCreateOrderTest.java | 12 +-
.../SideShiftApiOrderParameterTest.java | 6 +-
.../SideShiftApiQueryOrderStatusTest.java | 12 +-
.../SideShiftApiRequestQuoteTest.java | 6 +-
build.gradle | 9 +-
external-libs/VERSION | 2 +-
external-libs/include/wallet2_api.h | 36 +-
gradle/wrapper/gradle-wrapper.properties | 2 +-
119 files changed, 2996 insertions(+), 1973 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_baseline_cancel_24.xml
create mode 100644 app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml
create mode 100644 app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml
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
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/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/app/build.gradle b/app/build.gradle
index a02c046e..8cb20095 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 1301
+ versionName "2.3.1 'Doménikos'"
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'
@@ -142,8 +145,7 @@ dependencies {
implementation 'com.unstoppabledomains:resolution:3.0.0'
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
- implementation 'com.github.aelstad:keccakj:1.1.0'
-
+ //noinspection GradleDependency
testImplementation "junit:junit:$rootProject.ext.junitVersion"
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0"
@@ -153,3 +155,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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
java2cpp(JNIEnv *env, jobject arrayList) {
return result;
}
-jobject cpp2java(JNIEnv *env, const std::vector& vector) {
+jobject cpp2java(JNIEnv *env, const std::vector &vector) {
jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "", "(I)V");
jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
@@ -301,12 +301,13 @@ Java_com_m2049r_xmrwallet_model_WalletManager_openWalletJ(JNIEnv *env, jobject i
JNIEXPORT jlong JNICALL
Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobject instance,
jstring path, jstring password,
- jstring mnemonic,
+ jstring mnemonic, jstring offset,
jint networkType,
jlong restoreHeight) {
const char *_path = env->GetStringUTFChars(path, nullptr);
const char *_password = env->GetStringUTFChars(password, nullptr);
const char *_mnemonic = env->GetStringUTFChars(mnemonic, nullptr);
+ const char *_offset = env->GetStringUTFChars(offset, nullptr);
Monero::NetworkType _networkType = static_cast(networkType);
Bitmonero::Wallet *wallet =
@@ -315,11 +316,14 @@ Java_com_m2049r_xmrwallet_model_WalletManager_recoveryWalletJ(JNIEnv *env, jobje
std::string(_password),
std::string(_mnemonic),
_networkType,
- (uint64_t) restoreHeight);
+ (uint64_t) restoreHeight,
+ 1, // kdf_rounds
+ std::string(_offset));
env->ReleaseStringUTFChars(path, _path);
env->ReleaseStringUTFChars(password, _password);
env->ReleaseStringUTFChars(mnemonic, _mnemonic);
+ env->ReleaseStringUTFChars(offset, _offset);
return reinterpret_cast(wallet);
}
@@ -531,6 +535,17 @@ Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobj
return env->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
@@ -559,9 +574,12 @@ Java_com_m2049r_xmrwallet_model_WalletManager_closeJ(JNIEnv *env, jobject instan
/**********************************/
JNIEXPORT jstring JNICALL
-Java_com_m2049r_xmrwallet_model_Wallet_getSeed(JNIEnv *env, jobject instance) {
+Java_com_m2049r_xmrwallet_model_Wallet_getSeed(JNIEnv *env, jobject instance, jstring seedOffset) {
+ const char *_seedOffset = env->GetStringUTFChars(seedOffset, nullptr);
Bitmonero::Wallet *wallet = getHandle(env, instance);
- return env->NewStringUTF(wallet->seed().c_str());
+ jstring seed = env->NewStringUTF(wallet->seed(std::string(_seedOffset)).c_str());
+ env->ReleaseStringUTFChars(seedOffset, _seedOffset);
+ return seed;
}
JNIEXPORT jstring JNICALL
@@ -727,6 +745,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) {
@@ -1241,7 +1269,7 @@ jobject newTransactionInfo(JNIEnv *env, Bitmonero::TransactionInfo *info) {
#include
#include
-jobject cpp2java(JNIEnv *env, const std::vector& vector) {
+jobject cpp2java(JNIEnv *env, const std::vector &vector) {
jmethodID java_util_ArrayList_ = env->GetMethodID(class_ArrayList, "", "(I)V");
jmethodID java_util_ArrayList_add = env->GetMethodID(class_ArrayList, "add",
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/GenerateFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateFragment.java
index 079956fc..42fe137b 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;
@@ -78,6 +81,9 @@ public class GenerateFragment extends Fragment {
private TextInputLayout etWalletRestoreHeight;
private Button bGenerate;
+ private Button bSeedOffset;
+ private TextInputLayout etSeedOffset;
+
private String type = null;
private void clearErrorOnTextEntry(final TextInputLayout textInputLayout) {
@@ -115,139 +121,103 @@ public class GenerateFragment extends Fragment {
etWalletSpendKey = view.findViewById(R.id.etWalletSpendKey);
etWalletRestoreHeight = view.findViewById(R.id.etWalletRestoreHeight);
bGenerate = view.findViewById(R.id.bGenerate);
+ bSeedOffset = view.findViewById(R.id.bSeedOffset);
+ etSeedOffset = view.findViewById(R.id.etSeedOffset);
etWalletAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
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 +226,22 @@ 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) {
+ });
+ bSeedOffset.setVisibility(View.VISIBLE);
+ bSeedOffset.setOnClickListener(v -> toggleSeedOffset());
+ 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 +250,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 +265,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();
@@ -342,6 +295,18 @@ public class GenerateFragment extends Fragment {
return view;
}
+ void toggleSeedOffset() {
+ if (etSeedOffset.getVisibility() == View.VISIBLE) {
+ etSeedOffset.getEditText().getText().clear();
+ etSeedOffset.setVisibility(View.GONE);
+ bSeedOffset.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_baseline_keyboard_arrow_down_24, 0, 0, 0);
+ } else {
+ etSeedOffset.setVisibility(View.VISIBLE);
+ bSeedOffset.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_baseline_keyboard_arrow_up_24, 0, 0, 0);
+ etSeedOffset.requestFocusFromTouch();
+ }
+ }
+
private boolean checkName() {
String name = etWalletName.getEditText().getText().toString();
boolean ok = true;
@@ -387,7 +352,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 +360,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 +431,47 @@ 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;
+ final String seed = etWalletMnemonic.getEditText().getText().toString();
+ bGenerate.setEnabled(false);
+ if (fingerprintAuthAllowed) {
+ KeyStoreHelper.saveWalletUserPass(requireActivity(), name, password);
+ }
+ final String offset = etSeedOffset.getEditText().getText().toString();
+ activityCallback.onGenerate(name, crazyPass, seed, offset, 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;
}
}
@@ -539,7 +511,7 @@ public class GenerateFragment extends Fragment {
public interface Listener {
void onGenerate(String name, String password);
- void onGenerate(String name, String password, String seed, long height);
+ void onGenerate(String name, String password, String seed, String offset, long height);
void onGenerate(String name, String password, String address, String viewKey, String spendKey, long height);
@@ -552,7 +524,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 +567,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 +592,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()) {
diff --git a/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java b/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java
index 863ad00a..368317cb 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/GenerateReviewFragment.java
@@ -32,6 +32,7 @@ import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
+import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
@@ -45,6 +46,7 @@ import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.progressindicator.CircularProgressIndicator;
import com.google.android.material.switchmaterial.SwitchMaterial;
import com.google.android.material.textfield.TextInputLayout;
import com.m2049r.xmrwallet.ledger.Ledger;
@@ -77,6 +79,7 @@ public class GenerateReviewFragment extends Fragment {
private ProgressBar pbProgress;
private TextView tvWalletPassword;
private TextView tvWalletAddress;
+ private FrameLayout flWalletMnemonic;
private TextView tvWalletMnemonic;
private TextView tvWalletHeight;
private TextView tvWalletViewKey;
@@ -90,6 +93,9 @@ public class GenerateReviewFragment extends Fragment {
private Button bAdvancedInfo;
private Button bAccept;
+ private Button bSeedOffset;
+ private TextInputLayout etSeedOffset;
+
private String walletPath;
private String walletName;
@@ -106,6 +112,7 @@ public class GenerateReviewFragment extends Fragment {
tvWalletViewKey = view.findViewById(R.id.tvWalletViewKey);
tvWalletSpendKey = view.findViewById(R.id.tvWalletSpendKey);
tvWalletMnemonic = view.findViewById(R.id.tvWalletMnemonic);
+ flWalletMnemonic = view.findViewById(R.id.flWalletMnemonic);
tvWalletHeight = view.findViewById(R.id.tvWalletHeight);
bCopyAddress = view.findViewById(R.id.bCopyAddress);
bAdvancedInfo = view.findViewById(R.id.bAdvancedInfo);
@@ -115,6 +122,9 @@ public class GenerateReviewFragment extends Fragment {
llSpendKey = view.findViewById(R.id.llSpendKey);
llViewKey = view.findViewById(R.id.llViewKey);
+ etSeedOffset = view.findViewById(R.id.etSeedOffset);
+ bSeedOffset = view.findViewById(R.id.bSeedOffset);
+
bAccept = view.findViewById(R.id.bAccept);
boolean allowCopy = WalletManager.getInstance().getNetworkType() != NetworkType.NetworkType_Mainnet;
@@ -126,7 +136,25 @@ public class GenerateReviewFragment extends Fragment {
view.findViewById(R.id.bCopyViewKey).setOnClickListener(v -> copyViewKey());
bCopyAddress.setEnabled(false);
bCopyAddress.setOnClickListener(v -> copyAddress());
- view.findViewById(R.id.bAdvancedInfo).setOnClickListener(v -> showAdvancedInfo());
+ bAdvancedInfo.setOnClickListener(v -> toggleAdvancedInfo());
+
+ bSeedOffset.setOnClickListener(v -> toggleSeedOffset());
+ etSeedOffset.getEditText().addTextChangedListener(new TextWatcher() {
+ @Override
+ public void afterTextChanged(Editable s) {
+ showSeed();
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start,
+ int count, int after) {
+ }
+
+ @Override
+ public void onTextChanged(CharSequence s, int start,
+ int before, int count) {
+ }
+ });
Bundle args = getArguments();
type = args.getString(REQUEST_TYPE);
@@ -136,18 +164,32 @@ public class GenerateReviewFragment extends Fragment {
return view;
}
+ String getSeedOffset() {
+ return etSeedOffset.getEditText().getText().toString();
+ }
+
+ boolean seedOffsetInProgress = false;
+
+ void showSeed() {
+ synchronized (this) {
+ if (seedOffsetInProgress) return;
+ seedOffsetInProgress = true;
+ }
+ new AsyncShowSeed().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR, walletPath);
+ }
+
void showDetails() {
tvWalletPassword.setText(null);
new AsyncShow().executeOnExecutor(MoneroThreadPoolExecutor.MONERO_THREAD_POOL_EXECUTOR, walletPath);
}
void copyViewKey() {
- Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_viewkey), tvWalletViewKey.getText().toString());
+ Helper.clipBoardCopy(requireActivity(), getString(R.string.label_copy_viewkey), tvWalletViewKey.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_viewkey), Toast.LENGTH_SHORT).show();
}
void copyAddress() {
- Helper.clipBoardCopy(getActivity(), getString(R.string.label_copy_address), tvWalletAddress.getText().toString());
+ Helper.clipBoardCopy(requireActivity(), getString(R.string.label_copy_address), tvWalletAddress.getText().toString());
Toast.makeText(getActivity(), getString(R.string.message_copy_address), Toast.LENGTH_SHORT).show();
}
@@ -155,15 +197,27 @@ public class GenerateReviewFragment extends Fragment {
Toast.makeText(getActivity(), getString(R.string.message_nocopy), Toast.LENGTH_SHORT).show();
}
- void showAdvancedInfo() {
- llAdvancedInfo.setVisibility(View.VISIBLE);
- bAdvancedInfo.setVisibility(View.GONE);
- scrollview.post(new Runnable() {
- @Override
- public void run() {
- scrollview.fullScroll(ScrollView.FOCUS_DOWN);
- }
- });
+ void toggleAdvancedInfo() {
+ if (llAdvancedInfo.getVisibility() == View.VISIBLE) {
+ llAdvancedInfo.setVisibility(View.GONE);
+ bAdvancedInfo.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_baseline_keyboard_arrow_down_24, 0, 0, 0);
+ } else {
+ llAdvancedInfo.setVisibility(View.VISIBLE);
+ bAdvancedInfo.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_baseline_keyboard_arrow_up_24, 0, 0, 0);
+ scrollview.post(() -> scrollview.fullScroll(ScrollView.FOCUS_DOWN));
+ }
+ }
+
+ void toggleSeedOffset() {
+ if (etSeedOffset.getVisibility() == View.VISIBLE) {
+ etSeedOffset.getEditText().getText().clear();
+ etSeedOffset.setVisibility(View.GONE);
+ bSeedOffset.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_baseline_keyboard_arrow_down_24, 0, 0, 0);
+ } else {
+ etSeedOffset.setVisibility(View.VISIBLE);
+ bSeedOffset.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_baseline_keyboard_arrow_up_24, 0, 0, 0);
+ etSeedOffset.requestFocusFromTouch();
+ }
}
String type;
@@ -180,7 +234,6 @@ public class GenerateReviewFragment extends Fragment {
String seed;
String viewKey;
String spendKey;
- boolean isWatchOnly;
Wallet.Status walletStatus;
boolean dialogOpened = false;
@@ -215,14 +268,13 @@ public class GenerateReviewFragment extends Fragment {
name = wallet.getName();
walletStatus = wallet.getStatus();
if (!walletStatus.isOk()) {
- Timber.e(walletStatus.getErrorString());
if (closeWallet) wallet.close();
return false;
}
address = wallet.getAddress();
height = wallet.getRestoreHeight();
- seed = wallet.getSeed();
+ seed = wallet.getSeed(getSeedOffset());
switch (wallet.getDeviceType()) {
case Device_Ledger:
viewKey = Ledger.Key();
@@ -233,8 +285,7 @@ public class GenerateReviewFragment extends Fragment {
default:
throw new IllegalStateException("Hardware backing not supported. At all!");
}
- spendKey = isWatchOnly ? getActivity().getString(R.string.label_watchonly) : wallet.getSecretSpendKey();
- isWatchOnly = wallet.isWatchOnly();
+ spendKey = wallet.isWatchOnly() ? getActivity().getString(R.string.label_watchonly) : wallet.getSecretSpendKey();
if (closeWallet) wallet.close();
return true;
}
@@ -367,7 +418,7 @@ public class GenerateReviewFragment extends Fragment {
}
public void hideProgress() {
- pbProgress.setVisibility(View.GONE);
+ pbProgress.setVisibility(View.INVISIBLE);
}
boolean backOk() {
@@ -407,10 +458,7 @@ public class GenerateReviewFragment extends Fragment {
Wallet.Status walletStatus = wallet.getStatus();
if (walletStatus.isOk()) {
wallet.setPassword(newPassword);
- wallet.store();
ok = true;
- } else {
- Timber.e(walletStatus.getErrorString());
}
if (closeWallet) wallet.close();
return ok;
@@ -470,7 +518,7 @@ public class GenerateReviewFragment extends Fragment {
LayoutInflater li = LayoutInflater.from(getActivity());
View promptsView = li.inflate(R.layout.prompt_changepw, null);
- AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(getActivity());
+ AlertDialog.Builder alertDialogBuilder = new MaterialAlertDialogBuilder(requireActivity());
alertDialogBuilder.setView(promptsView);
final PasswordEntryView etPasswordA = promptsView.findViewById(R.id.etWalletPasswordA);
@@ -484,23 +532,20 @@ public class GenerateReviewFragment extends Fragment {
if (FingerprintHelper.isDeviceSupported(getActivity())) {
llFingerprintAuth.setVisibility(View.VISIBLE);
- swFingerprintAllowed.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (!swFingerprintAllowed.isChecked()) return;
+ swFingerprintAllowed.setOnClickListener(view -> {
+ if (!swFingerprintAllowed.isChecked()) return;
- AlertDialog.Builder 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();
- }
+ AlertDialog.Builder 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), new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialogInterface, int i) {
+ swFingerprintAllowed.setChecked(false);
+ }
+ })
+ .show();
});
swFingerprintAllowed.setChecked(FingerprintHelper.isFingerPassValid(getActivity(), walletName));
@@ -551,7 +596,7 @@ public class GenerateReviewFragment extends Fragment {
.setNegativeButton(getString(R.string.label_cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
- Helper.hideKeyboardAlways(getActivity());
+ Helper.hideKeyboardAlways(requireActivity());
dialog.cancel();
openDialog = null;
}
@@ -567,7 +612,7 @@ public class GenerateReviewFragment extends Fragment {
etPasswordB.setError(getString(R.string.generate_bad_passwordB));
} else {
new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
- Helper.hideKeyboardAlways(getActivity());
+ Helper.hideKeyboardAlways(requireActivity());
openDialog.dismiss();
openDialog = null;
}
@@ -575,25 +620,23 @@ public class GenerateReviewFragment extends Fragment {
});
// accept keyboard "ok"
- etPasswordB.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)) {
- String newPasswordA = etPasswordA.getEditText().getText().toString();
- String newPasswordB = etPasswordB.getEditText().getText().toString();
- // disallow empty passwords
- if (!newPasswordA.equals(newPasswordB)) {
- etPasswordB.setError(getString(R.string.generate_bad_passwordB));
- } else {
- new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
- Helper.hideKeyboardAlways(getActivity());
- openDialog.dismiss();
- openDialog = null;
- }
- return true;
+ etPasswordB.getEditText().setOnEditorActionListener((v, actionId, event) -> {
+ if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
+ || (actionId == EditorInfo.IME_ACTION_DONE)) {
+ String newPasswordA = etPasswordA.getEditText().getText().toString();
+ String newPasswordB = etPasswordB.getEditText().getText().toString();
+ // disallow empty passwords
+ if (!newPasswordA.equals(newPasswordB)) {
+ etPasswordB.setError(getString(R.string.generate_bad_passwordB));
+ } else {
+ new AsyncChangePassword().execute(newPasswordA, Boolean.toString(swFingerprintAllowed.isChecked()));
+ Helper.hideKeyboardAlways(requireActivity());
+ openDialog.dismiss();
+ openDialog = null;
}
- return false;
+ return true;
}
+ return false;
});
if (Helper.preventScreenshot()) {
@@ -609,4 +652,61 @@ public class GenerateReviewFragment extends Fragment {
&& !key.toLowerCase().equals("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
// ledger implmenetation returns the spend key as f's
}
+
+ private class AsyncShowSeed extends AsyncTask {
+ String seed;
+ String offset;
+ Wallet.Status walletStatus;
+
+ @Override
+ protected void onPreExecute() {
+ super.onPreExecute();
+ offset = getSeedOffset();
+ flWalletMnemonic.setAlpha(0.1f);
+ }
+
+ @Override
+ protected Boolean doInBackground(String... params) {
+ if (params.length != 1) return false;
+ String walletPath = params[0];
+
+ Wallet wallet;
+ boolean closeWallet;
+ if (type.equals(GenerateReviewFragment.VIEW_TYPE_WALLET)) {
+ wallet = GenerateReviewFragment.this.walletCallback.getWallet();
+ closeWallet = false;
+ } else {
+ wallet = WalletManager.getInstance().openWallet(walletPath, getPassword());
+ closeWallet = true;
+ }
+ walletStatus = wallet.getStatus();
+ if (!walletStatus.isOk()) {
+ if (closeWallet) wallet.close();
+ return false;
+ }
+
+ seed = wallet.getSeed(offset);
+ if (closeWallet) wallet.close();
+ return true;
+ }
+
+ @Override
+ protected void onPostExecute(Boolean result) {
+ super.onPostExecute(result);
+ if (!isAdded()) return; // never mind
+ if (result) {
+ if (!seed.isEmpty()) {
+ llMnemonic.setVisibility(View.VISIBLE);
+ tvWalletMnemonic.setText(seed);
+ }
+ } else {
+ tvWalletMnemonic.setText(walletStatus.toString());
+ }
+ seedOffsetInProgress = false;
+ if (!getSeedOffset().equals(offset)) { // make sure we have encrypted with the correct offset
+ showSeed(); // seed has changed in the meantime - recalc
+ } else
+ flWalletMnemonic.setAlpha(1);
+ }
+ }
}
diff --git a/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java b/app/src/main/java/com/m2049r/xmrwallet/LoginActivity.java
index 539095a6..0b630175 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 {
@@ -927,7 +929,8 @@ public class LoginActivity extends BaseActivity
}
@Override
- public void onGenerate(final String name, final String password, final String seed,
+ public void onGenerate(final String name, final String password,
+ final String seed, final String offset,
final long restoreHeight) {
createWallet(name, password,
new WalletCreator() {
@@ -939,7 +942,7 @@ public class LoginActivity extends BaseActivity
@Override
public boolean createWallet(File aFile, String password) {
Wallet newWallet = WalletManager.getInstance()
- .recoveryWallet(aFile, password, seed, restoreHeight);
+ .recoveryWallet(aFile, password, seed, offset, restoreHeight);
return checkAndCloseWallet(newWallet);
}
});
@@ -1469,4 +1472,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/SubaddressFragment.java b/app/src/main/java/com/m2049r/xmrwallet/SubaddressFragment.java
index 9c83f5c8..8b377592 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/SubaddressFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/SubaddressFragment.java
@@ -67,6 +67,8 @@ public class SubaddressFragment extends Fragment implements SubaddressInfoAdapte
void setToolbarButton(int type);
void showSubaddress(View view, final int subaddressIndex);
+
+ void saveWallet();
}
public interface ProgressListener {
@@ -217,7 +219,9 @@ public class SubaddressFragment extends Fragment implements SubaddressInfoAdapte
protected Boolean doInBackground(Void... params) {
if (params.length != 0) return false;
wallet.getNewSubaddress();
- wallet.store();
+ if (activityCallback != null) {
+ activityCallback.saveWallet();
+ }
return true;
}
diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
index 96392c76..4f7cc08b 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
@@ -505,6 +505,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
Timber.d("onResume()");
}
+ @Override
public void saveWallet() {
if (mIsBound) { // no point in talking to unbound service
Intent intent = new Intent(getApplicationContext(), WalletService.class);
@@ -609,9 +610,7 @@ public class WalletActivity extends BaseActivity implements WalletFragment.Liste
@Override
public void onWalletStored(final boolean success) {
runOnUiThread(() -> {
- if (success) {
- Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_unloaded), Toast.LENGTH_SHORT).show();
- } else {
+ if (!success) {
Toast.makeText(WalletActivity.this, getString(R.string.status_wallet_unload_failed), Toast.LENGTH_LONG).show();
}
});
diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java b/app/src/main/java/com/m2049r/xmrwallet/WalletFragment.java
index c1e53cd5..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);
}
}
@@ -349,14 +351,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/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 f7057e39..80c5766b 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;
@@ -95,6 +96,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;
@@ -121,11 +123,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)) {
@@ -141,14 +144,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() {
@@ -515,6 +525,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 {
- 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 {
@@ -102,7 +100,7 @@ public class TransactionInfoAdapter 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);
@@ -228,9 +218,9 @@ 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/TransactionInfo.java b/app/src/main/java/com/m2049r/xmrwallet/model/TransactionInfo.java
index 17af6803..4b904e16 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/model/TransactionInfo.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/model/TransactionInfo.java
@@ -29,6 +29,8 @@ import lombok.RequiredArgsConstructor;
// this is not the TransactionInfo from the API as that is owned by the TransactionHistory
// this is a POJO for the TransactionInfoAdapter
public class TransactionInfo implements Parcelable, Comparable {
+ 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/java/com/m2049r/xmrwallet/model/Wallet.java b/app/src/main/java/com/m2049r/xmrwallet/model/Wallet.java
index 6653418f..e85d0f85 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;
}
}
@@ -129,7 +129,7 @@ public class Wallet {
ConnectionStatus_WrongVersion
}
- public native String getSeed();
+ public native String getSeed(String offset);
public native String getSeedLanguage();
@@ -147,7 +147,7 @@ public class Wallet {
private native Status statusWithErrorString();
- public native boolean setPassword(String password);
+ public native synchronized boolean setPassword(String password);
public String getAddress() {
return getAddress(accountIndex);
@@ -203,12 +203,10 @@ public class Wallet {
public native String getSecretSpendKey();
public boolean store() {
- final boolean ok = store("");
- Timber.d("stored");
- return ok;
+ return store("");
}
- public native boolean store(String path);
+ public native synchronized boolean store(String path);
public boolean close() {
disposePendingTransaction();
@@ -247,6 +245,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);
}
@@ -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/model/WalletManager.java b/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java
index 2a6ffd0d..555a1796 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/model/WalletManager.java
@@ -124,19 +124,19 @@ public class WalletManager {
private native long openWalletJ(String path, String password, int networkType);
- public Wallet recoveryWallet(File aFile, String password, String mnemonic) {
- return recoveryWallet(aFile, password, mnemonic, 0);
- }
-
- public Wallet recoveryWallet(File aFile, String password, String mnemonic, long restoreHeight) {
- long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), password, mnemonic,
+ public Wallet recoveryWallet(File aFile, String password,
+ String mnemonic, String offset,
+ long restoreHeight) {
+ long walletHandle = recoveryWalletJ(aFile.getAbsolutePath(), password,
+ mnemonic, offset,
getNetworkType().getValue(), restoreHeight);
Wallet wallet = new Wallet(walletHandle);
manageWallet(wallet);
return wallet;
}
- private native long recoveryWalletJ(String path, String password, String mnemonic,
+ private native long recoveryWalletJ(String path, String password,
+ String mnemonic, String offset,
int networkType, long restoreHeight);
public Wallet createWalletWithKeys(File aFile, String password, String language, long restoreHeight,
@@ -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 876c944c..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;
@@ -124,7 +125,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 +153,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);
}
@@ -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/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/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..418e97f9
--- /dev/null
+++ b/app/src/main/java/com/m2049r/xmrwallet/util/NetCipherHelper.java
@@ -0,0 +1,393 @@
+/*
+ * 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() {
+ if (mockClient != null) return mockClient; // Unit-test mode
+ 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();
+ }
+
+ // for unit tests only
+ static public OkHttpClient mockClient = null;
+ }
+
+ 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_baseline_cancel_24.xml b/app/src/main/res/drawable/ic_baseline_cancel_24.xml
new file mode 100644
index 00000000..583a772b
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_cancel_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml
new file mode 100644
index 00000000..d6ed3084
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_down_24.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml
new file mode 100644
index 00000000..5df167a1
--- /dev/null
+++ b/app/src/main/res/drawable/ic_baseline_keyboard_arrow_up_24.xml
@@ -0,0 +1,10 @@
+
+
+
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_generate.xml b/app/src/main/res/layout/fragment_generate.xml
index 20dbad75..8b2a2a99 100644
--- a/app/src/main/res/layout/fragment_generate.xml
+++ b/app/src/main/res/layout/fragment_generate.xml
@@ -15,7 +15,6 @@
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/header_top_first"
app:errorEnabled="true">
@@ -92,12 +91,41 @@
android:textAlignment="textStart" />
+
+
+
+
+
+
+
@@ -179,7 +207,7 @@
style="@style/MoneroButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="8dp"
+ android:layout_marginTop="@dimen/header_top_first"
android:text="@string/generate_buttonGenerate" />
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:visibility="invisible" />
+ android:layout_height="wrap_content">
+ android:visibility="visible">
-
+ android:layout_marginTop="@dimen/data_top">
+
+
+
+
+
+
+
+
+
+
+ app:icon="@drawable/ic_baseline_keyboard_arrow_down_24" />
diff --git a/app/src/main/res/layout/fragment_send_address.xml b/app/src/main/res/layout/fragment_send_address.xml
index 5e839585..8a857278 100644
--- a/app/src/main/res/layout/fragment_send_address.xml
+++ b/app/src/main/res/layout/fragment_send_address.xml
@@ -126,23 +126,38 @@
android:src="@drawable/ic_xmrto_doge_off" />
-
+ android:layout_marginBottom="16dp">
+
+
+
+
+
+ android:text="@string/tx_list_failed_text" />
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 f59ee309..00000000
--- a/app/src/main/res/values-ar/strings.xml
+++ /dev/null
@@ -1,427 +0,0 @@
-
-
- محفظة
-
- عن
- سياسة الخصوصية
-
- شارك
- ساعدني
- استلم
- أعد التسمية …
- Delete
- انشئ نسخة احتياطية
- غير كلمة المرور
-
- … أكمل الكتابة
- … مه
- هيا يمكنك القيام بأفضل من هذا!
- تكاد تصل …
- أجل، كالمحترفين!
-
- المحافظ
- الاعتمادات
- حسناً
- إلغاء
- أغلق
- المس لالتفاصيل
-
- نجح الإرسال
- تم
-
- المس لرمز استجابة سريعة (qr)
-
- دفع BTC مفعل، المس لمعلومات أكثر.
- لدجر مفعل، المس لمعلومات أكثر.
-
- أدخلت عنوان بيتكوين.
- سترسل XMR و سيستلم المستلم %1$s باستخدام خدمة 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قد يستغرق هذا برهةً!
-
- نجح النسخ الاحتياطي
- فشل النسخ الاحتياطي!
- Delete failed!
- فشلت إعادة التسمية!
- فشل تغيير كلمة السر!
- تم تغيير كلمة السر
-
- العقدة
- جار تحميل المحفظة …
- حفظت المحفظة
- فشل حفظ المحفظة!
- جار الاتصال …
- فشل الاتصال بالعقدة!\nتأكد من اسم المستخدم/كلمة المرور
- نسخة العقدة غير متوافقة - حدث رجاءً!
- العقدة غير صحيحة!\nجرب عقدة أخرى.
- لا يمكن الوصول للعقدة!\nحاول مجدداً أو جرب عقدة أخرى.
-
- منقطعة
-
- فشلت المعاملة: %1sd
-
- !انتظرت طويلاً يا صاحبي!
-
- …ما زلت مشغولاً بمحفظتك الأخيرة
-
- أعد التسمية %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$dل!
- لا أفهم العلامة!
- لا أعرف ماذا تريد!
- 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
- ]]>
-
- رجاء أدخل أو امسح عنوان مونيرو
- ]]>
-
- العناوين الفرعية
- اسم العنوان الفرعي
- عناوين غير مستعملة كثيرة - استعمل بعضها لتتمكن من إنشاء المزيد!
- حسابات غير مستعملة كثيرة - استعمل بعضها لتتمكن من إنشاء المزيد!
- المعاملات لهذا العنوان الفرعي:
- لا معاملات لهذا العنوان الفرعي بعد
- اختر عنواناً فرعياً
- المس طويلاً للتفاصيل
-
- استورد محفظة
- فشل الاستيراد
-
- أعد ضبط المحفظة!
- ستتم إعادة ضبط هذه المحفظة ، وفقدان جميع البيانات خارج السلسلة (مثل الملاحظات ، وأسماء الحسابات والعناوين الفرعية ، ومفاتيح المعاملات الخاصة ، ...)! استخدم هذا فقط إذا كانت هذه المحفظة تالفة و لا تحمل!
-
- This wallet will be deleted. Your funds will be gone forever unless you have your seed or a working backup to recover it.
- Yes, do that!
- No thanks!
-
- Resolving ENS / UD…
- No address found for ENS / UD domain
-
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 57c94038..159aa32b 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!
@@ -23,7 +23,7 @@
D\'acord
Cancel·lar
Tancar
- Premi aquí per informació més detallada
+ Informació més detallada
Enviat correctament!
Fet
@@ -236,7 +236,7 @@
Error creant la transacció
- - Comissió %1$s
+ Comissió %1$s
(%1$s)
fallit
- %1$s
@@ -425,8 +425,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 9edec409..7a2b1ce0 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -24,7 +24,7 @@
OK
Abbrechen
Schließen
- Berühren für Detailinfos
+ Detailinfos
Erfolgreich gesendet
Fertig
@@ -232,7 +232,7 @@
Fehler bei Transaktionserstellung
- - Gebühr %1$s
+ Gebühr %1$s
(%1$s)
fehlgeschlagen
- %1$s
@@ -426,8 +426,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 ff9a7ee9..4dd42a6f 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -22,7 +22,7 @@
OK
Άκυρο
Κλείσιμο
- Πάτησε για λεπτομερείς πληροφορίες
+ Λεπτομερείς πληροφορίες
Αποστολή με επιτυχία
Έγινε
@@ -205,7 +205,7 @@
Σφάλμα Δημιουργίας Συναλλαγής
- - Κόμιστρο %1$s
+ Κόμιστρο %1$s
(%1$s)
απέτυχε
- %1$s
@@ -427,8 +427,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 4b80d680..025e4ec4 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -23,7 +23,7 @@
OK
Nuligi
Fermi
- Tuŝi por pli detalaj informoj.
+ Detalaj informoj
Sukcese sendis
Farite
@@ -236,7 +236,7 @@
Krei transakci-eraron
- - Kosto %1$s
+ Kosto %1$s
(%1$s)
masukcesis
- %1$s
@@ -427,8 +427,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 2a1ef414..0caf83bc 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -23,7 +23,7 @@
Aceptar
Cancelar
Cerrar
- Toca para información más detallada
+ Información más detallada
¡Éxito!
Hecho
@@ -173,7 +173,7 @@
Error creando la transacción
- - Comisión %1$s
+ Comisión %1$s
(%1$s)
fallido
- %1$s
@@ -418,8 +418,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 9e949a0e..57a68469 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -23,7 +23,7 @@
OK
Katkesta
Sulge
- Puuduta lisainfo saamiseks
+ Lisainfo
Edukalt saadetud
Tehtud
@@ -231,7 +231,7 @@
Viga ülekande genereerimisel
- - teenustasu %1$s
+ teenustasu %1$s
(%1$s)
ebaõnnestus
- %1$s
@@ -425,8 +425,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 276d9bda..37a156ff 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -23,7 +23,7 @@
OK
Annuler
Fermer
- Toucher pour plus d\'infos
+ Plus d\'infos
Envoi réussi
Fait
@@ -233,7 +233,7 @@
Erreur de Création de Transaction
- - Frais %1$s
+ Frais %1$s
(%1$s)
Echoué
- %1$s
@@ -431,8 +431,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 3650d54d..9797ace3 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -23,7 +23,7 @@
OK
Mégsem
Bezárás
- Koppints a részletes informcáióért
+ Részletes információk
Sikeresen elküldve
Kész
@@ -230,7 +230,7 @@
Tranzakciólétrehozási hiba
- - %1$s díj
+ %1$s díj
(%1$s)
sikertelen
- %1$s
@@ -429,8 +429,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
diff --git a/app/src/main/res/values-it/help.xml b/app/src/main/res/values-it/help.xml
index 659114e6..84e772f4 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,15 +284,36 @@
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!
+
+ 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 f2d48a0e..20ceb0fb 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -23,7 +23,7 @@
OK
Cancella
Chiudi
- Tocca per informazioni dettagliate
+ Informazioni dettagliate
Invio riuscito
Fatto
@@ -232,7 +232,7 @@
Errore nella creazione della transazione
- - Commissione %1$s
+ Commissione %1$s
(%1$s)
fallita
- %1$s
@@ -362,76 +362,89 @@
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!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ Resetta portafogli!
+
+
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 c3ad054a..ce6aa3e2 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -23,7 +23,6 @@
OK
キャンセル
閉じる
- タッチして詳細情報を見る
送金成功
完了
@@ -236,7 +235,7 @@
取引作成エラー
- - 手数料 %1$s
+ 手数料 %1$s
(%1$s)
失敗
- %1$s
@@ -430,8 +429,21 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ タッチして詳細情報を見る
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 20aa0552..8ed5c3b7 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -23,7 +23,7 @@
OK
Avbryt
Lukk
- Trykk for detaljert informasjon
+ Detaljert informasjon
Sendt suksessfullt!
Ferdig
@@ -230,7 +230,7 @@
Error med å lage transaksjon
- - Avgift %1$s
+ Avgift %1$s
(%1$s)
feila
- %1$s
@@ -427,8 +427,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 033c82a1..d88b790f 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -23,7 +23,7 @@
OK
Annuleren
Sluiten
- Tik voor meer informatie
+ Meer informatie
Verzonden
Klaar
@@ -227,7 +227,7 @@
Fout bij transactie maken
- - kosten %1$s
+ kosten %1$s
(%1$s)
mislukt
- %1$s
@@ -427,8 +427,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 9e8bb605..dcf45673 100755
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -23,7 +23,7 @@
OK
Cancelar
Fechar
- Toque para mais detalhes
+ Mais detalhes
Enviado com sucesso
Concluído
@@ -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
@@ -229,7 +229,7 @@
Erro ao criar a transação
- - taxa de %1$s
+ taxa de %1$s
(%1$s)
falhou
- %1$s
@@ -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,16 +412,29 @@
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!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ Resetar carteira!
+
+
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 93c79597..d426332d 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -23,7 +23,7 @@
OK
Cancelar
Fechar
- Toca para informação detalhada
+ Informação detalhada
Enviado com sucesso
Feito
@@ -229,7 +229,7 @@
Erro ao criar a transacção
- - Taxa %1$s
+ Taxa %1$s
(%1$s)
falhou
- %1$s
@@ -431,8 +431,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 8d98a3c6..57576bf6 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -22,7 +22,7 @@
OK
Anulează
Închide
- Atinge pentru informații detaliate
+ Informații detaliate
Trimis cu succes
Gata
@@ -205,7 +205,7 @@
Eroare creare tranzacție
- - Comision %1$s
+ Comision %1$s
(%1$s)
eșuat
- %1$s
@@ -427,8 +427,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
diff --git a/app/src/main/res/values-ru/help.xml b/app/src/main/res/values-ru/help.xml
index 26df4809..28fb0b0c 100644
--- a/app/src/main/res/values-ru/help.xml
+++ b/app/src/main/res/values-ru/help.xml
@@ -297,4 +297,23 @@
]]>
Я понял!
+
+ Не…
+ Скачать Orbot!
+ Tor
+ Tor, сокр. от The Onion Router, бесплатное и программное обеспечение с открытым исходным кодом для обеспечения анонимного общения.
+ Включение Tor перенаправит подключение к нескольким узлам и скроет IP-адрес от узла.
+ Имейте в виду, что это более приватно, но и медленнее.
+ Для того, чтобы использовать Tor с Monerujo, вам понадобится Orbot на вашем телефоне. После установки Orbot убедитесь,
+ что вы включили его, нажав значок сети на экране списка кошельков.
+ Если у вас есть проблемы с подключением к Tor, попробуйте получить новую идентичность в приложении Orbot (значок
+ в правом верхнем углу).
+ ]]>
+
+ Tor узел
+ Это .onion узел. Для того, чтобы использовать его, вы должны включить Tor, нажав
+ значок в верхней части страницы списка кошельков.
+ ]]>
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index c8c15a4a..b85f9a2c 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -23,7 +23,7 @@
Ок
Отмена
Закрыть
- Нажмите для доп. информации
+ Дополнительная информация
Успешно отправлено
Готово
@@ -231,7 +231,7 @@
Ошибка создания транзакции
- - Комиссия %1$s
+ Комиссия %1$s
(%1$s)
Не удалось
- %1$s
@@ -431,8 +431,20 @@
Ошибка импорта!
Сбросить кошелек
+<<<<<<< HEAD
Этот кошелек будет сброшен, вы потеряете все данные, которые не находятся в блокчейне (например примечания, имена подадресов, приватные ключи транзакций, ...)! Используйте это ТОЛЬКО если ваш кошелек поврежден и не загружается!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ Этот кошелек будет сброшен, потеряв всю локальную информацию (например: заметки, имена адресов, приватные ключи транзакций, …)! Используйте это ТОЛЬКО если кошелек поврежден и не загружается!
+
+ Необходим Tor
+ \u00A0ОЖИДАНИЕ УЗЛА\u00A0
+ Необходимо выбрать "Allow Background Starts" в настройках Orbot для использования Tor!
+ SideShift.ai не поддерживает Tor.\nОтключите Tor для обмена XMR.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 c2eb298e..50b57460 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -23,7 +23,7 @@
OK
Zrušiť
Zatvoriť
- Klepni pre viac info
+ Viac info
úspešne odoslané
Hotovo
@@ -228,7 +228,7 @@
Vytvor Chybu Transakcie
- - poplatok %1$s
+ poplatok %1$s
(%1$s)
zlyhala
- %1$s
@@ -428,8 +428,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 e2c09d5b..45846d40 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -23,7 +23,7 @@
OK
Otkaži
Zatvori
- Takni za detaljne informacije
+ Detaljne informacije
Uspešno poslato
Gotovo
@@ -237,7 +237,7 @@
Kreiraj transakcijsku grešku
- - naknada %1$s
+ naknada %1$s
(%1$s)
neuspelo
- %1$s
@@ -426,8 +426,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 e444d8d1..6476231e 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -23,7 +23,7 @@
OK
Avbryt
Stäng
- Tryck för detaljerad information
+ Detaljerad information
Har skickats
Färdig
@@ -218,7 +218,7 @@
Ett fel uppstod när transaktion skapades
- - Avgift %1$s
+ Avgift %1$s
(%1$s)
misslyckades
- %1$s
@@ -419,8 +419,20 @@
Importeringen misslyckad!
Återställ plånbok!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 5cb730af..46c52b80 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -23,7 +23,7 @@
Ok
Відміна
Закрити
- Натисніть для дод. інформації
+ Додатковій інформації
Успішно відправлено
Готово
@@ -231,7 +231,7 @@
Помилка створення транзакції
- - Комісія %1$s
+ Комісія %1$s
(%1$s)
Не вдалося
- %1$s
@@ -431,8 +431,20 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 3d437b2e..32d9fe3d 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -19,7 +19,6 @@
确认
取消
关闭
- 点击以查看详情
发送成功
完成
点此获取QR码
@@ -182,7 +181,7 @@
%1$s XMR
+%1$s 手续费
创建交易发生错误
- - 手续费 %1$s
+ 手续费 %1$s
(%1$s)
失败
- %1$s
@@ -351,8 +350,21 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ 点击以查看详情
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
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 baa04ff2..e1da7e07 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -23,7 +23,6 @@
好的
取消
關閉
- 點選以獲得詳細資訊
已成功發送
完成
@@ -229,7 +228,7 @@
建立交易錯誤
- - 手續費 %1$s
+ 手續費 %1$s
(%1$s)
失敗
- %1$s
@@ -426,8 +425,21 @@
Import failed!
Reset wallet!
+<<<<<<< HEAD
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!
Resolving ENS / UD…
No address found for ENS / UD domain
+=======
+ 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.
+
+ 點選以獲得詳細資訊
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
+>>>>>>> 7b96baeca7f216c943ad5d376e6838f9679e74b0
diff --git a/app/src/main/res/values/help.xml b/app/src/main/res/values/help.xml
index c0a67ff3..569e6799 100644
--- a/app/src/main/res/values/help.xml
+++ b/app/src/main/res/values/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/strings.xml b/app/src/main/res/values/strings.xml
index d5c47255..8f0e0daf 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -25,7 +25,7 @@
OK
Cancel
Close
- Touch for detailed information
+ Detailed information
Successfully sent
Done
@@ -100,7 +100,7 @@
Change Password failed!
Password changed
- Node
+ Network
Stagenet
Testnet
Loading Wallet …
@@ -245,7 +245,7 @@
Create Transaction Error
- - Fee %1$s
+ Fee %1$s
(%1$s)
failed
- %1$s
@@ -501,5 +501,15 @@
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.
+
+ Seed encryption (EXPERIMENTAL)
+ Seed Offset Phrase (optional)
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 @@