1
mirror of https://github.com/m2049r/xmrwallet synced 2024-11-22 13:04:00 +01:00

onion stuff (#796)

This commit is contained in:
m2049r 2021-12-05 22:24:26 +01:00 committed by GitHub
parent cdc2b23257
commit 05720e63ab
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
94 changed files with 2210 additions and 860 deletions

View File

@ -8,8 +8,8 @@ android {
applicationId "com.m2049r.xmrwallet" applicationId "com.m2049r.xmrwallet"
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 30 targetSdkVersion 30
versionCode 1102 versionCode 1201
versionName "2.1.2 'Vertant'" versionName "2.2.1 'René'"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild { externalNativeBuild {
cmake { cmake {
@ -113,27 +113,30 @@ android {
} }
} }
def getId(name) { static def getId(name) {
def Properties props = new Properties() Properties props = new Properties()
props.load(new FileInputStream(new File('monerujo.id'))) props.load(new FileInputStream(new File('monerujo.id')))
return props[name] return props[name]
} }
dependencies { dependencies {
implementation 'androidx.core:core:1.3.2' implementation 'androidx.core:core:1.6.0'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.3.0' implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.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.cardview:cardview:1.0.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0-alpha01' 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 'me.dm7.barcodescanner:zxing:1.9.8'
implementation "com.squareup.okhttp3:okhttp:4.9.0" implementation "com.squareup.okhttp3:okhttp:4.9.0"
implementation "io.github.rburgst:okhttp-digest:2.5" implementation "io.github.rburgst:okhttp-digest:2.5"
implementation "com.jakewharton.timber:timber:4.7.1" 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 'com.nulab-inc:zxcvbn:1.3.0'
implementation 'dnsjava:dnsjava:2.1.9' implementation 'dnsjava:dnsjava:2.1.9'
@ -141,6 +144,7 @@ dependencies {
implementation 'org.slf4j:slf4j-nop:1.7.30' implementation 'org.slf4j:slf4j-nop:1.7.30'
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2' implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
//noinspection GradleDependency
testImplementation "junit:junit:$rootProject.ext.junitVersion" testImplementation "junit:junit:$rootProject.ext.junitVersion"
testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion" testImplementation "org.mockito:mockito-all:$rootProject.ext.mockitoVersion"
testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0" testImplementation "com.squareup.okhttp3:mockwebserver:4.9.0"
@ -150,3 +154,4 @@ dependencies {
compileOnly 'org.projectlombok:lombok:1.18.16' compileOnly 'org.projectlombok:lombok:1.18.16'
annotationProcessor 'org.projectlombok:lombok:1.18.16' annotationProcessor 'org.projectlombok:lombok:1.18.16'
} }

View File

@ -11,6 +11,24 @@
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<queries>
<intent>
<action android:name="org.torproject.android.intent.action.START" />
</intent>
<intent>
<action android:name="org.torproject.android.intent.action.STATUS" />
</intent>
<intent>
<action android:name="org.torproject.android.REQUEST_HS_PORT" />
</intent>
<intent>
<action android:name="org.torproject.android.REQUEST_V3_ONION_SERVICE" />
</intent>
<package android:name="org.torproject.android" />
</queries>
<application <application
android:name=".XmrWalletApplication" android:name=".XmrWalletApplication"
android:allowBackup="false" android:allowBackup="false"

View File

@ -531,6 +531,17 @@ Java_com_m2049r_xmrwallet_model_WalletManager_resolveOpenAlias(JNIEnv *env, jobj
return env->NewStringUTF(resolvedAlias.c_str()); 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<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir); //TODO static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir);
JNIEXPORT jboolean JNICALL JNIEXPORT jboolean JNICALL
@ -727,6 +738,16 @@ Java_com_m2049r_xmrwallet_model_Wallet_getConnectionStatusJ(JNIEnv *env, jobject
//TODO virtual void setTrustedDaemon(bool arg) = 0; //TODO virtual void setTrustedDaemon(bool arg) = 0;
//TODO virtual bool trustedDaemon() const = 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<Bitmonero::Wallet>(env, instance);
bool rc = wallet->setProxy(std::string(_address));
env->ReleaseStringUTFChars(address, _address);
return rc;
}
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
Java_com_m2049r_xmrwallet_model_Wallet_getBalance(JNIEnv *env, jobject instance, Java_com_m2049r_xmrwallet_model_Wallet_getBalance(JNIEnv *env, jobject instance,
jint accountIndex) { jint accountIndex) {

View File

@ -77,7 +77,7 @@ public class Dispatcher implements PeerRetriever.OnGetPeers {
final NodeInfo nodeInfo = retrievedPeer.getNodeInfo(); final NodeInfo nodeInfo = retrievedPeer.getNodeInfo();
Timber.d("Retrieved %s", nodeInfo); Timber.d("Retrieved %s", nodeInfo);
if ((nodeInfo.isValid() || nodeInfo.isFavourite())) { if ((nodeInfo.isValid() || nodeInfo.isFavourite())) {
nodeInfo.setName(); nodeInfo.setDefaultName();
rpcNodes.add(nodeInfo); rpcNodes.add(nodeInfo);
Timber.d("RPC: %s", nodeInfo); Timber.d("RPC: %s", nodeInfo);
// the following is not totally correct but it works (otherwise we need to // the following is not totally correct but it works (otherwise we need to

View File

@ -65,6 +65,7 @@ import com.m2049r.xmrwallet.util.KeyStoreHelper;
import com.m2049r.xmrwallet.util.LegacyStorageHelper; import com.m2049r.xmrwallet.util.LegacyStorageHelper;
import com.m2049r.xmrwallet.util.LocaleHelper; import com.m2049r.xmrwallet.util.LocaleHelper;
import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor; import com.m2049r.xmrwallet.util.MoneroThreadPoolExecutor;
import com.m2049r.xmrwallet.util.NetCipherHelper;
import com.m2049r.xmrwallet.util.NightmodeHelper; import com.m2049r.xmrwallet.util.NightmodeHelper;
import com.m2049r.xmrwallet.util.ThemeHelper; import com.m2049r.xmrwallet.util.ThemeHelper;
import com.m2049r.xmrwallet.util.ZipBackup; import com.m2049r.xmrwallet.util.ZipBackup;
@ -701,6 +702,7 @@ public class LoginActivity extends BaseActivity
new AsyncWaitForService().execute(); new AsyncWaitForService().execute();
} }
if (!Ledger.isConnected()) attachLedger(); if (!Ledger.isConnected()) attachLedger();
registerTor();
} }
private class AsyncWaitForService extends AsyncTask<Void, Void, Void> { private class AsyncWaitForService extends AsyncTask<Void, Void, Void> {
@ -1469,4 +1471,69 @@ public class LoginActivity extends BaseActivity
} }
return usbManager; 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;
}
}
} }

View File

@ -19,6 +19,8 @@ package com.m2049r.xmrwallet;
import android.content.Context; import android.content.Context;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -28,22 +30,27 @@ import android.view.ViewGroup;
import android.view.animation.Animation; import android.view.animation.Animation;
import android.view.animation.AnimationUtils; import android.view.animation.AnimationUtils;
import android.widget.FrameLayout; import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.progressindicator.CircularProgressIndicator;
import com.m2049r.xmrwallet.data.NodeInfo; 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.layout.WalletInfoAdapter;
import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.KeyStoreHelper; import com.m2049r.xmrwallet.util.KeyStoreHelper;
import com.m2049r.xmrwallet.util.NetCipherHelper;
import com.m2049r.xmrwallet.util.NodePinger; import com.m2049r.xmrwallet.util.NodePinger;
import com.m2049r.xmrwallet.util.Notice; import com.m2049r.xmrwallet.util.Notice;
import com.m2049r.xmrwallet.widget.Toolbar; import com.m2049r.xmrwallet.widget.Toolbar;
@ -66,9 +73,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
private View tvGuntherSays; private View tvGuntherSays;
private ImageView ivGunther; private ImageView ivGunther;
private TextView tvNodeName; private TextView tvNodeName;
private TextView tvNodeAddress; private TextView tvNodeInfo;
private View pbNode; private ImageButton ibNetwork;
private View llNode; private CircularProgressIndicator pbNetwork;
private Listener activityCallback; private Listener activityCallback;
@ -109,6 +116,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
Set<NodeInfo> getOrPopulateFavourites(); Set<NodeInfo> getOrPopulateFavourites();
boolean hasLedger(); boolean hasLedger();
void runOnNetCipher(Runnable runnable);
} }
@Override @Override
@ -125,6 +134,7 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
@Override @Override
public void onPause() { public void onPause() {
Timber.d("onPause()"); Timber.d("onPause()");
torStatus = null;
super.onPause(); super.onPause();
} }
@ -135,7 +145,8 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
activityCallback.setTitle(null); activityCallback.setTitle(null);
activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS); activityCallback.setToolbarButton(Toolbar.BUTTON_CREDITS);
activityCallback.showNet(); activityCallback.showNet();
pingSelectedNode(); showNetwork();
//activityCallback.runOnNetCipher(this::pingSelectedNode);
} }
@Override @Override
@ -183,12 +194,14 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
ViewGroup llNotice = view.findViewById(R.id.llNotice); ViewGroup llNotice = view.findViewById(R.id.llNotice);
Notice.showAll(llNotice, ".*_login"); Notice.showAll(llNotice, ".*_login");
pbNode = view.findViewById(R.id.pbNode); view.findViewById(R.id.llNode).setOnClickListener(v -> startNodePrefs());
llNode = view.findViewById(R.id.llNode);
llNode.setOnClickListener(v -> startNodePrefs());
tvNodeName = view.findViewById(R.id.tvNodeName); 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()); 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()); Helper.hideKeyboard(getActivity());
@ -387,15 +400,29 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
return nodeList.get(0); 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<Integer, Void, NodeInfo> { private class AsyncFindBestNode extends AsyncTask<Integer, Void, NodeInfo> {
final static int PING_SELECTED = 0; final static int PING_SELECTED = 0;
final static int FIND_BEST = 1; final static int FIND_BEST = 1;
private boolean netState;
@Override @Override
protected void onPreExecute() { protected void onPreExecute() {
super.onPreExecute(); super.onPreExecute();
pbNode.setVisibility(View.VISIBLE); tvNodeName.setVisibility(View.GONE);
llNode.setVisibility(View.INVISIBLE); pbNetwork.setVisibility(View.VISIBLE);
netState = ibNetwork.isClickable();
ibNetwork.setClickable(false);
setSubtext(getString(R.string.node_waiting));
} }
@Override @Override
@ -417,8 +444,9 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
} }
if (selectedNode == null) { // autoselect if (selectedNode == null) { // autoselect
selectedNode = autoselect(favourites); selectedNode = autoselect(favourites);
} else } else {
selectedNode.testRpcService(); selectedNode.testRpcService();
}
} else throw new IllegalStateException(); } else throw new IllegalStateException();
if ((selectedNode != null) && selectedNode.isValid()) { if ((selectedNode != null) && selectedNode.isValid()) {
activityCallback.setNode(selectedNode); activityCallback.setNode(selectedNode);
@ -432,16 +460,17 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
@Override @Override
protected void onPostExecute(NodeInfo result) { protected void onPostExecute(NodeInfo result) {
if (!isAdded()) return; if (!isAdded()) return;
pbNode.setVisibility(View.INVISIBLE); tvNodeName.setVisibility(View.VISIBLE);
llNode.setVisibility(View.VISIBLE); pbNetwork.setVisibility(View.INVISIBLE);
ibNetwork.setClickable(netState);
if (result != null) { if (result != null) {
Timber.d("found a good node %s", result.toString()); Timber.d("found a good node %s", result.toString());
showNode(result); showNode(result);
} else { } else {
tvNodeName.setText(getResources().getText(R.string.node_create_hint)); tvNodeName.setText(getResources().getText(R.string.node_create_hint));
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0); tvNodeName.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
tvNodeAddress.setText(null); tvNodeInfo.setText(null);
tvNodeAddress.setVisibility(View.GONE); tvNodeInfo.setVisibility(View.GONE);
} }
} }
@ -453,12 +482,70 @@ public class LoginFragment extends Fragment implements WalletInfoAdapter.OnInter
private void showNode(NodeInfo nodeInfo) { private void showNode(NodeInfo nodeInfo) {
tvNodeName.setText(nodeInfo.getName()); tvNodeName.setText(nodeInfo.getName());
tvNodeName.setCompoundDrawablesWithIntrinsicBounds(NodeInfoAdapter.getPingIcon(nodeInfo), 0, 0, 0); nodeInfo.showInfo(tvNodeInfo);
Helper.showTimeDifference(tvNodeAddress, nodeInfo.getTimestamp()); tvNodeInfo.setVisibility(View.VISIBLE);
tvNodeAddress.setVisibility(View.VISIBLE);
} }
private void startNodePrefs() { private void startNodePrefs() {
activityCallback.onNodePrefs(); 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);
}
} }

View File

@ -20,7 +20,6 @@ import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.os.AsyncTask; import android.os.AsyncTask;
import android.os.Bundle; import android.os.Bundle;
import android.view.KeyEvent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuInflater; import android.view.MenuInflater;
@ -59,7 +58,6 @@ import java.text.NumberFormat;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import timber.log.Timber; 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 activityCallback.setNode(nodeItem); // this marks it as selected & saves it as well
nodeItem.setSelecting(false); nodeItem.setSelecting(false);
try { try {
Objects.requireNonNull(getActivity()).runOnUiThread(() -> nodesAdapter.allowClick(true)); requireActivity().runOnUiThread(() -> nodesAdapter.allowClick(true));
} catch (NullPointerException ex) { } catch (IllegalStateException ex) {
// it's ok // it's ok
} }
}); });
@ -403,16 +401,12 @@ public class NodeFragment extends Fragment
etNodeHost.setError(getString(R.string.node_host_empty)); etNodeHost.setError(getString(R.string.node_host_empty));
return false; return false;
} }
final boolean setHostSuccess = Helper.runWithNetwork(new Helper.Action() { final boolean setHostSuccess = Helper.runWithNetwork(() -> {
@Override try {
public boolean run() { nodeInfo.setHost(host);
try { return true;
nodeInfo.setHost(host); } catch (UnknownHostException ex) {
return true; return false;
} catch (UnknownHostException ex) {
etNodeHost.setError(getString(R.string.node_host_unresolved));
return false;
}
} }
}); });
if (!setHostSuccess) { if (!setHostSuccess) {
@ -421,14 +415,7 @@ public class NodeFragment extends Fragment
} }
etNodeHost.setError(null); etNodeHost.setError(null);
nodeInfo.setRpcPort(port); nodeInfo.setRpcPort(port);
// setName() may trigger reverse DNS nodeInfo.setName(etNodeName.getEditText().getText().toString().trim());
Helper.runWithNetwork(new Helper.Action() {
@Override
public boolean run() {
nodeInfo.setName(etNodeName.getEditText().getText().toString().trim());
return true;
}
});
nodeInfo.setUsername(etNodeUser.getEditText().getText().toString().trim()); nodeInfo.setUsername(etNodeUser.getEditText().getText().toString().trim());
nodeInfo.setPassword(etNodePass.getEditText().getText().toString()); // no trim for pw nodeInfo.setPassword(etNodePass.getEditText().getText().toString()); // no trim for pw
return true; return true;
@ -532,20 +519,10 @@ public class NodeFragment extends Fragment
@Override @Override
public void onShow(final DialogInterface dialog) { public void onShow(final DialogInterface dialog) {
Button testButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEUTRAL); Button testButton = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_NEUTRAL);
testButton.setOnClickListener(new View.OnClickListener() { testButton.setOnClickListener(view -> test());
@Override
public void onClick(View view) {
test();
}
});
Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE); Button button = ((AlertDialog) dialog).getButton(AlertDialog.BUTTON_POSITIVE);
button.setOnClickListener(new View.OnClickListener() { button.setOnClickListener(view -> apply());
@Override
public void onClick(View view) {
apply();
}
});
} }
}); });
@ -553,15 +530,13 @@ public class NodeFragment extends Fragment
editDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); editDialog.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE);
} }
etNodePass.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { etNodePass.getEditText().setOnEditorActionListener((v, actionId, event) -> {
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { if (actionId == EditorInfo.IME_ACTION_DONE) {
if (actionId == EditorInfo.IME_ACTION_DONE) { editDialog.getButton(DialogInterface.BUTTON_NEUTRAL).requestFocus();
editDialog.getButton(DialogInterface.BUTTON_NEUTRAL).requestFocus(); test();
test(); return true;
return true;
}
return false;
} }
return false;
}); });
} }
@ -589,6 +564,7 @@ public class NodeFragment extends Fragment
} else { } else {
nodesAdapter.setNodes(); nodesAdapter.setNodes();
} }
nodesAdapter.notifyItemChanged(nodeInfo);
} }
} }
} }

View File

@ -223,11 +223,13 @@ public class WalletFragment extends Fragment
} }
void showUnconfirmed(double unconfirmedAmount) { 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); String unconfirmed = Helper.getFormattedAmount(unconfirmedAmount, true);
tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed)); tvUnconfirmedAmount.setText(getResources().getString(R.string.xmr_unconfirmed_amount, unconfirmed));
} else { tvUnconfirmedAmount.setVisibility(View.VISIBLE);
tvUnconfirmedAmount.setText(null);
} }
} }

View File

@ -21,14 +21,17 @@ import android.content.Context;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.os.Build; import android.os.Build;
import com.m2049r.xmrwallet.BuildConfig; import androidx.annotation.NonNull;
import com.m2049r.xmrwallet.model.NetworkType; import com.m2049r.xmrwallet.model.NetworkType;
import com.m2049r.xmrwallet.util.LocaleHelper; import com.m2049r.xmrwallet.util.LocaleHelper;
import com.m2049r.xmrwallet.util.NetCipherHelper;
import com.m2049r.xmrwallet.util.NightmodeHelper; import com.m2049r.xmrwallet.util.NightmodeHelper;
import timber.log.Timber; import timber.log.Timber;
public class XmrWalletApplication extends Application { public class XmrWalletApplication extends Application {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -36,7 +39,10 @@ public class XmrWalletApplication extends Application {
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
Timber.plant(new Timber.DebugTree()); Timber.plant(new Timber.DebugTree());
} }
NightmodeHelper.setPreferredNightmode(this); NightmodeHelper.setPreferredNightmode(this);
NetCipherHelper.createInstance(this);
} }
@Override @Override
@ -45,7 +51,7 @@ public class XmrWalletApplication extends Application {
} }
@Override @Override
public void onConfigurationChanged(Configuration configuration) { public void onConfigurationChanged(@NonNull Configuration configuration) {
super.onConfigurationChanged(configuration); super.onConfigurationChanged(configuration);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
LocaleHelper.updateSystemDefaultLocale(configuration.getLocales().get(0)); LocaleHelper.updateSystemDefaultLocale(configuration.getLocales().get(0));

View File

@ -28,7 +28,11 @@ public enum DefaultNodes {
SUPPORTXMR("node.supportxmr.com:18081"), SUPPORTXMR("node.supportxmr.com:18081"),
HASHVAULT("nodes.hashvault.pro:18081"), HASHVAULT("nodes.hashvault.pro:18081"),
MONEROWORLD("node.moneroworld.com:18089"), 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 @Getter
private final String uri; private final String uri;

View File

@ -18,6 +18,7 @@ package com.m2049r.xmrwallet.data;
import com.m2049r.xmrwallet.model.NetworkType; import com.m2049r.xmrwallet.model.NetworkType;
import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.OnionHelper;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.InetAddress; import java.net.InetAddress;
@ -35,11 +36,63 @@ public class Node {
static public final String STAGENET = "stagenet"; static public final String STAGENET = "stagenet";
static public final String TESTNET = "testnet"; 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 @Getter
private String name = null; private String name = null;
@Getter @Getter
final private NetworkType networkType; final private NetworkType networkType;
InetAddress hostAddress; Address hostAddress;
@Getter @Getter
private String host; private String host;
@Getter @Getter
@ -74,6 +127,10 @@ public class Node {
&& (networkType == anotherNode.networkType)); && (networkType == anotherNode.networkType));
} }
public boolean isOnion() {
return hostAddress.isOnion();
}
static public Node fromString(String nodeString) { static public Node fromString(String nodeString) {
try { try {
return new Node(nodeString); return new Node(nodeString);
@ -205,7 +262,7 @@ public class Node {
// constructor used for created nodes from retrieved peer lists // constructor used for created nodes from retrieved peer lists
public Node(InetSocketAddress socketAddress) { public Node(InetSocketAddress socketAddress) {
this(); this();
this.hostAddress = socketAddress.getAddress(); this.hostAddress = Address.of(socketAddress.getAddress());
this.host = socketAddress.getHostString(); this.host = socketAddress.getHostString();
this.rpcPort = 0; // unknown this.rpcPort = 0; // unknown
this.levinPort = socketAddress.getPort(); this.levinPort = socketAddress.getPort();
@ -225,17 +282,25 @@ public class Node {
if ((host == null) || (host.isEmpty())) if ((host == null) || (host.isEmpty()))
throw new UnknownHostException("loopback not supported (yet?)"); throw new UnknownHostException("loopback not supported (yet?)");
this.host = host; this.host = host;
this.hostAddress = InetAddress.getByName(host); this.hostAddress = Address.of(host);
} }
public void setName() { public void setDefaultName() {
if (name == null) if (name != null) return;
this.name = hostAddress.getHostName(); 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) { public void setName(String name) {
if ((name == null) || (name.isEmpty())) if ((name == null) || (name.isEmpty()))
this.name = hostAddress.getHostName(); setDefaultName();
else else
this.name = name; this.name = name;
} }

View File

@ -16,14 +16,19 @@
package com.m2049r.xmrwallet.data; package com.m2049r.xmrwallet.data;
import com.burgstaller.okhttp.AuthenticationCacheInterceptor; import android.content.Context;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator; import android.text.Html;
import com.burgstaller.okhttp.digest.CachingAuthenticator; import android.text.Spanned;
import com.burgstaller.okhttp.digest.Credentials; import android.widget.TextView;
import com.burgstaller.okhttp.digest.DigestAuthenticator;
import androidx.core.content.ContextCompat;
import com.m2049r.levin.scanner.LevinPeer; 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.NodePinger;
import com.m2049r.xmrwallet.util.OkHttpHelper; import com.m2049r.xmrwallet.util.ThemeHelper;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -32,17 +37,12 @@ import java.io.IOException;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.SocketAddress; import java.net.SocketAddress;
import java.util.Calendar;
import java.util.Comparator; import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import okhttp3.ResponseBody; import okhttp3.ResponseBody;
import timber.log.Timber; import timber.log.Timber;
@ -94,7 +94,7 @@ public class NodeInfo extends Node {
synchronized public SocketAddress getLevinSocketAddress() { synchronized public SocketAddress getLevinSocketAddress() {
if (levinSocketAddress == null) { if (levinSocketAddress == null) {
// use default peer port if not set - very few peers use nonstandard port // 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; return levinSocketAddress;
} }
@ -180,7 +180,7 @@ public class NodeInfo extends Node {
return sb.toString(); 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_GOOD = HTTP_TIMEOUT / 3.0; //ms
public static final double PING_MEDIUM = 2 * PING_GOOD; //ms public static final double PING_MEDIUM = 2 * PING_GOOD; //ms
public static final double PING_BAD = HTTP_TIMEOUT; public static final double PING_BAD = HTTP_TIMEOUT;
@ -196,32 +196,29 @@ public class NodeInfo extends Node {
return result; 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) { private boolean testRpcService(int port) {
Timber.d("Testing %s", toNodeString()); Timber.d("Testing %s", toNodeString());
clear(); 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 { try {
OkHttpClient client = OkHttpHelper.getEagerClient();
if (!getUsername().isEmpty()) {
final DigestAuthenticator authenticator =
new DigestAuthenticator(new Credentials(getUsername(), getPassword()));
final Map<String, CachingAuthenticator> 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(); 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; responseTime = (System.nanoTime() - ta) / 1000000.0;
responseCode = response.code(); responseCode = response.code();
if (response.isSuccessful()) { if (response.isSuccessful()) {
@ -243,7 +240,7 @@ public class NodeInfo extends Node {
} }
} }
} catch (IOException | JSONException ex) { } catch (IOException | JSONException ex) {
Timber.d(ex); Timber.d("EX: %s", ex.getMessage()); //TODO: do something here (show error?)
} finally { } finally {
tested = true; tested = true;
} }
@ -264,4 +261,43 @@ public class NodeInfo extends Node {
} }
return false; 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() ? "&nbsp;.onion&nbsp;&nbsp;" : ""), " " + 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);
}
} }

View File

@ -17,13 +17,17 @@
package com.m2049r.xmrwallet.dialog; package com.m2049r.xmrwallet.dialog;
import android.app.Dialog; import android.app.Dialog;
import android.content.DialogInterface; import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.text.Html; import android.text.Html;
import android.text.Spanned;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.DialogFragment; import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.Fragment; import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager;
@ -31,15 +35,20 @@ import androidx.fragment.app.FragmentTransaction;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.util.NetCipherHelper;
public class HelpFragment extends DialogFragment { public class HelpFragment extends DialogFragment {
static final String TAG = "HelpFragment"; static final String TAG = "HelpFragment";
private static final String HELP_ID = "HELP_ID"; private static final String HELP_ID = "HELP_ID";
private static final String TOR_BUTTON = "TOR";
public static HelpFragment newInstance(int helpResourceId) { public static HelpFragment newInstance(int helpResourceId) {
HelpFragment fragment = new HelpFragment(); HelpFragment fragment = new HelpFragment();
Bundle bundle = new Bundle(); Bundle bundle = new Bundle();
bundle.putInt(HELP_ID, helpResourceId); 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); fragment.setArguments(bundle);
return fragment; return fragment;
} }
@ -54,27 +63,53 @@ public class HelpFragment extends DialogFragment {
HelpFragment.newInstance(helpResourceId).show(ft, TAG); 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 @Override
public Dialog onCreateDialog(Bundle savedInstanceState) { public Dialog onCreateDialog(Bundle savedInstanceState) {
final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_help, null); final View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_help, null);
int helpId = 0; int helpId = 0;
boolean torButton = false;
Bundle arguments = getArguments(); Bundle arguments = getArguments();
if (arguments != null) { if (arguments != null) {
helpId = arguments.getInt(HELP_ID); helpId = arguments.getInt(HELP_ID);
torButton = arguments.getInt(TOR_BUTTON) > 0;
} }
final TextView helpTv = view.findViewById(R.id.tvHelp);
if (helpId > 0) 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()) MaterialAlertDialogBuilder builder =
.setView(view) new MaterialAlertDialogBuilder(requireActivity())
.setNegativeButton(R.string.help_ok, .setView(view);
new DialogInterface.OnClickListener() { if (torButton) {
@Override builder.setNegativeButton(R.string.help_nok,
public void onClick(DialogInterface dialog, int id) { (dialog, id) -> dialog.dismiss())
.setPositiveButton(R.string.help_getorbot,
(dialog, id) -> {
dialog.dismiss(); dialog.dismiss();
} NetCipherHelper.getInstance().installOrbot(requireActivity());
}); });
} else {
builder.setNegativeButton(R.string.help_ok,
(dialog, id) -> dialog.dismiss());
}
return builder.create(); return builder.create();
} }
} }

View File

@ -22,6 +22,7 @@ import android.os.Bundle;
import android.text.Editable; import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.InputType; import android.text.InputType;
import android.text.Spanned;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Patterns; import android.util.Patterns;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -91,6 +92,7 @@ public class SendAddressWizardFragment extends SendWizardFragment {
private TextInputLayout etAddress; private TextInputLayout etAddress;
private TextInputLayout etNotes; private TextInputLayout etNotes;
private TextView tvXmrTo; private TextView tvXmrTo;
private TextView tvTor;
private Map<Crypto, ImageButton> ibCrypto; private Map<Crypto, ImageButton> ibCrypto;
final private Set<Crypto> possibleCryptos = new HashSet<>(); final private Set<Crypto> possibleCryptos = new HashSet<>();
private Crypto selectedCrypto = null; private Crypto selectedCrypto = null;
@ -117,11 +119,12 @@ public class SendAddressWizardFragment extends SendWizardFragment {
View view = inflater.inflate(R.layout.fragment_send_address, container, false); View view = inflater.inflate(R.layout.fragment_send_address, container, false);
if (Helper.ALLOW_SHIFT) { tvTor = view.findViewById(R.id.tvTor);
tvXmrTo = view.findViewById(R.id.tvXmrTo); tvXmrTo = view.findViewById(R.id.tvXmrTo);
ibCrypto = new HashMap<>(); ibCrypto = new HashMap<>();
for (Crypto crypto : Crypto.values()) { for (Crypto crypto : Crypto.values()) {
final ImageButton button = view.findViewById(crypto.getButtonId()); final ImageButton button = view.findViewById(crypto.getButtonId());
if (Helper.ALLOW_SHIFT || (crypto == Crypto.XMR)) {
ibCrypto.put(crypto, button); ibCrypto.put(crypto, button);
button.setOnClickListener(v -> { button.setOnClickListener(v -> {
if (possibleCryptos.contains(crypto)) { if (possibleCryptos.contains(crypto)) {
@ -137,14 +140,21 @@ public class SendAddressWizardFragment extends SendWizardFragment {
} else { } else {
tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto_help_xmr))); tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto_help_xmr)));
tvXmrTo.setVisibility(View.VISIBLE); 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 = view.findViewById(R.id.etAddress);
etAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS); etAddress.getEditText().setRawInputType(InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
etAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() { etAddress.getEditText().setOnEditorActionListener(new TextView.OnEditorActionListener() {
@ -455,6 +465,7 @@ public class SendAddressWizardFragment extends SendWizardFragment {
Timber.d("BUT ONLY XMR SUPPORTED"); Timber.d("BUT ONLY XMR SUPPORTED");
barcodeData = null; barcodeData = null;
sendListener.setBarcodeData(barcodeData); sendListener.setBarcodeData(barcodeData);
return;
} }
if (barcodeData.address != null) { if (barcodeData.address != null) {
etAddress.getEditText().setText(barcodeData.address); etAddress.getEditText().setText(barcodeData.address);

View File

@ -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.api.SideShiftApi;
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl; import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.OkHttpHelper;
import com.m2049r.xmrwallet.util.ServiceHelper; import com.m2049r.xmrwallet.util.ServiceHelper;
import com.m2049r.xmrwallet.widget.ExchangeOtherEditText; import com.m2049r.xmrwallet.widget.ExchangeOtherEditText;
import com.m2049r.xmrwallet.widget.SendProgressView; import com.m2049r.xmrwallet.widget.SendProgressView;
@ -255,8 +254,7 @@ public class SendBtcAmountWizardFragment extends SendWizardFragment {
if (xmrToApi == null) { if (xmrToApi == null) {
synchronized (this) { synchronized (this) {
if (xmrToApi == null) { if (xmrToApi == null) {
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(), xmrToApi = new SideShiftApiImpl(ServiceHelper.getXmrToBaseUrl());
ServiceHelper.getXmrToBaseUrl());
} }
} }
} }

View File

@ -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.api.SideShiftApi;
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl; import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.OkHttpHelper;
import com.m2049r.xmrwallet.util.ServiceHelper; import com.m2049r.xmrwallet.util.ServiceHelper;
import com.m2049r.xmrwallet.widget.SendProgressView; import com.m2049r.xmrwallet.widget.SendProgressView;
@ -543,8 +542,7 @@ public class SendBtcConfirmWizardFragment extends SendWizardFragment implements
if (xmrToApi == null) { if (xmrToApi == null) {
synchronized (this) { synchronized (this) {
if (xmrToApi == null) { if (xmrToApi == null) {
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(), xmrToApi = new SideShiftApiImpl(ServiceHelper.getXmrToBaseUrl());
ServiceHelper.getXmrToBaseUrl());
} }
} }
} }

View File

@ -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.api.SideShiftApi;
import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl; import com.m2049r.xmrwallet.service.shift.sideshift.network.SideShiftApiImpl;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.OkHttpHelper;
import com.m2049r.xmrwallet.util.ServiceHelper; import com.m2049r.xmrwallet.util.ServiceHelper;
import java.text.NumberFormat; import java.text.NumberFormat;
@ -245,8 +244,7 @@ public class SendBtcSuccessWizardFragment extends SendWizardFragment {
if (xmrToApi == null) { if (xmrToApi == null) {
synchronized (this) { synchronized (this) {
if (xmrToApi == null) { if (xmrToApi == null) {
xmrToApi = new SideShiftApiImpl(OkHttpHelper.getOkHttpClient(), xmrToApi = new SideShiftApiImpl(ServiceHelper.getXmrToBaseUrl());
ServiceHelper.getXmrToBaseUrl());
} }
} }
} }

View File

@ -23,28 +23,25 @@ import android.view.ViewGroup;
import android.widget.ImageButton; import android.widget.ImageButton;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.m2049r.xmrwallet.R; import com.m2049r.xmrwallet.R;
import com.m2049r.xmrwallet.data.NodeInfo; import com.m2049r.xmrwallet.data.NodeInfo;
import com.m2049r.xmrwallet.util.ThemeHelper; import com.m2049r.xmrwallet.dialog.HelpFragment;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.NetCipherHelper;
import java.net.HttpURLConnection; import java.net.HttpURLConnection;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.TimeZone;
public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHolder> { public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHolder> {
private final SimpleDateFormat TS_FORMATTER = new SimpleDateFormat("yyyy-MM-dd HH:mm");
public interface OnInteractionListener { public interface OnInteractionListener {
void onInteraction(View view, NodeInfo item); void onInteraction(View view, NodeInfo item);
@ -54,14 +51,16 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
private final List<NodeInfo> nodeItems = new ArrayList<>(); private final List<NodeInfo> nodeItems = new ArrayList<>();
private final OnInteractionListener listener; private final OnInteractionListener listener;
private final Context context; private final FragmentActivity activity;
public NodeInfoAdapter(Context context, OnInteractionListener listener) { public NodeInfoAdapter(FragmentActivity activity, OnInteractionListener listener) {
this.context = context; this.activity = activity;
this.listener = listener; 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<NodeInfo> { private static class NodeDiff extends DiffCallback<NodeInfo> {
@ -142,7 +141,7 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
final ImageButton ibBookmark; final ImageButton ibBookmark;
final View pbBookmark; final View pbBookmark;
final TextView tvName; final TextView tvName;
final TextView tvIp; final TextView tvInfo;
final ImageView ivPing; final ImageView ivPing;
NodeInfo nodeItem; NodeInfo nodeItem;
@ -151,7 +150,7 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
ibBookmark = itemView.findViewById(R.id.ibBookmark); ibBookmark = itemView.findViewById(R.id.ibBookmark);
pbBookmark = itemView.findViewById(R.id.pbBookmark); pbBookmark = itemView.findViewById(R.id.pbBookmark);
tvName = itemView.findViewById(R.id.tvName); tvName = itemView.findViewById(R.id.tvName);
tvIp = itemView.findViewById(R.id.tvAddress); tvInfo = itemView.findViewById(R.id.tvInfo);
ivPing = itemView.findViewById(R.id.ivPing); ivPing = itemView.findViewById(R.id.ivPing);
ibBookmark.setOnClickListener(v -> { ibBookmark.setOnClickListener(v -> {
nodeItem.toggleFavourite(); nodeItem.toggleFavourite();
@ -179,13 +178,12 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
ivPing.setImageResource(getPingIcon(nodeItem)); ivPing.setImageResource(getPingIcon(nodeItem));
if (nodeItem.isTested()) { if (nodeItem.isTested()) {
if (nodeItem.isValid()) { if (nodeItem.isValid()) {
Helper.showTimeDifference(tvIp, nodeItem.getTimestamp()); nodeItem.showInfo(tvInfo);
} else { } else {
tvIp.setText(getResponseErrorText(context, nodeItem.getResponseCode())); nodeItem.showInfo(tvInfo, getResponseErrorText(activity, nodeItem.getResponseCode()), true);
tvIp.setTextColor(ThemeHelper.getThemedColor(context, R.attr.colorError));
} }
} else { } else {
tvIp.setText(context.getResources().getString(R.string.node_testing, nodeItem.getHostAddress())); nodeItem.showInfo(tvInfo);
} }
itemView.setSelected(nodeItem.isSelected()); itemView.setSelected(nodeItem.isSelected());
itemView.setClickable(itemsClickable); itemView.setClickable(itemsClickable);
@ -201,6 +199,16 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
int position = getAdapterPosition(); // gets item position int position = getAdapterPosition(); // gets item position
if (position != RecyclerView.NO_POSITION) { // Check if an item was deleted, but the user clicked it before the UI removed it if (position != RecyclerView.NO_POSITION) { // Check if an item was deleted, but the user clicked it before the UI removed it
final NodeInfo node = nodeItems.get(position); final NodeInfo node = nodeItems.get(position);
if (node.isOnion()) {
switch (NetCipherHelper.getStatus()) {
case NOT_INSTALLED:
HelpFragment.display(activity.getSupportFragmentManager(), R.string.help_tor);
return;
case DISABLED:
HelpFragment.display(activity.getSupportFragmentManager(), R.string.help_tor_enable);
return;
}
}
node.setSelecting(true); node.setSelecting(true);
allowClick(false); allowClick(false);
listener.onInteraction(view, node); listener.onInteraction(view, node);
@ -245,6 +253,8 @@ public class NodeInfoAdapter extends RecyclerView.Adapter<NodeInfoAdapter.ViewHo
return ctx.getResources().getString(R.string.node_general_error); return ctx.getResources().getString(R.string.node_general_error);
} else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) { } else if (responseCode == HttpURLConnection.HTTP_UNAUTHORIZED) {
return ctx.getResources().getString(R.string.node_auth_error); return ctx.getResources().getString(R.string.node_auth_error);
} else if (responseCode == 418) {
return ctx.getResources().getString(R.string.node_tor_error);
} else { } else {
return ctx.getResources().getString(R.string.node_test_error, responseCode); return ctx.getResources().getString(R.string.node_test_error, responseCode);
} }

View File

@ -152,7 +152,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
final ImageView ivTxType; final ImageView ivTxType;
final TextView tvAmount; final TextView tvAmount;
final TextView tvFee; final TextView tvFailed;
final TextView tvPaymentId; final TextView tvPaymentId;
final TextView tvDateTime; final TextView tvDateTime;
final CircularProgressIndicator pbConfirmations; final CircularProgressIndicator pbConfirmations;
@ -163,7 +163,7 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
super(itemView); super(itemView);
ivTxType = itemView.findViewById(R.id.ivTxType); ivTxType = itemView.findViewById(R.id.ivTxType);
tvAmount = itemView.findViewById(R.id.tx_amount); tvAmount = itemView.findViewById(R.id.tx_amount);
tvFee = itemView.findViewById(R.id.tx_fee); tvFailed = itemView.findViewById(R.id.tx_failed);
tvPaymentId = itemView.findViewById(R.id.tx_paymentid); tvPaymentId = itemView.findViewById(R.id.tx_paymentid);
tvDateTime = itemView.findViewById(R.id.tx_datetime); tvDateTime = itemView.findViewById(R.id.tx_datetime);
pbConfirmations = itemView.findViewById(R.id.pbConfirmations); pbConfirmations = itemView.findViewById(R.id.pbConfirmations);
@ -203,18 +203,10 @@ public class TransactionInfoAdapter extends RecyclerView.Adapter<TransactionInfo
tvAmount.setText(context.getString(R.string.tx_list_amount_positive, displayAmount)); tvAmount.setText(context.getString(R.string.tx_list_amount_positive, displayAmount));
} }
if ((infoItem.fee > 0)) { tvFailed.setVisibility(View.GONE);
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);
}
if (infoItem.isFailed) { if (infoItem.isFailed) {
this.tvAmount.setText(context.getString(R.string.tx_list_amount_failed, displayAmount)); this.tvAmount.setText(context.getString(R.string.tx_list_amount_failed, displayAmount));
this.tvFee.setText(context.getString(R.string.tx_list_failed_text)); tvFailed.setVisibility(View.VISIBLE);
tvFee.setVisibility(View.VISIBLE);
setTxColour(failedColour); setTxColour(failedColour);
pbConfirmations.setVisibility(View.GONE); pbConfirmations.setVisibility(View.GONE);
tvConfirmations.setVisibility(View.GONE); tvConfirmations.setVisibility(View.GONE);

View File

@ -75,7 +75,7 @@ public class Wallet {
@Override @Override
@NonNull @NonNull
public String toString() { public String toString() {
return "Wallet.Status: (" + status + "/" + errorString + ", " + connectionStatus; return "Wallet.Status: " + status + "/" + errorString + "/" + connectionStatus;
} }
} }
@ -247,6 +247,8 @@ public class Wallet {
//TODO virtual void setTrustedDaemon(bool arg) = 0; //TODO virtual void setTrustedDaemon(bool arg) = 0;
//TODO virtual bool trustedDaemon() const = 0; //TODO virtual bool trustedDaemon() const = 0;
public native boolean setProxy(String address);
public long getBalance() { public long getBalance() {
return getBalance(accountIndex); return getBalance(accountIndex);
} }

View File

@ -309,6 +309,8 @@ public class WalletManager {
public native String resolveOpenAlias(String address, boolean dnssec_valid); public native String resolveOpenAlias(String address, boolean dnssec_valid);
public native boolean setProxy(String address);
//TODO static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir); //TODO static std::tuple<bool, std::string, std::string, std::string, std::string> checkUpdates(const std::string &software, const std::string &subdir);
static public native void initLogger(String argv0, String defaultLogBaseName); static public native void initLogger(String argv0, String defaultLogBaseName);

View File

@ -45,6 +45,7 @@ import com.m2049r.xmrwallet.model.WalletListener;
import com.m2049r.xmrwallet.model.WalletManager; import com.m2049r.xmrwallet.model.WalletManager;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.LocaleHelper; import com.m2049r.xmrwallet.util.LocaleHelper;
import com.m2049r.xmrwallet.util.NetCipherHelper;
import timber.log.Timber; import timber.log.Timber;
@ -531,6 +532,7 @@ public class WalletService extends Service {
Timber.d("Using daemon %s", WalletManager.getInstance().getDaemonAddress()); Timber.d("Using daemon %s", WalletManager.getInstance().getDaemonAddress());
showProgress(55); showProgress(55);
wallet.init(0); wallet.init(0);
wallet.setProxy(NetCipherHelper.getProxy());
showProgress(90); showProgress(90);
} }
return wallet; return wallet;

View File

@ -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.ExchangeCallback;
import com.m2049r.xmrwallet.service.exchange.api.ExchangeException; import com.m2049r.xmrwallet.service.exchange.api.ExchangeException;
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate; import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
import com.m2049r.xmrwallet.util.NetCipherHelper;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Element; import org.w3c.dom.Element;
@ -48,26 +49,21 @@ import javax.xml.parsers.ParserConfigurationException;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
public class ExchangeApiImpl implements ExchangeApi { public class ExchangeApiImpl implements ExchangeApi {
@NonNull
private final OkHttpClient okHttpClient;
@NonNull @NonNull
private final HttpUrl baseUrl; private final HttpUrl baseUrl;
//so we can inject the mockserver url //so we can inject the mockserver url
@VisibleForTesting @VisibleForTesting
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient, @NonNull final HttpUrl baseUrl) { public ExchangeApiImpl(@NonNull final HttpUrl baseUrl) {
this.okHttpClient = okHttpClient;
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
} }
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) { public ExchangeApiImpl() {
this(okHttpClient, HttpUrl.parse("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml")); 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 // 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); final NetCipherHelper.Request httpRequest = new NetCipherHelper.Request(baseUrl);
httpRequest.enqueue(new okhttp3.Callback() {
okHttpClient.newCall(httpRequest).enqueue(new okhttp3.Callback() {
@Override @Override
public void onFailure(final Call call, final IOException ex) { public void onFailure(final Call call, final IOException ex) {
callback.onError(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<String, Double> fxEntries = new HashMap<>(); final private Map<String, Double> fxEntries = new HashMap<>();
private Calendar fxDate = null; private Calendar fxDate = null;
private Calendar fetchDate = null; private Calendar fetchDate = null;

View File

@ -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.ExchangeException;
import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate; import com.m2049r.xmrwallet.service.exchange.api.ExchangeRate;
import com.m2049r.xmrwallet.util.Helper; import com.m2049r.xmrwallet.util.Helper;
import com.m2049r.xmrwallet.util.NetCipherHelper;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
@ -33,27 +34,21 @@ import java.io.IOException;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
public class ExchangeApiImpl implements ExchangeApi { public class ExchangeApiImpl implements ExchangeApi {
@NonNull
private final OkHttpClient okHttpClient;
private final HttpUrl baseUrl; private final HttpUrl baseUrl;
//so we can inject the mockserver url //so we can inject the mockserver url
@VisibleForTesting @VisibleForTesting
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient, final HttpUrl baseUrl) { public ExchangeApiImpl(final HttpUrl baseUrl) {
this.okHttpClient = okHttpClient;
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
} }
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) { public ExchangeApiImpl() {
this(okHttpClient, HttpUrl.parse("https://api.kraken.com/0/public/Ticker")); this(HttpUrl.parse("https://api.kraken.com/0/public/Ticker"));
} }
@Override @Override
@ -86,9 +81,8 @@ public class ExchangeApiImpl implements ExchangeApi {
.addQueryParameter("pair", base + (quote.equals("BTC") ? "XBT" : quote)) .addQueryParameter("pair", base + (quote.equals("BTC") ? "XBT" : quote))
.build(); .build();
final Request httpRequest = createHttpRequest(url); final NetCipherHelper.Request httpRequest = new NetCipherHelper.Request(url);
httpRequest.enqueue(new okhttp3.Callback() {
okHttpClient.newCall(httpRequest).enqueue(new okhttp3.Callback() {
@Override @Override
public void onFailure(final Call call, final IOException ex) { public void onFailure(final Call call, final IOException ex) {
callback.onError(ex); callback.onError(ex);
@ -127,11 +121,4 @@ public class ExchangeApiImpl implements ExchangeApi {
callback.onError(ex); callback.onError(ex);
} }
} }
private Request createHttpRequest(final HttpUrl url) {
return new Request.Builder()
.url(url)
.get()
.build();
}
} }

View File

@ -35,13 +35,6 @@ import timber.log.Timber;
public class ExchangeApiImpl implements ExchangeApi { public class ExchangeApiImpl implements ExchangeApi {
static public final String BASE_FIAT = "EUR"; static public final String BASE_FIAT = "EUR";
@NonNull
private final OkHttpClient okHttpClient;
public ExchangeApiImpl(@NonNull final OkHttpClient okHttpClient) {
this.okHttpClient = okHttpClient;
}
@Override @Override
public void queryExchangeRate(@NonNull final String baseCurrency, @NonNull final String quoteCurrency, public void queryExchangeRate(@NonNull final String baseCurrency, @NonNull final String quoteCurrency,
@NonNull final ExchangeCallback callback) { @NonNull final ExchangeCallback callback) {
@ -61,13 +54,13 @@ public class ExchangeApiImpl implements ExchangeApi {
final String quote = Helper.BASE_CRYPTO.equals(baseCurrency) ? quoteCurrency : baseCurrency; final String quote = Helper.BASE_CRYPTO.equals(baseCurrency) ? quoteCurrency : baseCurrency;
final ExchangeApi krakenApi = 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() { krakenApi.queryExchangeRate(Helper.BASE_CRYPTO, BASE_FIAT, new ExchangeCallback() {
@Override @Override
public void onSuccess(final ExchangeRate krakenRate) { public void onSuccess(final ExchangeRate krakenRate) {
Timber.d("kraken = %f", krakenRate.getRate()); Timber.d("kraken = %f", krakenRate.getRate());
final ExchangeApi ecbApi = 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() { ecbApi.queryExchangeRate(BASE_FIAT, quote, new ExchangeCallback() {
@Override @Override
public void onSuccess(final ExchangeRate ecbRate) { public void onSuccess(final ExchangeRate ecbRate) {

View File

@ -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.QueryOrderStatus;
import com.m2049r.xmrwallet.service.shift.sideshift.api.RequestQuote; 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.api.SideShiftApi;
import com.m2049r.xmrwallet.util.OkHttpHelper; import com.m2049r.xmrwallet.util.NetCipherHelper;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -39,22 +39,14 @@ import java.io.IOException;
import okhttp3.Call; import okhttp3.Call;
import okhttp3.HttpUrl; import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response; import okhttp3.Response;
import timber.log.Timber; import timber.log.Timber;
public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall { public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall {
@NonNull
private final OkHttpClient okHttpClient;
private final HttpUrl baseUrl; private final HttpUrl baseUrl;
public SideShiftApiImpl(@NonNull final OkHttpClient okHttpClient, final HttpUrl baseUrl) { public SideShiftApiImpl(final HttpUrl baseUrl) {
this.okHttpClient = okHttpClient;
this.baseUrl = baseUrl; this.baseUrl = baseUrl;
} }
@ -95,9 +87,9 @@ public class SideShiftApiImpl implements SideShiftApi, ShiftApiCall {
final HttpUrl url = baseUrl.newBuilder() final HttpUrl url = baseUrl.newBuilder()
.addPathSegments(path) .addPathSegments(path)
.build(); .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 @Override
public void onFailure(final Call call, final IOException ex) { public void onFailure(final Call call, final IOException ex) {
callback.onError(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);
}
}
} }

View File

@ -84,7 +84,7 @@ public class Helper {
static public final long ONE_XMR = Math.round(Math.pow(10, Helper.XMR_DECIMALS)); 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 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 WALLET_DIR = "wallets";
static private final String MONERO_DIR = "monero"; static private final String MONERO_DIR = "monero";
@ -606,30 +606,4 @@ public class Helper {
static public boolean preventScreenshot() { static public boolean preventScreenshot() {
return !(BuildConfig.DEBUG || BuildConfig.FLAVOR_type.equals("alpha")); 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));
}
} }

View File

@ -0,0 +1,389 @@
/*
* Copyright (c) 2021 m2049r
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.m2049r.xmrwallet.util;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import com.burgstaller.okhttp.AuthenticationCacheInterceptor;
import com.burgstaller.okhttp.CachingAuthenticatorDecorator;
import com.burgstaller.okhttp.digest.CachingAuthenticator;
import com.burgstaller.okhttp.digest.Credentials;
import com.burgstaller.okhttp.digest.DigestAuthenticator;
import org.json.JSONObject;
import java.io.IOException;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import info.guardianproject.netcipher.client.StrongOkHttpClientBuilder;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import info.guardianproject.netcipher.proxy.SignatureUtils;
import info.guardianproject.netcipher.proxy.StatusCallback;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.Response;
import timber.log.Timber;
@RequiredArgsConstructor
public class NetCipherHelper implements StatusCallback {
public static final String USER_AGENT = "Monerujo/1.0";
public static final int HTTP_TIMEOUT = 1000; //ms
public static final int TOR_TIMEOUT_CONNECT = 5000; //ms
public static final int TOR_TIMEOUT = 2000; //ms
public interface OnStatusChangedListener {
void connected();
void disconnected();
void notInstalled();
void notEnabled();
}
final private Context context;
final private OrbotHelper orbot;
@SuppressLint("StaticFieldLeak")
private static NetCipherHelper Instance;
public static void createInstance(Context context) {
if (Instance == null) {
synchronized (NetCipherHelper.class) {
if (Instance == null) {
final Context applicationContext = context.getApplicationContext();
Instance = new NetCipherHelper(applicationContext, OrbotHelper.get(context).statusTimeout(5000));
}
}
}
}
public static NetCipherHelper getInstance() {
if (Instance == null) throw new IllegalStateException("NetCipherHelper is null");
return Instance;
}
private OkHttpClient client;
private void createTorClient(Intent statusIntent) {
String orbotStatus = statusIntent.getStringExtra(OrbotHelper.EXTRA_STATUS);
if (orbotStatus == null) throw new IllegalStateException("status is null");
if (!orbotStatus.equals(OrbotHelper.STATUS_ON))
throw new IllegalStateException("Orbot is not ON");
try {
final OkHttpClient.Builder okBuilder = new OkHttpClient.Builder()
.connectTimeout(TOR_TIMEOUT_CONNECT, TimeUnit.MILLISECONDS)
.writeTimeout(TOR_TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(TOR_TIMEOUT, TimeUnit.MILLISECONDS);
client = new StrongOkHttpClientBuilder(context)
.withSocksProxy()
.applyTo(okBuilder, statusIntent)
.build();
Helper.ALLOW_SHIFT = false; // no shifting with Tor
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
private void createClearnetClient() {
try {
client = new OkHttpClient.Builder()
.connectTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS)
.writeTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS)
.readTimeout(HTTP_TIMEOUT, TimeUnit.MILLISECONDS)
.build();
Helper.ALLOW_SHIFT = true;
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
private OnStatusChangedListener onStatusChangedListener;
public static void deregister() {
getInstance().onStatusChangedListener = null;
}
public static void register(OnStatusChangedListener listener) {
final NetCipherHelper me = getInstance();
me.onStatusChangedListener = listener;
// NOT_INSTALLED is dealt with through the callbacks
me.orbot.removeStatusCallback(me) // make sure we are registered just once
.addStatusCallback(me);
// deal with org.torproject.android.intent.action.STATUS = STARTS_DISABLED
me.context.registerReceiver(orbotStatusReceiver, new IntentFilter(OrbotHelper.ACTION_STATUS));
me.startTor();
}
// for StatusCallback
public enum Status {
STARTING,
ENABLED,
STOPPING,
DISABLED,
NOT_INSTALLED,
NOT_ENABLED,
UNKNOWN;
}
private Status status = Status.UNKNOWN;
@Override
public void onStarting() {
Timber.d("onStarting");
status = Status.STARTING;
}
@Override
public void onEnabled(Intent statusIntent) {
Timber.d("onEnabled");
if (getTorPref() != Status.ENABLED) return; // do we want Tor?
createTorClient(statusIntent);
status = Status.ENABLED;
if (onStatusChangedListener != null) {
new Thread(() -> onStatusChangedListener.connected()).start();
}
}
@Override
public void onStopping() {
Timber.d("onStopping");
status = Status.STOPPING;
}
@Override
public void onDisabled() {
Timber.d("onDisabled");
createClearnetClient();
status = Status.DISABLED;
if (onStatusChangedListener != null) {
new Thread(() -> onStatusChangedListener.disconnected()).start();
}
}
@Override
public void onStatusTimeout() {
Timber.d("onStatusTimeout");
createClearnetClient();
// (timeout does not not change the status)
if (onStatusChangedListener != null) {
new Thread(() -> onStatusChangedListener.disconnected()).start();
}
orbotInit = false; // do init() next time we try to open Tor
}
@Override
public void onNotYetInstalled() {
Timber.d("onNotYetInstalled");
// never mind then
orbot.removeStatusCallback(this);
createClearnetClient();
status = Status.NOT_INSTALLED;
if (onStatusChangedListener != null) {
new Thread(() -> onStatusChangedListener.notInstalled()).start();
}
}
// user has not enabled background Orbot starts
public void onNotEnabled() {
Timber.d("onNotEnabled");
// keep the callback in case they turn it on manually
setTorPref(Status.DISABLED);
createClearnetClient();
status = Status.NOT_ENABLED;
if (onStatusChangedListener != null) {
new Thread(() -> onStatusChangedListener.notEnabled()).start();
}
}
static public Status getStatus() {
return getInstance().status;
}
public void toggle() {
switch (getStatus()) {
case ENABLED:
onDisabled();
setTorPref(Status.DISABLED);
break;
case DISABLED:
setTorPref(Status.ENABLED);
startTor();
break;
}
}
private boolean orbotInit = false;
private void startTor() {
if (!isOrbotInstalled()) {
onNotYetInstalled();
} else if (getTorPref() == Status.DISABLED) {
onDisabled();
} else if (!orbotInit) {
orbotInit = orbot.init();
} else {
orbot.requestStart(context);
}
}
// extracted from OrbotHelper
private boolean isOrbotInstalled() {
ArrayList<String> hashes = new ArrayList<>();
// Tor Project signing key
hashes.add("A4:54:B8:7A:18:47:A8:9E:D7:F5:E7:0F:BA:6B:BA:96:F3:EF:29:C2:6E:09:81:20:4F:E3:47:BF:23:1D:FD:5B");
// f-droid.org signing key
hashes.add("A7:02:07:92:4F:61:FF:09:37:1D:54:84:14:5C:4B:EE:77:2C:55:C1:9E:EE:23:2F:57:70:E1:82:71:F7:CB:AE");
return null != SignatureUtils.validateBroadcastIntent(context,
OrbotHelper.getOrbotStartIntent(context),
hashes, false);
}
static public boolean hasClient() {
return getInstance().client != null;
}
static public boolean isTor() {
return getStatus() == Status.ENABLED;
}
static public String getProxy() {
if (!isTor()) return "";
final Proxy proxy = getInstance().client.proxy();
if (proxy == null) return "";
return proxy.address().toString().substring(1);
}
@ToString
static public class Request {
final HttpUrl url;
final String json;
final String username;
final String password;
public Request(final HttpUrl url, final String json, final String username, final String password) {
this.url = url;
this.json = json;
this.username = username;
this.password = password;
}
public Request(final HttpUrl url, final JSONObject json) {
this(url, json == null ? null : json.toString(), null, null);
}
public Request(final HttpUrl url) {
this(url, null, null, null);
}
public void enqueue(Callback callback) {
newCall().enqueue(callback);
}
public Response execute() throws IOException {
return newCall().execute();
}
private Call newCall() {
return getClient().newCall(getRequest());
}
private OkHttpClient getClient() {
final OkHttpClient client = getInstance().client;
if ((username != null) && (!username.isEmpty())) {
final DigestAuthenticator authenticator = new DigestAuthenticator(new Credentials(username, password));
final Map<String, CachingAuthenticator> authCache = new ConcurrentHashMap<>();
return client.newBuilder()
.authenticator(new CachingAuthenticatorDecorator(authenticator, authCache))
.addInterceptor(new AuthenticationCacheInterceptor(authCache))
.build();
// TODO: maybe cache & reuse the client for these credentials?
} else {
return client;
}
}
private okhttp3.Request getRequest() {
final okhttp3.Request.Builder builder =
new okhttp3.Request.Builder()
.url(url)
.header("User-Agent", USER_AGENT);
if (json != null) {
builder.post(RequestBody.create(json, MediaType.parse("application/json")));
} else {
builder.get();
}
return builder.build();
}
}
private static final String PREFS_NAME = "tor";
private static final String PREFS_STATUS = "status";
private Status currentPref = Status.UNKNOWN;
private Status getTorPref() {
if (currentPref != Status.UNKNOWN) return currentPref;
currentPref = Status.valueOf(context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
.getString(PREFS_STATUS, "DISABLED"));
return currentPref;
}
private void setTorPref(Status status) {
if (getTorPref() == status) return; // no change
context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE)
.edit()
.putString(PREFS_STATUS, status.name())
.apply();
currentPref = status;
}
private static final BroadcastReceiver orbotStatusReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Timber.d("%s/%s", intent.getAction(), intent.getStringExtra(OrbotHelper.EXTRA_STATUS));
if (OrbotHelper.ACTION_STATUS.equals(intent.getAction())) {
if (OrbotHelper.STATUS_STARTS_DISABLED.equals(intent.getStringExtra(OrbotHelper.EXTRA_STATUS))) {
getInstance().onNotEnabled();
}
}
}
};
public void installOrbot(Activity host) {
host.startActivity(OrbotHelper.getOrbotInstallIntent(context));
}
}

View File

@ -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();
}
}

View File

@ -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");
}
}

View File

@ -19,6 +19,6 @@ public class ServiceHelper {
} }
static public ExchangeApi getExchangeApi() { static public ExchangeApi getExchangeApi() {
return new com.m2049r.xmrwallet.service.exchange.krakenEcb.ExchangeApiImpl(OkHttpHelper.getOkHttpClient()); return new com.m2049r.xmrwallet.service.exchange.krakenEcb.ExchangeApiImpl();
} }
} }

View File

@ -344,8 +344,8 @@ public class ExchangeEditText extends LinearLayout {
if (rate > 0) { if (rate > 0) {
tvAmountB.setText(Helper.getFormattedAmount(rate * amount, getCurrencyB() == 0)); tvAmountB.setText(Helper.getFormattedAmount(rate * amount, getCurrencyB() == 0));
} else { } else {
tvAmountB.setText(null); tvAmountB.setText("--");
Timber.w("No rate!"); Timber.d("No rate!");
} }
} }

View File

@ -321,23 +321,13 @@ public class ExchangeView extends LinearLayout {
@Override @Override
public void onSuccess(final ExchangeRate exchangeRate) { public void onSuccess(final ExchangeRate exchangeRate) {
if (isAttachedToWindow()) if (isAttachedToWindow())
new Handler(Looper.getMainLooper()).post(new Runnable() { new Handler(Looper.getMainLooper()).post(() -> exchange(exchangeRate));
@Override
public void run() {
exchange(exchangeRate);
}
});
} }
@Override @Override
public void onError(final Exception e) { public void onError(final Exception e) {
Timber.e(e.getLocalizedMessage()); Timber.e(e.getLocalizedMessage());
new Handler(Looper.getMainLooper()).post(new Runnable() { new Handler(Looper.getMainLooper()).post(() -> exchangeFailed());
@Override
public void run() {
exchangeFailed();
}
});
} }
}); });
} }
@ -362,11 +352,10 @@ public class ExchangeView extends LinearLayout {
} }
tvAmountB.setText(xmrAmount); tvAmountB.setText(xmrAmount);
} else { // no XMR currency - cannot happen! } else { // no XMR currency - cannot happen!
Timber.e("No XMR currency!"); throw new IllegalStateException("No XMR currency!");
setXmr(null);
notXmrAmount = null;
return;
} }
if (rate == 0)
tvAmountB.setText("--");
} }
boolean prepareExchange() { boolean prepareExchange() {

View File

@ -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<StrongOkHttpClientBuilder, OkHttpClient> {
/**
* 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());
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android"> <selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="?attr/colorSecondary" android:state_enabled="true"/> <item android:color="?attr/colorPrimary" android:state_enabled="true"/>
<item android:color="?attr/colorOnBackground"/> <item android:color="?attr/colorPrimaryVariant"/>
</selector> </selector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#2D1A2E"
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
</vector>

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="100"
android:viewportHeight="100">
<path
android:fillColor="@color/btn_color_selector"
android:pathData="M50,8.33A41.67,41.67 0,1 0,91.67 50,41.65 41.65,0 0,0 50,8.33ZM78.87,33.33L66.54,33.33A65.26,65.26 0,0 0,60.79 18.5,33.48 33.48,0 0,1 78.83,33.33ZM50,16.83a58.59,58.59 0,0 1,8 16.5L42,33.33A58.72,58.72 0,0 1,50 16.83ZM17.75,58.33a32.66,32.66 0,0 1,0 -16.66L31.83,41.67A69.49,69.49 0,0 0,31.25 50a69.49,69.49 0,0 0,0.58 8.33ZM21.17,66.67L33.46,66.67A64.9,64.9 0,0 0,39.21 81.5,33.26 33.26,0 0,1 21.17,66.67ZM33.46,33.33L21.17,33.33a33.26,33.26 0,0 1,18 -14.83A65.26,65.26 0,0 0,33.46 33.33ZM50,83.17a58.72,58.72 0,0 1,-8 -16.5L58,66.67A58.72,58.72 0,0 1,50 83.17ZM59.75,58.33L40.25,58.33A60.51,60.51 0,0 1,39.58 50a59.88,59.88 0,0 1,0.67 -8.33h19.5A59.88,59.88 0,0 1,60.42 50,60.51 60.51,0 0,1 59.75,58.33ZM60.75,81.5a65.08,65.08 0,0 0,5.75 -14.83L78.83,66.67A33.44,33.44 0,0 1,60.79 81.5ZM68.13,58.33A69.49,69.49 0,0 0,68.75 50a69.49,69.49 0,0 0,-0.58 -8.33L82.25,41.67a32.66,32.66 0,0 1,0 16.66Z" />
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="100"
android:viewportHeight="100">
<path
android:fillColor="@color/btn_color_selector"
android:fillType="evenOdd"
android:pathData="M50.08,84.36L50.08,79.27a29.27,29.27 0,0 0,0 -58.54L50.08,15.64a34.36,34.36 0,0 1,0 68.72ZM50.08,66.54a16.55,16.55 0,0 0,0 -33.09L50.08,28.36a21.64,21.64 0,0 1,0 43.27ZM50.08,41.09a8.91,8.91 0,0 1,0 17.82ZM8,50A42,42 0,1 0,50 8,42 42,0 0,0 8,50Z" />
</vector>

View File

@ -7,26 +7,14 @@
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingEnd="16dp"> android:paddingEnd="16dp">
<LinearLayout <TextView
android:id="@+id/tvHelp"
style="@style/MoneroText"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:layout_marginTop="@dimen/header_top"
android:autoLink="web"
<ImageView android:gravity="start"
android:layout_width="match_parent" android:textSize="14sp"
android:layout_height="48dp" tools:text="@string/menu_help" />
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tvHelp"
style="@style/MoneroText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/header_top"
android:autoLink="web"
android:gravity="start"
android:textSize="14sp"
tools:text="@string/menu_help" />
</LinearLayout>
</ScrollView> </ScrollView>

View File

@ -29,28 +29,49 @@
<RelativeLayout <RelativeLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"> android:layout_marginBottom="8dp">
<com.google.android.material.progressindicator.CircularProgressIndicator
android:id="@+id/pbNetwork"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_alignStart="@id/ibNetwork"
android:layout_alignTop="@+id/ibNetwork"
android:layout_alignEnd="@id/ibNetwork"
android:layout_alignBottom="@id/ibNetwork"
android:layout_gravity="center"
android:indeterminate="true"
android:progress="100"
android:visibility="visible"
app:indicatorInset="9dp"
app:indicatorSize="30dp"
app:trackThickness="2dp" />
<ImageButton
android:id="@+id/ibNetwork"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerInParent="true"
android:background="?android:attr/selectableItemBackgroundBorderless"
android:gravity="center"
android:padding="12dp"
android:src="@drawable/ic_network_clearnet" />
<FrameLayout <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="0dp"
android:layout_alignParentTop="true" android:layout_alignTop="@+id/ibNetwork"
android:layout_marginStart="16dp" android:layout_alignBottom="@id/ibNetwork"
android:layout_toStartOf="@+id/ibRenew"> android:layout_toStartOf="@+id/ibRenew"
android:layout_toEndOf="@+id/ibNetwork">
<ProgressBar
android:id="@+id/pbNode"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:visibility="invisible" />
<LinearLayout <LinearLayout
android:id="@+id/llNode" android:id="@+id/llNode"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="?android:attr/selectableItemBackground" android:background="?android:attr/selectableItemBackground"
android:gravity="start|center_vertical" android:gravity="center_vertical"
android:orientation="vertical"> android:orientation="vertical">
<TextView <TextView
@ -58,17 +79,14 @@
style="@style/MoneroText.PosAmount" style="@style/MoneroText.PosAmount"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:drawablePadding="8dp"
app:drawableStartCompat="@drawable/ic_refresh_black_24dp"
tools:text="monero-v9.monerujo.io" /> tools:text="monero-v9.monerujo.io" />
<TextView <TextView
android:id="@+id/tvNodeAddress" android:id="@+id/tvInfo"
style="@style/MoneroText.Small" style="@style/MoneroText.Small"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="32dp" tools:text="Last Block: 2 minutes ago" />
tools:text="128.130.233.151:18089" />
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>

View File

@ -111,8 +111,9 @@
android:text="@string/label_receive_info_gen_qr_code" android:text="@string/label_receive_info_gen_qr_code"
android:textAlignment="center" android:textAlignment="center"
android:textSize="16sp" android:textSize="16sp"
android:visibility="gone" android:textColor="#2D1A2E"
card_view:drawableStartCompat="@drawable/ic_info_outline_gray_24dp" /> android:visibility="visible"
card_view:drawableStartCompat="@drawable/ic_info_outline_black_24dp" />
<ImageView <ImageView
android:id="@+id/qrCode" android:id="@+id/qrCode"

View File

@ -126,23 +126,38 @@
android:src="@drawable/ic_xmrto_doge_off" /> android:src="@drawable/ic_xmrto_doge_off" />
</LinearLayout> </LinearLayout>
<TextView <FrameLayout
android:id="@+id/tvXmrTo"
style="@style/MoneroText.Info"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginLeft="8dp" android:layout_marginLeft="8dp"
android:layout_marginTop="16dp" android:layout_marginTop="16dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:layout_marginBottom="16dp" android:layout_marginBottom="16dp">
android:drawablePadding="8dp"
android:gravity="start" <TextView
android:singleLine="false" android:id="@+id/tvXmrTo"
android:text="@string/label_send_btc_xmrto_key" style="@style/MoneroText.Info"
android:textSize="18sp" android:layout_width="match_parent"
android:visibility="invisible" android:layout_height="match_parent"
app:drawableStartCompat="@drawable/gunther_24dp" android:drawablePadding="8dp"
tools:text="@string/info_xmrto" /> android:gravity="start|center_vertical"
android:singleLine="false"
android:textSize="18sp"
android:visibility="invisible"
app:drawableStartCompat="@drawable/gunther_24dp"
tools:text="@string/info_xmrto" />
<TextView
android:id="@+id/tvTor"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawablePadding="8dp"
android:gravity="start|center_vertical"
android:singleLine="false"
android:text="@string/tor_noshift"
android:visibility="invisible"
app:drawableStartCompat="@drawable/gunther_24dp" />
</FrameLayout>
</LinearLayout> </LinearLayout>
<com.google.android.material.textfield.TextInputLayout <com.google.android.material.textfield.TextInputLayout

View File

@ -53,7 +53,7 @@
tools:text="monero-v9.monerujo.io" /> tools:text="monero-v9.monerujo.io" />
<TextView <TextView
android:id="@+id/tvAddress" android:id="@+id/tvInfo"
style="@style/MoneroText.Small" style="@style/MoneroText.Small"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"

View File

@ -73,12 +73,12 @@
tools:text="+ 999.999999" /> tools:text="+ 999.999999" />
<TextView <TextView
android:id="@+id/tx_fee" android:id="@+id/tx_failed"
style="@style/MoneroText.PosFee" style="@style/MoneroText.PosFee"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="end" android:gravity="end"
tools:text="Fee 0.06817" /> android:text="@string/tx_list_failed_text" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>

View File

@ -4,11 +4,11 @@
<h1>Crear Portamonedes - New</h1> <h1>Crear Portamonedes - New</h1>
<p>Per si necessiteu una nova adreça de Monero!</p> <p>Per si necessiteu una nova adreça de Monero!</p>
<p>Introduïu un nom i contrasenya únics del portamonedes. <p>Introduïu un nom i contrasenya únics del portamonedes.
         La contrasenya sutilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.</p> La contrasenya sutilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.</p>
<h2>Apunteu la vostra llavor mnemotècnica!</h2> <h2>Apunteu la vostra llavor mnemotècnica!</h2>
<p>A la pantalla següent trobareu la vostra "Llavor Mnemotècnica" de 25 paraules. <p>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. 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 <em> qualsevol persona</em> tingui accés total als vostres fons!.</p> Mantenir-la segura i privada és molt important ja que permet que <em> qualsevol persona</em> tingui accés total als vostres fons!.</p>
<p>Si perdeu la contrasenya del portamonedes encara podrieu recuperar-lo amb la llavor Mnemotècnica.</p> <p>Si perdeu la contrasenya del portamonedes encara podrieu recuperar-lo amb la llavor Mnemotècnica.</p>
<p>La llavor Mnemotècnica tampoc no es pot canviar mai, i si és robada o compromesa dalguna 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 <em> múltiple </em> llocs de forma segura.</p> <p>La llavor Mnemotècnica tampoc no es pot canviar mai, i si és robada o compromesa dalguna 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 <em> múltiple </em> llocs de forma segura.</p>
]]></string> ]]></string>
@ -17,7 +17,7 @@
<h1>Crear Portamonedes - Llavor</h1> <h1>Crear Portamonedes - Llavor</h1>
<p>Si ja teniu una adreça Monero i voleu recuperar les transaccions de la blockchain!</p> <p>Si ja teniu una adreça Monero i voleu recuperar les transaccions de la blockchain!</p>
<p>Introduïu un nom i contrasenya únics del portamonedes. <p>Introduïu un nom i contrasenya únics del portamonedes.
         La contrasenya sutilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.</p> La contrasenya sutilitza per protegir les dades del seu portamonedes en el dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.</p>
<p>Introduïu la Llavor en el camp \"Llavor Mnemotècnica\".<p> <p>Introduïu la Llavor en el camp \"Llavor Mnemotècnica\".<p>
<p>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 <em> abans </em> dhaver fer servir aquesta adreça del portamonedes.</p> <p>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 <em> abans </em> dhaver fer servir aquesta adreça del portamonedes.</p>
]]></string> ]]></string>
@ -36,7 +36,7 @@
<p>Introduïu un nom i contrasenya únics del portamonedes. La contrasenya sutilitza per protegir les dades de la seva cartera al dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.<p> <p>Introduïu un nom i contrasenya únics del portamonedes. La contrasenya sutilitza per protegir les dades de la seva cartera al dispositiu. Utilitzeu una contrasenya sòlida - encara millor si utiliza una frase.<p>
<p>Introduïu la vostra Adreça Monero en el camp \"Adreça Pública\" i ompliu \"Clau de Visualització\" i \"Clau de Despesa\" </p> <p>Introduïu la vostra Adreça Monero en el camp \"Adreça Pública\" i ompliu \"Clau de Visualització\" i \"Clau de Despesa\" </p>
<p>Introduïu el número de bloc de la primera transacció realitzada en aquesta adreça en el <p>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 <em> abans </em> dhaver fer servir aquesta adreça del portamonedes.</p> 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 <em> abans </em> dhaver fer servir aquesta adreça del portamonedes.</p>
]]></string> ]]></string>
<string name="help_create_view"><![CDATA[ <string name="help_create_view"><![CDATA[
@ -53,20 +53,20 @@
La vostra adreça pública és com el vostre número de compte bancari que podeu compartir amb qualsevol persona sense haver de tenir por de perdre el vostres Monero. La gent enviarà Monero al seu portamonedes mitjançant aquesta adreça. La vostra adreça pública és com el vostre número de compte bancari que podeu compartir amb qualsevol persona sense haver de tenir por de perdre el vostres Monero. La gent enviarà Monero al seu portamonedes mitjançant aquesta adreça.
<h2>Clau Mnemotècnica</h2> <h2>Clau Mnemotècnica</h2>
Aquestes són les úniques dades necessàries per a recuperar el vostre portamonedes i obtenir 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 <em> qualsevol persona</em> 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 <em> qualsevol persona</em> tingui accés total als vostres fons! Si no us heu escrit en cap lloc segur, feu-ho!
<h2>Contrasenya de Recuperació dArxius del Portamonedes</h2> <h2>Contrasenya de Recuperació dArxius del Portamonedes</h2>
Assegureu-vos que heu escrit aquesta contrasenya. Si restabliu el dispositiu o desinstal·leu laplicació, la necessitarà per tornar a accedir al seu portamonedes.<br/> Assegureu-vos que heu escrit aquesta contrasenya. Si restabliu el dispositiu o desinstal·leu laplicació, la necessitarà per tornar a accedir al seu portamonedes.<br/>
<h3>CrAzYsenya</h3> <h3>CrAzYsenya</h3>
Si la contrasenya que es mostra aquí és de 52 caràcters alfanumèrics en grups de 4 - felicitats! 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!<br/> 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!<br/>
Aquesta opció és obligatoria per a tots els nous portamonedes. Aquesta opció és obligatoria per a tots els nous portamonedes.
<h3>Contrasenya de Llegat</h3> <h3>Contrasenya de Llegat</h3>
Si veieu la vostra contrasenya aquí, els fitxers del portamonedes no estan tan segurs com quan sutilitza la CrAzYsenya. Per solucionar-ho, seleccioneu \"Canviar Contrasenya\" des del menú. Després dentrar una nova contrasenya (potser fins i tot la mateixa que abans) laplicació 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 sutilitza la CrAzYsenya. Per solucionar-ho, seleccioneu \"Canviar Contrasenya\" des del menú. Després dentrar una nova contrasenya (potser fins i tot la mateixa que abans) laplicació generarà una CrAzYsenya per a protegir els vostres arxius del portamonedes. Anoteu-la!
<h3>CrAzYsenya del Portamonedes</h3> <h3>CrAzYsenya del Portamonedes</h3>
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. <br/> 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. <br/>
        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! 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!
<h2>Clau de Visualització</h2> <h2>Clau de Visualització</h2>
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.
<h2>Clau de Despesa</h2> <h2>Clau de Despesa</h2>
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. 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.
]]></string> ]]></string>
@ -75,13 +75,13 @@
<h1>Llista de Portamonedes</h1> <h1>Llista de Portamonedes</h1>
<h2>Node</h2> <h2>Node</h2>
<p>Monerujo utilitza un node remot per comunicar-se amb la xarxa Monero sense necessitat <p>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/<p> 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/<p>
<p>Monerujo té alguns Nodes remots incorporats. Sen recorda dels últims cinc nodes empleats.</p> <p>Monerujo té alguns Nodes remots incorporats. Sen recorda dels últims cinc nodes empleats.</p>
<h2>Portamonedes</h2> <h2>Portamonedes</h2>
<p>Aquí podeu veure els portamonedes. Es troben a la carpeta <tt> monerujo </tt> <p>Aquí podeu veure els portamonedes. Es troben a la carpeta <tt> monerujo </tt>
         dins lemmagatzematge intern del dispositiu. Podeu utilitzar una aplicació dexploració darxius per veurels. Haurieu de fer còpies de seguretat daquesta carpeta de manera regular en un emmagatzematge extern al dispositiu en cas que el vostre dispositiu exploti o el robin.</p> dins lemmagatzematge intern del dispositiu. Podeu utilitzar una aplicació dexploració darxius per veurels. Haurieu de fer còpies de seguretat daquesta carpeta de manera regular en un emmagatzematge extern al dispositiu en cas que el vostre dispositiu exploti o el robin.</p>
<p>Seleccioneu una portamonedes per obrir-lo o premeu el botó "+" per crear-ne un de nou. <p>Seleccioneu una portamonedes per obrir-lo o premeu el botó "+" per crear-ne un de nou.
         O seleccioneu una de les operacions del portamonedes:</p> O seleccioneu una de les operacions del portamonedes:</p>
<h3>Detalls</h3> <h3>Detalls</h3>
<p>Mostra els detalls del portamonedes, la llavor i les seves claus.</p> <p>Mostra els detalls del portamonedes, la llavor i les seves claus.</p>
<h3>Rebre</h3> <h3>Rebre</h3>
@ -90,7 +90,7 @@
<p>Canvia el nom del portamonedes. El canvi de nom no afecta a les còpies de seguretat.</p> <p>Canvia el nom del portamonedes. El canvi de nom no afecta a les còpies de seguretat.</p>
<h3>Còpia de Seguretat</h3> <h3>Còpia de Seguretat</h3>
<p>Feu una còpia del portamonedes en la carpeta <tt> backups </tt> dins del <tt> monerujo </tt> <p>Feu una còpia del portamonedes en la carpeta <tt> backups </tt> dins del <tt> monerujo </tt>
         per a sobreescriure còpies anteriors.</p> per a sobreescriure còpies anteriors.</p>
<h3>Arxiu</h3> <h3>Arxiu</h3>
<p>Feu una còpia de seguretat i a continuació elimineu el portamonedes. La còpia es mantindrà a la carpeta <tt> backups </tt>. Si ja no necessiteu les vostres còpies de seguretat les haureu deliminar amb un explorador darxius o una aplicació segura.</p> <p>Feu una còpia de seguretat i a continuació elimineu el portamonedes. La còpia es mantindrà a la carpeta <tt> backups </tt>. Si ja no necessiteu les vostres còpies de seguretat les haureu deliminar amb un explorador darxius o una aplicació segura.</p>
]]></string> ]]></string>
@ -100,9 +100,9 @@
<h2>Destí</h2> <h2>Destí</h2>
Aquesta és ladreça pública del portamonedes on esteu enviant els Monero. Aquesta és ladreça pública del portamonedes on esteu enviant els Monero.
<h2>ID de Pagament</h2> <h2>ID de Pagament</h2>
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.
<h2>ID de Transacció</h2> <h2>ID de Transacció</h2>
Aquest és el vostre ID de transacció que podeu utilitzar per identificar la vostra transacció oculta en un Explorador de Blockchain de Monero com <a href="https:// xmrchain.net/"> https://xmrchain.net/ </a> Aquest és el vostre ID de transacció que podeu utilitzar per identificar la vostra transacció oculta en un Explorador de Blockchain de Monero com <a href="https:// xmrchain.net/"> https://xmrchain.net/ </a>
<h2>Clau de Transacció</h2> <h2>Clau de Transacció</h2>
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. 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.
<h2>Bloc</h2> <h2>Bloc</h2>
@ -122,14 +122,14 @@
<h1>Enviant BTC</h1> <h1>Enviant BTC</h1>
<h2>SideShift.ai</h2> <h2>SideShift.ai</h2>
<p>SideShift.ai és un servei de tercers que fa proporciona el canvi de Monero a Bitcoin. <p>SideShift.ai és un servei de tercers que fa proporciona el canvi de Monero a Bitcoin.
         Nosaltres fem servir lAPI SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop dull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. Lequip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.</p> Nosaltres fem servir lAPI SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop dull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. Lequip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.</p>
<h2>Tipus de Canvi SideShift.ai<h2> <h2>Tipus de Canvi SideShift.ai<h2>
<p>A la pantalla \"Quantitat\" es mostraran els paràmetres actuals del servei SideShift.ai. Aquests <p>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.</p> 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.</p>
<h2>Ordre de compra SideShift.ai<h2> <h2>Ordre de compra SideShift.ai<h2>
<p>A la pantalla \"Confirmar\", veureu lordre de compra SideShift.ai real. Aquesta comanda és vàlida per a <p>A la pantalla \"Confirmar\", veureu lordre 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 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.</p> ser diferent del mostrat en pantalles anteriors.</p>
<h2>Clau Secreta SideShift.ai<h2> <h2>Clau Secreta SideShift.ai<h2>
<p>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.</p> <p>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.</p>
<h2>Compte enrere SideShift.ai!</h2> <h2>Compte enrere SideShift.ai!</h2>
@ -140,14 +140,14 @@
<h1>Enviant BTC</h1> <h1>Enviant BTC</h1>
<h2>SideShift.ai</h2> <h2>SideShift.ai</h2>
<p>SideShift.ai és un servei de tercers que fa proporciona el canvi de Monero a Bitcoin. <p>SideShift.ai és un servei de tercers que fa proporciona el canvi de Monero a Bitcoin.
         Nosaltres fem servir lAPI SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop dull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. Lequip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.</p> Nosaltres fem servir lAPI SideShift.ai per integrar els pagaments de Bitcoin a Monerujo. Si us plau, doneu un cop dull a https://sideshift.ai i decidiu vosaltres mateixos si és una cosa que volgueu utilitzar. Lequip de Monerujo no està associat amb SideShift.ai i no pot oferir assistència amb el seu servei.</p>
<h2>Tipus de Canvi SideShift.ai<h2> <h2>Tipus de Canvi SideShift.ai<h2>
<p>A la pantalla \"Quantitat\" es mostraran els paràmetres actuals del servei SideShift.ai. Aquests <p>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.</p> 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.</p>
<h2>Ordre de compra SideShift.ai<h2> <h2>Ordre de compra SideShift.ai<h2>
<p>A la pantalla \"Confirmar\", veureu lordre de compra SideShift.ai real. Aquesta comanda és vàlida per a <p>A la pantalla \"Confirmar\", veureu lordre 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 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.</p> ser diferent del mostrat en pantalles anteriors.</p>
<h2>Clau Secreta SideShift.ai<h2> <h2>Clau Secreta SideShift.ai<h2>
<p>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.</p> <p>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.</p>
<h2>Compte enrere SideShift.ai!</h2> <h2>Compte enrere SideShift.ai!</h2>
@ -163,8 +163,8 @@
<h2>El Balanç</h2> <h2>El Balanç</h2>
<p><b>Ajuda! El balanç del meu portamonedes ha desaparegut o consta com a no confirmat!</b><br/> <p><b>Ajuda! El balanç del meu portamonedes ha desaparegut o consta com a no confirmat!</b><br/>
No patiu! Quan envieu fons desde el vostre portamonedes part del balanç apareixerà com a no confirmat de forma temporal. 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. 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 Podeu llegir més sobre el canvi a https://getmonero.org/resources/moneropedia/change.html
<h2>Llista de Transacció</h2> <h2>Llista de Transacció</h2>
<p>Llistat de les transaccions del portamonedes. Els portamonedes de visualització només mostraran les transaccions entrants.</p> <p>Llistat de les transaccions del portamonedes. Els portamonedes de visualització només mostraran les transaccions entrants.</p>
]]></string> ]]></string>
@ -173,49 +173,49 @@
<h1>Nodes</h1> <h1>Nodes</h1>
<h2>TL;DR</h2> <h2>TL;DR</h2>
<p>Actualitzeu la llista de nodes prement cap avall; marqueu 3&#8211;5 nodes per permetre a Monerujo <p>Actualitzeu la llista de nodes prement cap avall; marqueu 3&#8211;5 nodes per permetre a Monerujo
         triar el millor per a tu!</p> triar el millor per a tu!</p>
<h2>Què és un Node?</h2> <h2>Què és un Node?</h2>
<p>Monerujo utilitza un Node Remot (de vegades també anomenat daemon) per comunicar-se <p>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 la xarxa Monero sense haver de descarregar i emmagatzemar una còpia de
         tota la blockchain mateixa.<p> tota la blockchain mateixa.<p>
<h2>Llista de Nodes</h2> <h2>Llista de Nodes</h2>
<p>Si la llista està buida, podeu afegir nous nodes manualment o deixar que Monerujo <p>Si la llista està buida, podeu afegir nous nodes manualment o deixar que Monerujo
         escanegi la xarxa per vostè. O ambdós. Llegiu &#8230;</p> escanegi la xarxa per vostè. O ambdós. Llegiu &#8230;</p>
<p>La llista de nodes mostra tots els nodes coneguts. A més, la marca de temps <p>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 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 representa el temps de resposta del node
         (que indica el nivell de connectivitat estimat) (que indica el nivell de connectivitat estimat)
         es mostra al costat de cada node.</p> es mostra al costat de cada node.</p>
<p>Es pot marcar qualsevol node de la llista per utilitzar-lo més endevant. <p>Es pot marcar qualsevol node de la llista per utilitzar-lo més endevant.
         Es descartaràn els nodes que no hagin estat seleccionats.<p> Es descartaràn els nodes que no hagin estat seleccionats.<p>
<p>Monerujo escollirà el node òptim (marcat) cada vegada que lutilitzeu. <p>Monerujo escollirà el node òptim (marcat) cada vegada que lutilitzeu.
         Això ho fa mitjançant la comprovació de lalçada de bloc (com dactualitzat Això ho fa mitjançant la comprovació de lalçada de bloc (com dactualitzat
         està el node?), així com el temps de resposta (què tan ràpidament respon el node a les peticions?).</p> està el node?), així com el temps de resposta (què tan ràpidament respon el node a les peticions?).</p>
<p>La llista sordena per aquestes característiques, de manera que el node superior seria el que Monerujo <p>La llista sordena 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.</p> triaria ara mateix. La part inferior de la llista mostraria els nodes més lents o no disponibles.</p>
<h2>Afegir Node</h2> <h2>Afegir Node</h2>
<p>Si premeu el botó &quot;Afegir Node&quot; a la part inferior, se us demanarà <p>Si premeu el botó &quot;Afegir Node&quot; a la part inferior, se us demanarà
        que introduïu els detalls del node al següent diàleg. que introduïu els detalls del node al següent diàleg.
        El &quot;Adreça&quot; és el nom del servidor o adreça IP del node - aquesta és la única El &quot;Adreça&quot; és el nom del servidor o adreça IP del node - aquesta és la única
        entrada obligatòria. entrada obligatòria.
        Introduïu el &quot;Port&quot; si el node sexecuta en un port no predeterminat (per exemple, 18089). Introduïu el &quot;Port&quot; si el node sexecuta 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. 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 dusuari i Alguns nodes necessiten credencials per utilitzar-los. Introduïu el nom dusuari i
        contrasenya proporcionats als camps corresponents. Ara podeu &quot;Test&quot; aquesta configuració. contrasenya proporcionats als camps corresponents. Ara podeu &quot;Test&quot; aquesta configuració.
        Els &quot;Resultats de les Proves&quot; mostraran lalçada de bloc, el temps de resposta i lIP real. Els &quot;Resultats de les Proves&quot; mostraran lalçada de bloc, el temps de resposta i lIP real.
        El resultat també pot ser un error - generalment perquè el nom del servidor proporcionat no és El resultat també pot ser un error - generalment perquè el nom del servidor proporcionat no és
        accessible dins dun temps raonable o les credencials són incorrectes. accessible dins dun 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! 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 &quot;Dacord&quot; per desar iamp; Un cop aprovada la prova (sense error), ja estás llest per prémer &quot;Dacord&quot; per desar iamp;
        marcar aquest node.</p> marcar aquest node.</p>
<h2>Escanejar Nodes</h2> <h2>Escanejar Nodes</h2>
<p>A més, podeu escanejar la xarxa per buscar nodes. Monerujo començarà <p>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 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à 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 preguntant-los per als seus companys, etc. Si no teniu cap node marcat
         (o no ens informen sobre els seus companys), (o no ens informen sobre els seus companys),
         Monerujo anirà directament als nodes de llavor de Monero codificats a dins de Monero. Monerujo anirà directament als nodes de llavor de Monero codificats a dins de Monero.
         Lescaneig satura quan troba un total de 10 nodes remots.</p> Lescaneig satura quan troba un total de 10 nodes remots.</p>
]]></string> ]]></string>
<string name="help_uri"><![CDATA[ <string name="help_uri"><![CDATA[
@ -230,4 +230,25 @@
]]></string> ]]></string>
<string name="help_ok">Ja ho tinc!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Ja ho tinc!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -13,7 +13,7 @@
<string name="menu_changepw">Canvi de contrasenya</string> <string name="menu_changepw">Canvi de contrasenya</string>
<string name="password_weak">Segueix escrivint &#8230;</string> <string name="password_weak">Segueix escrivint &#8230;</string>
<string name="password_fair">Més o menys... &#8230;</string> <string name="password_fair">Més o menys</string>
<string name="password_good">Vinga, ho pots fer millor!</string> <string name="password_good">Vinga, ho pots fer millor!</string>
<string name="password_strong">Força bé, pero millorbale &#8230;</string> <string name="password_strong">Força bé, pero millorbale &#8230;</string>
<string name="password_very_strong">Genial, ets tot un hacker!</string> <string name="password_very_strong">Genial, ets tot un hacker!</string>
@ -236,7 +236,7 @@
<string name="send_create_tx_error_title">Error creant la transacció</string> <string name="send_create_tx_error_title">Error creant la transacció</string>
<string name="tx_list_fee">- Comissió %1$s</string> <string name="tx_list_fee">Comissió %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">fallit</string> <string name="tx_list_failed_text">fallit</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -425,5 +425,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -290,4 +290,25 @@
]]></string> ]]></string>
<string name="help_ok">Hab\'s verstanden!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Hab\'s verstanden!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -232,7 +232,7 @@
<string name="send_create_tx_error_title">Fehler bei Transaktionserstellung</string> <string name="send_create_tx_error_title">Fehler bei Transaktionserstellung</string>
<string name="tx_list_fee">- Gebühr %1$s</string> <string name="tx_list_fee">Gebühr %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">fehlgeschlagen</string> <string name="tx_list_failed_text">fehlgeschlagen</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -426,5 +426,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -272,4 +272,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -205,7 +205,7 @@
<string name="send_create_tx_error_title">Σφάλμα Δημιουργίας Συναλλαγής</string> <string name="send_create_tx_error_title">Σφάλμα Δημιουργίας Συναλλαγής</string>
<string name="tx_list_fee">- Κόμιστρο %1$s</string> <string name="tx_list_fee">Κόμιστρο %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">απέτυχε</string> <string name="tx_list_failed_text">απέτυχε</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -427,5 +427,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -45,7 +45,7 @@
]]></string> ]]></string>
<string name="help_create_keys"><![CDATA[ <string name="help_create_keys"><![CDATA[
<h1>Krei monujon - Ŝlosiloj</h1> <h1>Krei monujon - Ŝlosiloj</h1>
<p>Se vi restaŭras vian monujon per viaj ŝlosiloj!</p> <p>Se vi restaŭras vian monujon per viaj ŝlosiloj!</p>
<p>Entajpu unikan monujnomon kaj pasvorton. <p>Entajpu unikan monujnomon kaj pasvorton.
@ -316,4 +316,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -236,7 +236,7 @@
<string name="send_create_tx_error_title">Krei transakci-eraron</string> <string name="send_create_tx_error_title">Krei transakci-eraron</string>
<string name="tx_list_fee">- Kosto %1$s</string> <string name="tx_list_fee">Kosto %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">masukcesis</string> <string name="tx_list_failed_text">masukcesis</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -427,5 +427,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -312,4 +312,25 @@
]]></string> ]]></string>
<string name="help_ok">¡Entendido!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">¡Entendido!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -173,7 +173,7 @@
<string name="send_create_tx_error_title">Error creando la transacción</string> <string name="send_create_tx_error_title">Error creando la transacción</string>
<string name="tx_list_fee">- Comisión %1$s</string> <string name="tx_list_fee">Comisión %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">fallido</string> <string name="tx_list_failed_text">fallido</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -418,5 +418,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -292,4 +292,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -231,7 +231,7 @@
<string name="send_create_tx_error_title">Viga ülekande genereerimisel</string> <string name="send_create_tx_error_title">Viga ülekande genereerimisel</string>
<string name="tx_list_fee">- teenustasu %1$s</string> <string name="tx_list_fee">teenustasu %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">ebaõnnestus</string> <string name="tx_list_failed_text">ebaõnnestus</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -425,5 +425,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -310,4 +310,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -233,7 +233,7 @@
<string name="send_create_tx_error_title">Erreur de Création de Transaction</string> <string name="send_create_tx_error_title">Erreur de Création de Transaction</string>
<string name="tx_list_fee">- Frais %1$s</string> <string name="tx_list_fee">Frais %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">Echoué</string> <string name="tx_list_failed_text">Echoué</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -431,5 +431,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -294,4 +294,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -230,7 +230,7 @@
<string name="send_create_tx_error_title">Tranzakciólétrehozási hiba</string> <string name="send_create_tx_error_title">Tranzakciólétrehozási hiba</string>
<string name="tx_list_fee">- %1$s díj</string> <string name="tx_list_fee">%1$s díj</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">sikertelen</string> <string name="tx_list_failed_text">sikertelen</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -429,5 +429,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -295,4 +295,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -232,7 +232,7 @@
<string name="send_create_tx_error_title">Errore nella creazione della transazione</string> <string name="send_create_tx_error_title">Errore nella creazione della transazione</string>
<string name="tx_list_fee">- Commissione %1$s</string> <string name="tx_list_fee">Commissione %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">fallita</string> <string name="tx_list_failed_text">fallita</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -431,4 +431,9 @@
<string name="menu_deletecache">Resetta portafogli!</string> <string name="menu_deletecache">Resetta portafogli!</string>
<string name="deletecache_alert_message">Il reset del portafogli cancellerà tutte le informazioni locali (note, nomi di account &amp; sottoindirizzi, chiavi di transazione private, ...)! Procedi solo se il portafogli è corrotto e non si carica!</string> <string name="deletecache_alert_message">Il reset del portafogli cancellerà tutte le informazioni locali (note, nomi di account &amp; sottoindirizzi, chiavi di transazione private, ...)! Procedi solo se il portafogli è corrotto e non si carica!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -423,4 +423,25 @@
]]></string> ]]></string>
<string name="help_ok">分かりました!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">分かりました!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -236,7 +236,7 @@
<string name="send_create_tx_error_title">取引作成エラー</string> <string name="send_create_tx_error_title">取引作成エラー</string>
<string name="tx_list_fee">- 手数料 %1$s</string> <string name="tx_list_fee">手数料 %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">失敗</string> <string name="tx_list_failed_text">失敗</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -430,5 +430,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -292,4 +292,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -230,7 +230,7 @@
<string name="send_create_tx_error_title">Error med å lage transaksjon</string> <string name="send_create_tx_error_title">Error med å lage transaksjon</string>
<string name="tx_list_fee">- Avgift %1$s</string> <string name="tx_list_fee">Avgift %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">feila</string> <string name="tx_list_failed_text">feila</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -427,5 +427,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -29,7 +29,6 @@
<style name="AppCard" parent="Widget.MaterialComponents.CardView"> <style name="AppCard" parent="Widget.MaterialComponents.CardView">
<item name="cardElevation">0dp</item> <item name="cardElevation">0dp</item>
<item name="cardCornerRadius">1dp</item>
</style> </style>
</resources> </resources>

View File

@ -230,4 +230,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -227,7 +227,7 @@
<string name="send_create_tx_error_title">Fout bij transactie maken</string> <string name="send_create_tx_error_title">Fout bij transactie maken</string>
<string name="tx_list_fee">- kosten %1$s</string> <string name="tx_list_fee">kosten %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">mislukt</string> <string name="tx_list_failed_text">mislukt</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -427,5 +427,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -291,4 +291,25 @@
]]></string> ]]></string>
<string name="help_ok">Entendi!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Entendi!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -229,7 +229,7 @@
<string name="send_create_tx_error_title">Erro ao criar a transação</string> <string name="send_create_tx_error_title">Erro ao criar a transação</string>
<string name="tx_list_fee">- taxa de %1$s</string> <string name="tx_list_fee">taxa de %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">falhou</string> <string name="tx_list_failed_text">falhou</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -421,4 +421,9 @@ aqui.</string>
<string name="menu_deletecache">Resetar carteira!</string> <string name="menu_deletecache">Resetar carteira!</string>
<string name="deletecache_alert_message">Esta carteira será resetada, perdendo todos os dados "off-chain" (como notas, contas &amp; nomes de subendereços, chaves de transações privadas, ...)! Use isso SOMENTE se esta carteira estiver corrompida e não carrega!</string> <string name="deletecache_alert_message">Esta carteira será resetada, perdendo todos os dados "off-chain" (como notas, contas &amp; nomes de subendereços, chaves de transações privadas, ...)! Use isso SOMENTE se esta carteira estiver corrompida e não carrega!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -291,4 +291,25 @@
]]></string> ]]></string>
<string name="help_ok">Entendido!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Entendido!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -229,7 +229,7 @@
<string name="send_create_tx_error_title">Erro ao criar a transacção</string> <string name="send_create_tx_error_title">Erro ao criar a transacção</string>
<string name="tx_list_fee">- Taxa %1$s</string> <string name="tx_list_fee">Taxa %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">falhou</string> <string name="tx_list_failed_text">falhou</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -431,5 +431,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -298,4 +298,25 @@
]]></string> ]]></string>
<string name="help_ok">Am înțeles!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Am înțeles!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -205,7 +205,7 @@
<string name="send_create_tx_error_title">Eroare creare tranzacție</string> <string name="send_create_tx_error_title">Eroare creare tranzacție</string>
<string name="tx_list_fee">- Comision %1$s</string> <string name="tx_list_fee">Comision %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">eșuat</string> <string name="tx_list_failed_text">eșuat</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -427,5 +427,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -297,4 +297,25 @@
]]></string> ]]></string>
<string name="help_ok">Я понял!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Я понял!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -231,7 +231,7 @@
<string name="send_create_tx_error_title">Ошибка создания транзакции</string> <string name="send_create_tx_error_title">Ошибка создания транзакции</string>
<string name="tx_list_fee">- Комиссия %1$s</string> <string name="tx_list_fee">Комиссия %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">Не удалось</string> <string name="tx_list_failed_text">Не удалось</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -431,5 +431,10 @@
<string name="restore_failed">Ошибка импорта!</string> <string name="restore_failed">Ошибка импорта!</string>
<string name="menu_deletecache">Сбросить кошелек</string> <string name="menu_deletecache">Сбросить кошелек</string>
<string name="deletecache_alert_message">Этот кошелек будет сброшен, вы потеряете все данные, которые не находятся в блокчейне (например примечания, имена подадресов, приватные ключи транзакций, ...)! Используйте это ТОЛЬКО если ваш кошелек поврежден и не загружается!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -1,52 +1,52 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="about_close">Zatvoriť</string> <string name="about_close">Zatvoriť</string>
<string name="about_whoami">ja som monerujo</string> <string name="about_whoami">ja som monerujo</string>
<string name="about_version">Verzia %1$s (%2$d)</string> <string name="about_version">Verzia %1$s (%2$d)</string>
<string name="credits_text"><![CDATA[ <string name="credits_text"><![CDATA[
<b>Zásluhy</b> <b>Zásluhy</b>
<br/> <br/>
m2049r, baltsar777, anhdres, keejef, m2049r, baltsar777, anhdres, keejef,
rehrar, EarlOfEgo et al. rehrar, EarlOfEgo et al.
<br/><br/> <br/><br/>
<a href="https://monerujo.io/">monerujo.io</a> <a href="https://monerujo.io/">monerujo.io</a>
]]></string> ]]></string>
<string name="privacy_policy"><![CDATA[ <string name="privacy_policy"><![CDATA[
<h1>Zásady ochrany osobných údajov</h1> <h1>Zásady ochrany osobných údajov</h1>
<p>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, <p>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). ktoré získame od užívateľov našej apky (monerujo: Monero Wallet).
</p> </p>
<p>Používaním tejto aplikácie súhlasíš so zbieraním a spracovávaním informácií v súlade s týmito pravidlami. <p>Používaním tejto aplikácie súhlasíš so zbieraním a spracovávaním informácií v súlade s týmito pravidlami.
</p> </p>
<h2>Zbierané Dáta</h2> <h2>Zbierané Dáta</h2>
<p>Osobné dáta sú také dáta, na základe ktorých by bolo možné identifikovať jedinca.</p> <p>Osobné dáta sú také dáta, na základe ktorých by bolo možné identifikovať jedinca.</p>
<p>Monero kľúče a verejné adresy sú zbierané a spracovávané aplikáciou lokálne na účely <p>Monero kľúče a verejné adresy sú zbierané a spracovávané aplikáciou lokálne na účely
spracovania a prenosu transakcie v Monero sieti.</p> spracovania a prenosu transakcie v Monero sieti.</p>
<p>Iné osobné data nie sú zbierané a spracovávané.</p> <p>Iné osobné data nie sú zbierané a spracovávané.</p>
<p>Pokiaľ používaš (voliteľnú) funkciu zmenárne, monerujo vyhľadá výmenný kurz cez verejné API portálu coinmarketcap.com. <p>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ú</p> Pre viac detailov pozri zásady ochrany osobných údajov na https://coinmarketcap.com/privacy kde je uvedené aké dáta zbierajú</p>
<p>Pokiaľ používaš aplikáciu pre platby na BTC adresy, využívaš služby SideShift.ai. <p>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 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ť. </p> addresu príjemcu a posielané množstvo. Tvoju IP bude tiež možné zaznamenať. </p>
<h2>Povolenia</h2> <h2>Povolenia</h2>
<ul> <ul>
<li>INTERNET : Pripojiť do Monero siete cez vzdialený Monero uzol</li> <li>INTERNET : Pripojiť do Monero siete cez vzdialený Monero uzol</li>
<li>READ_EXTERNAL_STORAGE : Čítať súbory peňaženky uložené v zariadení</li> <li>READ_EXTERNAL_STORAGE : Čítať súbory peňaženky uložené v zariadení</li>
<li>WRITE_EXTERNAL_STORAGE : Zapisovať do súborov peňaženky uložených v zariadení</li> <li>WRITE_EXTERNAL_STORAGE : Zapisovať do súborov peňaženky uložených v zariadení</li>
<li>WAKE_LOCK : Udržať zariadenie prebudené počas synchronizácie</li> <li>WAKE_LOCK : Udržať zariadenie prebudené počas synchronizácie</li>
<li>CAMERA : Snímať QR kódy na posielanie a obdržanie Monero</li> <li>CAMERA : Snímať QR kódy na posielanie a obdržanie Monero</li>
</ul> </ul>
<h2>Zmeny v týchto zásadách</h2> <h2>Zmeny v týchto zásadách</h2>
<p>Je možné, že z času načas sa tieto zásady upravia, či doplnia, na čo budete včas upozornení aplikáciou <p>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). 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. Doporučujeme tieto zásady periodicky kontrolovať kôli prípadným zmenám.
<p>tieto zásady ochrany údajov boli naposledy upravené: 10. November, 2017. <p>tieto zásady ochrany údajov boli naposledy upravené: 10. November, 2017.
</p> </p>
<h2>Kontaktuj Nás</h2> <h2>Kontaktuj Nás</h2>
<p>Ak máš akékoľvek otázky ohľadom zásad ochrany osobných údajov, alebo ako sú data spracovávané, <p>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. pošli email na privacy@monerujo.io.
</p> </p>
]]></string> ]]></string>
</resources> </resources>

View File

@ -1,262 +1,283 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="help_create_new"><![CDATA[ <string name="help_create_new"><![CDATA[
<h1>Vytvoriť Peňaženku - Novú</h1> <h1>Vytvoriť Peňaženku - Novú</h1>
<p>Ak Ti treba novú Monero adresu!</p> <p>Ak Ti treba novú Monero adresu!</p>
<p>Vlož unikátny názov a heslo peňaženky. <p>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í. 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.</p> Používaj silné heslo - alebo ešte lepšie je použiť frázu.</p>
<h2>Zapíš si mnemotechnický Seed!</h2> <h2>Zapíš si mnemotechnický Seed!</h2>
<p>Na nasledujúcej obrazovke uvidíš svoj 25-slovný \"Mnemotechnický Seed\". <p>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. 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 <em>hocikto</em> môže získať kontrolu nad vašimi XMR!</p> Bezpečné uloženie a utajenie týchto dát je veľmi dôležité, keďže pomocou nich <em>hocikto</em> môže získať kontrolu nad vašimi XMR!</p>
<p>Ak stratíš heslo do peňaženky, ešte stále si môžeš obnoviť peňaženku so svojím mnemotechnickým Seedom.</p> <p>Ak stratíš heslo do peňaženky, ešte stále si môžeš obnoviť peňaženku so svojím mnemotechnickým Seedom.</p>
<p>Ak stratíš mnemotechnický Seed, neexistuje spôsob ako ho odvodiť a všetky Tvoje mince sú navždy stratené! <p>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). 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 <em>niekoľko</em> bezpečných a utajených miest.</p> Preto je najlepšie ak si svoj Seed zálohuješ zapísaním na papier a uložíš na <em>niekoľko</em> bezpečných a utajených miest.</p>
]]></string> ]]></string>
<string name="help_create_seed"><![CDATA[ <string name="help_create_seed"><![CDATA[
<h1>Vytvoriť Peňaženku - Seed</h1> <h1>Vytvoriť Peňaženku - Seed</h1>
<p>Ak už máš Monero adresu a chceš obnoviť transakcie z blockchain!</p> <p>Ak už máš Monero adresu a chceš obnoviť transakcie z blockchain!</p>
<p>Vlož unikátny názov a heslo peňaženky. <p>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í. 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.</p> Používaj silné heslo - alebo ešte lepšie je použiť frázu.</p>
<p>Vlož svoj Seed do políčka \"Mnemotechnický Seed\".<p> <p>Vlož svoj Seed do políčka \"Mnemotechnický Seed\".<p>
<p>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ť <em>celú</em> blockchain, <p>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ť <em>celú</em> blockchain,
aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať <em>veľmi</em> dlho.</p> aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať <em>veľmi</em> dlho.</p>
]]></string> ]]></string>
<string name="help_create_keys"><![CDATA[ <string name="help_create_keys"><![CDATA[
<h1>Vytvoriť Peňaženku - Kľúče</h1> <h1>Vytvoriť Peňaženku - Kľúče</h1>
<p>Ak obnovuješ svoju peňaženku pomocou kľúčov!</p> <p>Ak obnovuješ svoju peňaženku pomocou kľúčov!</p>
<p>Vlož unikátny názov a heslo peňaženky. <p>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í. 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.<p> Používaj silné heslo - alebo ešte lepšie je použiť frázu.<p>
<p>Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\" and \"Platobný Kľúč\".</p> <p>Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\" and \"Platobný Kľúč\".</p>
<p>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ť <em>celú</em> blockchain, <p>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ť <em>celú</em> blockchain,
aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať <em>veľmi</em> dlho.</p> aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať <em>veľmi</em> dlho.</p>
<p>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. <p>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 <em>pred</em> tým ako si prvýkrát použil danú adresu.</p> Ak to nevieš naisto, vlož približný dátum/číslo bloku <em>pred</em> tým ako si prvýkrát použil danú adresu.</p>
]]></string> ]]></string>
<string name="help_create_ledger"><![CDATA[ <string name="help_create_ledger"><![CDATA[
<h1>Vytvoriť Peňaženku - Ledger</h1> <h1>Vytvoriť Peňaženku - Ledger</h1>
<p>Obnovenie peňaženky zo zariadenia Ledger Nano S.</p> <p>Obnovenie peňaženky zo zariadenia Ledger Nano S.</p>
<p>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.</p> <p>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.</p>
<p>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í. <p>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.<p> Používaj silné heslo - alebo ešte lepšie je použiť frázu.<p>
<p>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. <p>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 <em>pred</em> tým ako si prvýkrát použil danú adresu. Urýchli to prehľadávanie blockchain.</p> Ak to nevieš presne, vlož približný dátum/číslo bloku <em>pred</em> tým ako si prvýkrát použil danú adresu. Urýchli to prehľadávanie blockchain.</p>
]]></string> ]]></string>
<string name="help_create_view"><![CDATA[ <string name="help_create_view"><![CDATA[
<h1>Vytvoriť Peňaženku - Prezeracia Peňaženka</h1> <h1>Vytvoriť Peňaženku - Prezeracia Peňaženka</h1>
<p>Ak chceš iba sledovať prichádzajúce transakcie!</p> <p>Ak chceš iba sledovať prichádzajúce transakcie!</p>
<p>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í. <p>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.<p> Používaj silné heslo - alebo ešte lepšie je použiť frázu.<p>
<p>Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\".</p> <p>Vlož svoju Monero adresu do poľa \"Verejná Adresa\" a vyplň \"Prezerací Kľúč\".</p>
<p>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. <p>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 <em>pred</em> tým ako si prvýkrát použil danú adresu. Ak to nevieš naisto, vlož približný dátum/číslo bloku <em>pred</em> tým ako si prvýkrát použil danú adresu.
Zanechaním prázdneho poľa budeš skenovať <em>celú</em> blockchain, aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať <em>veľmi</em> dlho.</p> Zanechaním prázdneho poľa budeš skenovať <em>celú</em> blockchain, aby si našiel transakcie prislúchajúce tejto adrese. To môže trvať <em>veľmi</em> dlho.</p>
]]></string> ]]></string>
<string name="help_details"><![CDATA[ <string name="help_details"><![CDATA[
<h1>Detaily Peňaženky</h1> <h1>Detaily Peňaženky</h1>
<h2>Verejná Adresa</h2> <h2>Verejná Adresa</h2>
Vaša verejná adresa je niečo ako číslo bakového účtu, ktoré môžte zdieľať bez toho aby ste sa báli, 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. že prídete o svoje Monero. Ľudia vám budú posielať Monero práve na túto adresu.
<h2>Mnemotechnický Seed</h2> <h2>Mnemotechnický Seed</h2>
Tieto dáta sú potrebné len na obnovu peňaženky a získanie plného prístupu k vašim prostriedkom. 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 <em>hocikto</em> môže získať kontrolu nad vašimi XMR! Bezpečné uloženie a utajenie týchto dát je veľmi dôležité, keďže pomocou nich <em>hocikto</em> 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! Ak to ešte nemáš zapísané a uložené niekde na bezpečnom mieste, urob tak čo najskôr!
<h2>Heslo pre súbory peňaženky</h2> <h2>Heslo pre súbory peňaženky</h2>
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. 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.
<br/> <br/>
<h3>CrAzYpass</h3> <h3>CrAzYpass</h3>
Pokiaľ tu zobrazené heslo tvorí 52 alfanumerických znakov v skupinách po 4 - gratulujem! 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. 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!<br/> Extrémne to zťažuje hacknutie týchto súborov!<br/>
Táto funkcia je povinná pre všetky novo-vytvorené peňaženky. Táto funkcia je povinná pre všetky novo-vytvorené peňaženky.
<h3>Legacy Password</h3> <h3>Legacy Password</h3>
Ak vidíš svoju prístupovú frázu na tomto mieste, Tvoja peňaženka nie je zabezpečená tak, 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. 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 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 a zabezpečí s ním súbory peňaženky. Zapísať!
<h3>CrAzYpass peňaženky</h3> <h3>CrAzYpass peňaženky</h3>
Ak budeš potrebovať niekedy preinštalovať Monerujo (napríklad po resetovaní telefónu alebo pri výmene za iný), 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ť 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.<br/> použiť toto heslo pre obnovu na opätovný prístup do svojej peňaženky.<br/>
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. 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ť! Zapísať!
<h2>Prezerací Kľúč</h2> <h2>Prezerací Kľúč</h2>
Tvoj prezerací kľúč (view key) môžeš používať na sledovanie prichádzajúcich transakcií do peňaženky, 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. zatiaľ čo míňať prostriedky tento prezerací kľúč neumožňuje.
<h2>Platobný Kľúč</h2> <h2>Platobný Kľúč</h2>
Platobný Kľúč (spend key) umožňuje míňať Monero prislúchajúce danej peňaženke, 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. takže ho nikomu nepredrádzaj a uchovaj rovnako bezpečne ako svoj mnemotechnický seed.
]]></string> ]]></string>
<string name="help_list"><![CDATA[ <string name="help_list"><![CDATA[
<h1>Zoznam Peňaženiek</h1> <h1>Zoznam Peňaženiek</h1>
<h2>Uzol</h2> <h2>Uzol</h2>
<p>Monerujo používa vzdialené uzly na komunikáciu so sieťou Monero. Nie je tak potrebné sťahovať <p>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 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/<p> https://moneroworld.com/<p>
<p>Monerujo prichádza s niekoľkými prednastavenými uzlami. Pamätá si posledných 5 použitých uzlov.</p> <p>Monerujo prichádza s niekoľkými prednastavenými uzlami. Pamätá si posledných 5 použitých uzlov.</p>
<h2>Peňaženky</h2> <h2>Peňaženky</h2>
<p>Tu vidíš svoje peňaženky. Sú umiestnené v adresári <tt>monerujo</tt> na internom úložisku Tvojho zariadenia. <p>Tu vidíš svoje peňaženky. Sú umiestnené v adresári <tt>monerujo</tt> na internom úložisku Tvojho zariadenia.
Môžeš použiť súborový manažér telefónu na ich vyhľadanuie a zobrazenie. 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.</p> Mal by si robiť pravidelné zálohy týchto adresárov a umiestniť ich mimo zariadenie pre prípad straty, či poškodenia.</p>
<p>Označ Peňaženku alebo stlač \"+\" pre vytvorenie novej. <p>Označ Peňaženku alebo stlač \"+\" pre vytvorenie novej.
Alebo označ jednu z možností:</p> Alebo označ jednu z možností:</p>
<h3>Detaily</h3> <h3>Detaily</h3>
<p>ukáže detaily peňaženky, seed &amp; kľúče.</p> <p>ukáže detaily peňaženky, seed &amp; kľúče.</p>
<h3>Prijať</h3> <h3>Prijať</h3>
<p>Vytvorí QR kód na prijímanie Moneroj.</p> <p>Vytvorí QR kód na prijímanie Moneroj.</p>
<h3>Premenuj</h3> <h3>Premenuj</h3>
<p>Premenuje peňaženku. Zálohy nie sú premenované.</p> <p>Premenuje peňaženku. Zálohy nie sú premenované.</p>
<h3>Záloha</h3> <h3>Záloha</h3>
<p>Vytvorí kópiu peňaženky v adresári <tt>backups</tt> vnútri <tt>monerujo</tt> <p>Vytvorí kópiu peňaženky v adresári <tt>backups</tt> vnútri <tt>monerujo</tt>
prepísaním predchádzajúcich kópií.</p> prepísaním predchádzajúcich kópií.</p>
<h3>Archivovať</h3> <h3>Archivovať</h3>
<p>Vytvorí zálohu s následným zmazaním peňaženky. Kópia zostáva v adresári <tt>backups</tt> <p>Vytvorí zálohu s následným zmazaním peňaženky. Kópia zostáva v adresári <tt>backups</tt>
Pokiaľ už nepotrebuješ zálohy, mal by si ich vymazať zo svojho telefónu pomocou súborového manažéra, 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. alebo inej aplikácie na bezpečné mazanie.
</p> </p>
]]></string> ]]></string>
<string name="help_tx_details"><![CDATA[ <string name="help_tx_details"><![CDATA[
<h1>Detaily Transakcie</h1> <h1>Detaily Transakcie</h1>
<h2>Destinácia</h2> <h2>Destinácia</h2>
Toto je verejná adresa peňaženky kde chceš poslať Monero. Toto je verejná adresa peňaženky kde chceš poslať Monero.
<h2>ID Platby</h2> <h2>ID Platby</h2>
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. 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. 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.
<h2>TX ID</h2> <h2>TX ID</h2>
Toto je ID transakcie, ktoré slúži na identifikáciu transakcie v Monero blockchain exploreri, ako napr. <a href="https://xmrchain.net/">https://xmrchain.net/</a> Toto je ID transakcie, ktoré slúži na identifikáciu transakcie v Monero blockchain exploreri, ako napr. <a href="https://xmrchain.net/">https://xmrchain.net/</a>
<h2>TX KĽÚČ (Transaction Key)</h2> <h2>TX KĽÚČ (Transaction Key)</h2>
Toto je Tvoj súkromný kľúč transakcie, uchovaj ho bezpečne a neposkytuj ho tretím stranám, 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ú. aby nemohli identifikovať tvoj podpis v kruhovom podpise a spraviť tak transakciu verejnú a transparentnú.
<h2>Blok</h2> <h2>Blok</h2>
Blok do ktorého je zaradená vaša transakcia. Blok do ktorého je zaradená vaša transakcia.
]]></string> ]]></string>
<string name="help_send"><![CDATA[ <string name="help_send"><![CDATA[
<h1>Poslať</h1> <h1>Poslať</h1>
<h2>Adresa Príjemcu</h2> <h2>Adresa Príjemcu</h2>
<p>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. <p>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.</p> Trikrát sa uisti, že neposielaš mince na zlú adresu.</p>
<p>Okrem XMR adries, môžte použiť tiež <p>Okrem XMR adries, môžte použiť tiež
<ul> <ul>
<li>OpenAlias pre XMR či BTC</li> <li>OpenAlias pre XMR či BTC</li>
<li>BTC adresu</li> <li>BTC adresu</li>
</u> </u>
Nezabúdajte, že posielanie BTC prebieha cez službu SideShift.ai (detaily na https://sideshift.ai). Pozri sekciu nižšie o posielaní BTC</p> Nezabúdajte, že posielanie BTC prebieha cez službu SideShift.ai (detaily na https://sideshift.ai). Pozri sekciu nižšie o posielaní BTC</p>
<h1>Posielanie BTC</h1> <h1>Posielanie BTC</h1>
<h2>SideShift.ai</h2> <h2>SideShift.ai</h2>
<p>SideShift.ai je služba tretej strany, ktorá umožňuje zámenu z Monero na Bitcoin. <p>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 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ť. 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.</p> 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.</p>
<h2>SideShift.ai Výmenný Kurz<h2> <h2>SideShift.ai Výmenný Kurz<h2>
<p>Na obrazovke \"Množstvo\" uvidíš aktuálne parametre služby SideShift.ai, vrátane aktuálneho kurzu BTC, hornej a dolnej hranice. <p>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ý.</p> Podotýkame, že tento kurz nie je garantovaný.</p>
<h2>SideShift.ai Objednávka<h2> <h2>SideShift.ai Objednávka<h2>
<p>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úť\". <p>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.</p> Výmenný kurz sa môže líšiť od toho, ktorý bol na predošlých obrazovkách.</p>
<h2>SideShift.ai Tajný Kľúč<h2> <h2>SideShift.ai Tajný Kľúč<h2>
<p>Keďže Monerujo dbá len na tú časť transakcie, ktorá pracuje s Monero, <p>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 tento SideShift.ai Tajný Kľúč sa môže využívať na sledovanie Bitcoinovej časti transakcie a objednávky
na domovskej stránke SideShift.ai</p> na domovskej stránke SideShift.ai</p>
<h2>SideShift.ai Odpočítavanie!</h2> <h2>SideShift.ai Odpočítavanie!</h2>
<p>Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .</p> <p>Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .</p>
]]></string> ]]></string>
<string name="help_xmrto"><![CDATA[ <string name="help_xmrto"><![CDATA[
<h1>Posielanie BTC</h1> <h1>Posielanie BTC</h1>
<h2>SideShift.ai</h2> <h2>SideShift.ai</h2>
<p>SideShift.ai je služba tretej strany, ktorá umožňuje zámenu z Monero na Bitcoin. <p>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 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ť. 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.</p> 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.</p>
<h2>SideShift.ai Výmenný Kurz<h2> <h2>SideShift.ai Výmenný Kurz<h2>
<p>Na obrazovke \"Množstvo\" uvidíš aktuálne parametre služby SideShift.ai, vrátane aktuálneho kurzu BTC, hornej a dolnej hranice. <p>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ý.</p> Podotýkame, že tento kurz nie je garantovaný.</p>
<h2>SideShift.ai Objednávka<h2> <h2>SideShift.ai Objednávka<h2>
<p>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úť\". <p>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.</p> Výmenný kurz sa môže líšiť od toho, ktorý bol na predošlých obrazovkách.</p>
<h2>SideShift.ai Tajný Kľúč<h2> <h2>SideShift.ai Tajný Kľúč<h2>
<p>Keďže Monerujo dbá len na tú časť transakcie, ktorá pracuje s Monero, <p>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 tento SideShift.ai Tajný Kľúč sa môže využívať na sledovanie Bitcoinovej časti transakcie a objednávky
na domovskej stránke SideShift.ai</p> na domovskej stránke SideShift.ai</p>
<h2>SideShift.ai Odpočítavanie!</h2> <h2>SideShift.ai Odpočítavanie!</h2>
<p>Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .</p> <p>Akonáhle odpočítavanie dosiahne nulu, budeš potrebovať nový kľúč z SideShift.ai návratom na predchádzajúci krok a obrazovku \"Potvrdiť\" .</p>
]]></string> ]]></string>
<string name="help_wallet"><![CDATA[ <string name="help_wallet"><![CDATA[
<h1>Peňaženka</h1> <h1>Peňaženka</h1>
<h2>Mód Ulica</h2> <h2>Mód Ulica</h2>
<p>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, <p>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é, 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.</p> aby ste mohli vidieť či vám odoslalo a dorazilo všetko správne.</p>
<h2>Skenovanie</h2> <h2>Skenovanie</h2>
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á. 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. 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.
<h2>Zostatok</h2> <h2>Zostatok</h2>
<p><b>Pomóc! Zostatok v mojej peňaženke zmizol, alebo je nepotvrdený!</b><br/> <p><b>Pomóc! Zostatok v mojej peňaženke zmizol, alebo je nepotvrdený!</b><br/>
Nestresuj! Keď odosielaš prostriedky zo svojej peňaženky, časť zostatku sa dočasne ukáže ako 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. 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 Viac o zmenách sa dočítaš (anglicky) na https://getmonero.org/resources/moneropedia/change.html
<h2>Zoznam Transakcií</h2> <h2>Zoznam Transakcií</h2>
<p>Zoznam transakcií v peňaženke. V prípade prezeracej peňaženky budú zobrazené iba prichádzajúce transakcie.</p> <p>Zoznam transakcií v peňaženke. V prípade prezeracej peňaženky budú zobrazené iba prichádzajúce transakcie.</p>
]]></string> ]]></string>
<string name="help_node"><![CDATA[ <string name="help_node"><![CDATA[
<h1>Uzly</h1> <h1>Uzly</h1>
<h2>TL;DR</h2> <h2>TL;DR</h2>
<p>Aktuálny zoznam uzlov získaš tak, že potiahneš a pridáš do záložiek 5 uzlov, z ktorých si Monerujo jeden vyberie.</p> <p>Aktuálny zoznam uzlov získaš tak, že potiahneš a pridáš do záložiek 5 uzlov, z ktorých si Monerujo jeden vyberie.</p>
<h2>Čo je Uzol?</h2> <h2>Čo je Uzol?</h2>
<p>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.<p> <p>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.<p>
<h2>Zoznam Uzlov</h2> <h2>Zoznam Uzlov</h2>
<p>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&#8230;</p> <p>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&#8230;</p>
<p>Zoznam uzlov zobrazuje všetky momentálne známe uzly. Pod každým uzlom je zobrazená časová pečiatka jeho posledného bloku. <p>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.</p> Vedľa je ikonka nodu, ktorá indikuje úroveň pripojenia.</p>
<p>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žú.<p> <p>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žú.<p>
<p>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.</p> <p>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.</p>
<p>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.</p> <p>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.</p>
<h2>Pridať Uzol</h2> <h2>Pridať Uzol</h2>
<p>Dotykom na tlačítko &quot;Pridať Uzol&quot; vložíte detaily vlastného uzla. <p>Dotykom na tlačítko &quot;Pridať Uzol&quot; vložíte detaily vlastného uzla.
&quot;Adresa&quot; je hostname alebo IP-adresa uzla. Je to jediné povinné pole. &quot;Adresa&quot; je hostname alebo IP-adresa uzla. Je to jediné povinné pole.
&quot;Port&quot; ak uzol používa iný ako predvolený port (napr. 18089). &quot;Port&quot; 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é. 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í. 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í. &quot;Test&quot; To by malo stačiť na testovanie týchto nastavení. &quot;Test&quot;
&quot;Výsledky Testu&quot; zobrazia výšku, čas odozvy a aktuálnu IP adresu uzla. &quot;Výsledky Testu&quot; 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. 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! 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 &quot;OK&quot; a ulož si daný uzol.</p> Akonáhle test skončí úspešne (žiadna chyba sa neobjaví) - klepni na &quot;OK&quot; a ulož si daný uzol.</p>
<h2>Vyhľadať Uzol</h2> <h2>Vyhľadať Uzol</h2>
<p>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. <p>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ď. 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.</p> 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.</p>
]]></string> ]]></string>
<string name="help_uri"><![CDATA[ <string name="help_uri"><![CDATA[
<h1>Používanie platobného linku</h1> <h1>Používanie platobného linku</h1>
<p>Monerujo je spustené z platobného linku. Ak chceš posielať prostriedky, postupuj nasledovne:</p> <p>Monerujo je spustené z platobného linku. Ak chceš posielať prostriedky, postupuj nasledovne:</p>
<p> <p>
1. Otvor peňaženku z ktorej chceš platiť<br> 1. Otvor peňaženku z ktorej chceš platiť<br>
2. Počkaj kým sa peňaženka zosynchronizuje a zobrazí sa tlačítko "Poslať" <br> 2. Počkaj kým sa peňaženka zosynchronizuje a zobrazí sa tlačítko "Poslať" <br>
3. Stlač tlačidlo "Poslať" 3. Stlač tlačidlo "Poslať"
</p> </p>
<p>Detaily platby budú vložené automaticky. Skontroluj ich a pokračuj ako obvykle pri ostatných transakciách.</p> <p>Detaily platby budú vložené automaticky. Skontroluj ich a pokračuj ako obvykle pri ostatných transakciách.</p>
]]></string> ]]></string>
<string name="help_ok">Rozumiem!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Rozumiem!</string> <!-- Note: "Got it" as in "I understand this" -->
</resources>
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources>

View File

@ -228,7 +228,7 @@
<string name="send_create_tx_error_title">Vytvor Chybu Transakcie</string> <string name="send_create_tx_error_title">Vytvor Chybu Transakcie</string>
<string name="tx_list_fee">- poplatok %1$s</string> <string name="tx_list_fee">poplatok %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">zlyhala</string> <string name="tx_list_failed_text">zlyhala</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -428,5 +428,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -290,4 +290,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -237,7 +237,7 @@
<string name="send_create_tx_error_title">Kreiraj transakcijsku grešku</string> <string name="send_create_tx_error_title">Kreiraj transakcijsku grešku</string>
<string name="tx_list_fee">- naknada %1$s</string> <string name="tx_list_fee">naknada %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">neuspelo</string> <string name="tx_list_failed_text">neuspelo</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -426,5 +426,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -279,4 +279,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -218,7 +218,7 @@
<string name="send_create_tx_error_title">Ett fel uppstod när transaktion skapades</string> <string name="send_create_tx_error_title">Ett fel uppstod när transaktion skapades</string>
<string name="tx_list_fee">- Avgift %1$s</string> <string name="tx_list_fee">Avgift %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">misslyckades</string> <string name="tx_list_failed_text">misslyckades</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -419,5 +419,10 @@
<string name="restore_failed">Importeringen misslyckad!</string> <string name="restore_failed">Importeringen misslyckad!</string>
<string name="menu_deletecache">Återställ plånbok!</string> <string name="menu_deletecache">Återställ plånbok!</string>
<string name="deletecache_alert_message">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!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -4,18 +4,18 @@
<h1>Створити гаманець - Новий</h1> <h1>Створити гаманець - Новий</h1>
<p>Якщо вам потрібна нова адреса Monero!</p> <p>Якщо вам потрібна нова адреса Monero!</p>
<p>Введіть унікальне і\'мя та пароль гаманця. <p>Введіть унікальне і\'мя та пароль гаманця.
        Пароль використовується для захисту даних вашого гаманця на Android пристрої. Пароль використовується для захисту даних вашого гаманця на Android пристрої.
Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль. Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль.
</p> </p>
<h2>Запишіть вашу мнемонічну фразу!</h2> <h2>Запишіть вашу мнемонічну фразу!</h2>
<p>Наступний екран буде містити вашу \"мнемонічну фразу\", що складається з 25 слів. <p>Наступний екран буде містити вашу \"мнемонічну фразу\", що складається з 25 слів.
        Це єдині дані, які необхідні для відновлення вашого гаманця в Це єдині дані, які необхідні для відновлення вашого гаманця в
        майбутньому і отримання доступу до ваших коштів. майбутньому і отримання доступу до ваших коштів.
        Підтримувати її безпеку і конфіденційність дуже важливо, так як це Підтримувати її безпеку і конфіденційність дуже важливо, так як це
     гарантує, що ніхто не зможе отримати доступ до ваших коштів!</p> гарантує, що ніхто не зможе отримати доступ до ваших коштів!</p>
<p>Якщо ви втратите пароль від вашого гаманця, ви зможете відновити його, використовуючи мнемонічну фразу.</p> <p>Якщо ви втратите пароль від вашого гаманця, ви зможете відновити його, використовуючи мнемонічну фразу.</p>
<p>Спосіб відновлення мнемонічної фрази відсутній. У разі її втрати - будуть втрачені <p>Спосіб відновлення мнемонічної фрази відсутній. У разі її втрати - будуть втрачені
     і всі ваші кошти! Також ви ніколи не зможете змінити мнемонічну фразу, і якщо вона і всі ваші кошти! Також ви ніколи не зможете змінити мнемонічну фразу, і якщо вона
буде вкрадена або розкрита будь-яким іншим чином, то вам доведеться перенести ваші кошти буде вкрадена або розкрита будь-яким іншим чином, то вам доведеться перенести ваші кошти
в новий гаманець (з новою мнемонічною фразою). Тому рекомендується створити резервну копію в новий гаманець (з новою мнемонічною фразою). Тому рекомендується створити резервну копію
вашої мнемонічною фрази, записавши її, і зберігати декілька копій в безпечному місці.</p> вашої мнемонічною фрази, записавши її, і зберігати декілька копій в безпечному місці.</p>
@ -61,7 +61,7 @@
не боячись втратити свої Monero. Monero відправлятимуть на ваш гаманець, використовуючи саме цю адресу. не боячись втратити свої Monero. Monero відправлятимуть на ваш гаманець, використовуючи саме цю адресу.
<h2>Мнемонічна фраза</h2> <h2>Мнемонічна фраза</h2>
Це єдині дані, які необхідні для відновлення вашого гаманця в майбутньому, і отримання Це єдині дані, які необхідні для відновлення вашого гаманця в майбутньому, і отримання
        доступу до ваших коштів. Підтримувати її безпеку і конфіденційність дуже важливо, доступу до ваших коштів. Підтримувати її безпеку і конфіденційність дуже важливо,
так як це гарантує, що <em>ніхто</em> не зможе отримати доступ до ваших коштів! так як це гарантує, що <em>ніхто</em> не зможе отримати доступ до ваших коштів!
Якщо ви не записали цю фразу, і не зберегли її в безпечному місці, зробіть це негайно! Якщо ви не записали цю фразу, і не зберегли її в безпечному місці, зробіть це негайно!
<h2>Файли відновлення паролю гаманця</h2> <h2>Файли відновлення паролю гаманця</h2>
@ -207,10 +207,10 @@
<p>Ваші секретні ключі ніколи не покинуть пристрій Ledger. Вам потрібен <p>Ваші секретні ключі ніколи не покинуть пристрій Ledger. Вам потрібен
пристрій кожен раз, коли ви хочете отримати доступ до свого гаманця.</p> пристрій кожен раз, коли ви хочете отримати доступ до свого гаманця.</p>
<p>Необхідно ввести унікальні і&apos:мя і пароль гаманця. Пароль використовується для захисту даних вашого <p>Необхідно ввести унікальні і&apos:мя і пароль гаманця. Пароль використовується для захисту даних вашого
         гаманця на пристрої. Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль.</p> гаманця на пристрої. Необхідно використовувати надійний пароль. Краще навіть використовувати фразу-пароль.</p>
<p>Якщо вам відомий номер блоку першої транзакції, який використовувався з цією адресою, слід <p>Якщо вам відомий номер блоку першої транзакції, який використовувався з цією адресою, слід
         ввести його в поле \"Відновити висоту\". Ви також можете використовувати дату в форматі YYYY-MM-DD. ввести його в поле \"Відновити висоту\". Ви також можете використовувати дату в форматі YYYY-MM-DD.
  Якщо ви не впевнені, введіть приблизну дату/висоту блоку <em>до</em> того, як ви вперше використали цей гаманець.</p> Якщо ви не впевнені, введіть приблизну дату/висоту блоку <em>до</em> того, як ви вперше використали цей гаманець.</p>
]]></string> ]]></string>
<string name="help_wallet"><![CDATA[ <string name="help_wallet"><![CDATA[
@ -229,7 +229,7 @@
<p><b>Допоможіть! Баланс мого гаманця кудись зник або не підтверджений!</b><br/> <p><b>Допоможіть! Баланс мого гаманця кудись зник або не підтверджений!</b><br/>
Не панікуйте! Якщо ви відправляєте кошти з вашого гаманця, ваш баланс тимчасово залишається Не панікуйте! Якщо ви відправляєте кошти з вашого гаманця, ваш баланс тимчасово залишається
непідтвердженим. Це відбувається в результаті процесу обміну Monero в блокчейні, і роботи механізму непідтвердженим. Це відбувається в результаті процесу обміну Monero в блокчейні, і роботи механізму
        решти. Подробиці обміну можна дізнатися за посиланням: решти. Подробиці обміну можна дізнатися за посиланням:
https://getmonero.org/resources/moneropedia/change.html https://getmonero.org/resources/moneropedia/change.html
<h2>Список транзакцій</h2> <h2>Список транзакцій</h2>
<p>Список транзакцій, проведених з використанням цього гаманця. У гаманцях перегляду можна побачити <p>Список транзакцій, проведених з використанням цього гаманця. У гаманцях перегляду можна побачити
@ -278,8 +278,6 @@
Сканування зупиниться, як тільки буде знайдено 10 віддалених вузлів.</p> Сканування зупиниться, як тільки буде знайдено 10 віддалених вузлів.</p>
]]></string> ]]></string>
<string name="help_uri"><![CDATA[ <string name="help_uri"><![CDATA[
<h1>Використання плажіного посилання</h1> <h1>Використання плажіного посилання</h1>
<p>Ви почали використовувати Monerujo з платіжним посиланням. Для надсилання коштів, будь ласка, виконайте найступне:</p> <p>Ви почали використовувати Monerujo з платіжним посиланням. Для надсилання коштів, будь ласка, виконайте найступне:</p>
@ -292,4 +290,25 @@
]]></string> ]]></string>
<string name="help_ok">Я зрозумів!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Я зрозумів!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -231,7 +231,7 @@
<string name="send_create_tx_error_title">Помилка створення транзакції</string> <string name="send_create_tx_error_title">Помилка створення транзакції</string>
<string name="tx_list_fee">- Комісія %1$s</string> <string name="tx_list_fee">Комісія %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">Не вдалося</string> <string name="tx_list_failed_text">Не вдалося</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -431,5 +431,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -26,7 +26,7 @@
选择输入一个估算的日期或区块高度,但这个日期或区块高度对应的时间必须在你第一次使用该地址<em>之前</em></p> 选择输入一个估算的日期或区块高度,但这个日期或区块高度对应的时间必须在你第一次使用该地址<em>之前</em></p>
]]></string> ]]></string>
<string name="help_create_ledger"><![CDATA[ <string name="help_create_ledger"><![CDATA[
<h1>用Ledger恢复钱包</h1> <h1>用Ledger恢复钱包</h1>
<p>如果你已经拥有一个钱包地址并想用Ledger Nano S来恢复你的钱包。</p> <p>如果你已经拥有一个钱包地址并想用Ledger Nano S来恢复你的钱包。</p>
<p>因为你的密钥时刻存储在Ledger设备中所以你每次访问钱包的时候都需要插入Ledger设备。</p> <p>因为你的密钥时刻存储在Ledger设备中所以你每次访问钱包的时候都需要插入Ledger设备。</p>
@ -35,8 +35,8 @@
<p>请在\"恢复高度\"中输入你在这个地址上的第一笔交易所在的区块高度。你也可以使用YYYY-MM-DD的格式来输入日期。如果你不是十分确定也可以 <p>请在\"恢复高度\"中输入你在这个地址上的第一笔交易所在的区块高度。你也可以使用YYYY-MM-DD的格式来输入日期。如果你不是十分确定也可以
选择输入一个估算的日期或区块高度,但这个日期或区块高度对应的时间必须在你第一次使用该地址<em>之前</em></p> 选择输入一个估算的日期或区块高度,但这个日期或区块高度对应的时间必须在你第一次使用该地址<em>之前</em></p>
]]></string> ]]></string>
<string name="help_create_keys"><![CDATA[ <string name="help_create_keys"><![CDATA[
<h1>用密钥恢复钱包</h1> <h1>用密钥恢复钱包</h1>
<p>如果你已经拥有一个钱包地址,并想用密钥恢复它。</p> <p>如果你已经拥有一个钱包地址,并想用密钥恢复它。</p>
<p>请输入钱包名称(不得重复)和密码。 <p>请输入钱包名称(不得重复)和密码。
@ -230,4 +230,25 @@
]]></string> ]]></string>
<string name="help_ok">我明白了!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">我明白了!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -182,7 +182,7 @@
<string name="send_amount">%1$s XMR</string> <string name="send_amount">%1$s XMR</string>
<string name="send_fee">+%1$s 手续费</string> <string name="send_fee">+%1$s 手续费</string>
<string name="send_create_tx_error_title">创建交易发生错误</string> <string name="send_create_tx_error_title">创建交易发生错误</string>
<string name="tx_list_fee">- 手续费 %1$s</string> <string name="tx_list_fee">手续费 %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">失败</string> <string name="tx_list_failed_text">失败</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -351,5 +351,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -231,4 +231,25 @@
]]></string> ]]></string>
<string name="help_ok">我知道了!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">我知道了!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -229,7 +229,7 @@
<string name="send_create_tx_error_title">建立交易錯誤</string> <string name="send_create_tx_error_title">建立交易錯誤</string>
<string name="tx_list_fee">- 手續費 %1$s</string> <string name="tx_list_fee">手續費 %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">失敗</string> <string name="tx_list_failed_text">失敗</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -426,5 +426,10 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -290,4 +290,25 @@
]]></string> ]]></string>
<string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" --> <string name="help_ok">Got it!</string> <!-- Note: "Got it" as in "I understand this" -->
<string name="help_nok">Nah…</string> <!-- Note: "Nah..." as in "I don't want this" -->
<string name="help_getorbot">Get Orbot!</string>
<string name="help_tor"><![CDATA[
<h1>Tor</h1>
<p>Tor, short for The Onion Router, is free and open-source software for enabling anonymous
communication.</p>
<p>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 <b>slower</b>.</p>
<p>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.</p>
<p>If you have issues connecting with Tor, try to get a new Identity in the Orbot App (icon
on the top right).</p>
]]></string>
<string name="help_tor_enable"><![CDATA[
<h1>Tor Node</h1>
<p>This is an .onion node. In order to use it, you must enable Tor mode by touching the
<img src="ic_network_clearnet"/> icon near the top of the Wallet List page.</p>
]]></string>
</resources> </resources>

View File

@ -100,7 +100,7 @@
<string name="changepw_failed">Change Password failed!</string> <string name="changepw_failed">Change Password failed!</string>
<string name="changepw_success">Password changed</string> <string name="changepw_success">Password changed</string>
<string name="label_daemon">Node</string> <string name="label_daemon">Network</string>
<string name="connect_stagenet" translatable="false">Stagenet</string> <string name="connect_stagenet" translatable="false">Stagenet</string>
<string name="connect_testnet" translatable="false">Testnet</string> <string name="connect_testnet" translatable="false">Testnet</string>
<string name="status_wallet_loading">Loading Wallet &#8230;</string> <string name="status_wallet_loading">Loading Wallet &#8230;</string>
@ -243,7 +243,7 @@
<string name="send_create_tx_error_title">Create Transaction Error</string> <string name="send_create_tx_error_title">Create Transaction Error</string>
<string name="tx_list_fee">- Fee %1$s</string> <string name="tx_list_fee">Fee %1$s</string>
<string name="tx_list_amount_failed">(%1$s)</string> <string name="tx_list_amount_failed">(%1$s)</string>
<string name="tx_list_failed_text">failed</string> <string name="tx_list_failed_text">failed</string>
<string name="tx_list_amount_negative">- %1$s</string> <string name="tx_list_amount_negative">- %1$s</string>
@ -499,5 +499,12 @@
<string name="restore_failed">Import failed!</string> <string name="restore_failed">Import failed!</string>
<string name="menu_deletecache">Reset wallet!</string> <string name="menu_deletecache">Reset wallet!</string>
<string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, ...)! Use this ONLY if this wallet is corrupt and does not load!</string> <string name="deletecache_alert_message">This wallet will be reset, losing all off-chain data (like notes, account &amp; subaddress names, private transaction keys, &#8230;)! Use this ONLY if this wallet is corrupt and does not load!</string>
<string name="status" translatable="false">&lt;span style=\"background-color: #%1$s; color: #%2$s;\"&gt;%3$s&lt;/span&gt;%4$s</string>
<string name="node_tor_error">Tor required</string>
<string name="node_waiting">\u00A0WAITING FOR NODE\u00A0</string>
<string name="tor_enable_background">"Allow Background Starts" in Orbot Settings to use Tor!</string>
<string name="tor_noshift">SideShift.ai doesn\'t support Tor.\nDisable Tor to swap XMR.</string>
</resources> </resources>

View File

@ -36,8 +36,7 @@
</style> </style>
<style name="AppCard" parent="Widget.MaterialComponents.CardView"> <style name="AppCard" parent="Widget.MaterialComponents.CardView">
<item name="cardElevation">4dp</item> <item name="cardElevation">2dp</item>
<item name="cardCornerRadius">1dp</item>
</style> </style>
<style name="AppButton" parent="@style/Widget.MaterialComponents.Button"> <style name="AppButton" parent="@style/Widget.MaterialComponents.Button">

View File

@ -1,5 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
repositories { repositories {
mavenCentral() mavenCentral()