diff --git a/app/build.gradle b/app/build.gradle
index 4f5b7dee9b..8cb200952c 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -142,6 +142,7 @@ dependencies {
implementation 'dnsjava:dnsjava:2.1.9'
implementation 'org.jitsi:dnssecjava:1.2.0'
implementation 'org.slf4j:slf4j-nop:1.7.30'
+ implementation 'com.unstoppabledomains:resolution:3.0.0'
implementation 'com.github.brnunes:swipeablerecyclerview:1.0.2'
//noinspection GradleDependency
diff --git a/app/src/main/assets/licenses.html b/app/src/main/assets/licenses.html
index ff886b6b57..e73ad859b1 100644
--- a/app/src/main/assets/licenses.html
+++ b/app/src/main/assets/licenses.html
@@ -444,6 +444,8 @@
zxcvbn4j (https://github.com/nulab/zxcvbn4j)
Copyright (c) 2014 Nulab Inc
slfj-nop - Simple Logging Facade for Java no-operation binding (https://www.slf4j.org/)
Copyright (c) 2004-2017 QOS.ch
+resolution-java - Java library to resolve ENS & Unstoppable Domains
+Copyright (c) 2020 Unstoppable Domains
The MIT License
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
diff --git a/app/src/main/java/com/m2049r/xmrwallet/BaseActivity.java b/app/src/main/java/com/m2049r/xmrwallet/BaseActivity.java
index b72c35bc00..ae3956ac5d 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/BaseActivity.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/BaseActivity.java
@@ -215,11 +215,12 @@ private void processNfcIntent(Intent intent) {
if (uri == null) {
Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
} else {
- BarcodeData bc = BarcodeData.fromString(uri.toString());
- if (bc == null)
- Toast.makeText(this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
- else
- onUriScanned(bc);
+ BarcodeData.fromString(uri.toString(), data -> runOnUiThread(() -> {
+ if (data == null)
+ Toast.makeText(BaseActivity.this, getString(R.string.nfc_tag_read_undef), Toast.LENGTH_LONG).show();
+ else
+ onUriScanned(data);
+ }));
}
}
}
diff --git a/app/src/main/java/com/m2049r/xmrwallet/ScannerFragment.java b/app/src/main/java/com/m2049r/xmrwallet/ScannerFragment.java
index 32512fdfe6..35d0c5f5c2 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/ScannerFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/ScannerFragment.java
@@ -27,6 +27,7 @@
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
+import com.m2049r.xmrwallet.data.BarcodeData;
import me.dm7.barcodescanner.zxing.ZXingScannerView;
import timber.log.Timber;
@@ -36,7 +37,11 @@ public class ScannerFragment extends Fragment implements ZXingScannerView.Result
private OnScannedListener onScannedListener;
public interface OnScannedListener {
- boolean onScanned(String qrCode);
+ void onScanned(String qrCode, ScannedCallbackListener listener);
+ }
+
+ public interface ScannedCallbackListener {
+ void onScanned(boolean success);
}
private ZXingScannerView mScannerView;
@@ -59,11 +64,11 @@ public void onResume() {
@Override
public void handleResult(Result rawResult) {
if ((rawResult.getBarcodeFormat() == BarcodeFormat.QR_CODE)) {
- if (onScannedListener.onScanned(rawResult.getText())) {
- return;
- } else {
- Toast.makeText(getActivity(), getString(R.string.send_qr_address_invalid), Toast.LENGTH_SHORT).show();
- }
+ onScannedListener.onScanned(rawResult.getText(), (success) -> requireActivity().runOnUiThread(() -> {
+ if (!success) {
+ Toast.makeText(getActivity(), getString(R.string.send_qr_address_invalid), Toast.LENGTH_SHORT).show();
+ }
+ }));
} else {
Toast.makeText(getActivity(), getString(R.string.send_qr_invalid), Toast.LENGTH_SHORT).show();
}
diff --git a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
index 0ff49ee4c0..4f7cc08bb4 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/WalletActivity.java
@@ -905,17 +905,18 @@ public void onScan() {
}
@Override
- public boolean onScanned(String qrCode) {
+ public void onScanned(String qrCode, ScannerFragment.ScannedCallbackListener listener) {
// #gurke
- BarcodeData bcData = BarcodeData.fromString(qrCode);
- if (bcData != null) {
- popFragmentStack(null);
- Timber.d("AAA");
- onUriScanned(bcData);
- return true;
- } else {
- return false;
- }
+ BarcodeData.fromString(qrCode, (bcData) -> {
+ if (bcData != null) {
+ popFragmentStack(null);
+ Timber.d("AAA");
+ onUriScanned(bcData);
+ listener.onScanned(true);
+ } else {
+ listener.onScanned(false);
+ }
+ });
}
OnUriScannedListener onUriScannedListener = null;
@@ -937,6 +938,7 @@ void onUriScanned(BarcodeData barcodeData) {
}
}
+ @SuppressLint("MissingSuperCall")
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
Timber.d("onRequestPermissionsResult()");
diff --git a/app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java b/app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
index 3a5cecb9ca..956042e9fc 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/data/BarcodeData.java
@@ -19,6 +19,10 @@
import android.net.Uri;
import com.m2049r.xmrwallet.util.OpenAliasHelper;
+import com.unstoppabledomains.exceptions.ns.NamingServiceException;
+import com.unstoppabledomains.resolution.DomainResolution;
+import com.unstoppabledomains.resolution.Resolution;
+import com.unstoppabledomains.resolution.naming.service.NamingServiceType;
import java.net.URI;
import java.net.URISyntaxException;
@@ -38,6 +42,10 @@ public enum Security {
OA_DNSSEC
}
+ public interface Listener {
+ void onParseComplete(BarcodeData data);
+ }
+
final public Crypto asset;
final public List ambiguousAssets;
final public String address;
@@ -169,7 +177,7 @@ static public BarcodeData parseUri(String uriString) {
}
- static public BarcodeData fromString(String qrCode) {
+ static public void fromString(String qrCode, Listener listener) {
BarcodeData bcData = parseUri(qrCode);
if (bcData == null) {
// maybe it's naked?
@@ -179,7 +187,44 @@ static public BarcodeData fromString(String qrCode) {
// check for OpenAlias
bcData = parseOpenAlias(qrCode, false);
}
- return bcData;
+ if (bcData == null) {
+ // Check for UD domain (async)
+ parseUD(qrCode, listener);
+ } else {
+ listener.onParseComplete(bcData);
+ }
+ }
+
+ static public void parseUD(String udString, Listener listener) {
+ Timber.d("parseUD=%s", udString);
+ if (udString == null) listener.onParseComplete(null);
+
+ new Thread(() -> {
+ DomainResolution resolution = Resolution.builder()
+ .providerUrl(NamingServiceType.ENS, "https://cloudflare-eth.com")
+ .build();
+
+ String address = null;
+ Crypto crypto = null;
+ for (Crypto currentCrypto: Crypto.values()) {
+ try {
+ address = resolution.getAddress(udString, currentCrypto.getSymbol().toLowerCase());
+ crypto = currentCrypto;
+ break;
+ } catch (NamingServiceException e) {
+ Timber.d(e.getLocalizedMessage());
+ }
+ }
+ if (crypto == null) {
+ Timber.d("Unsupported UD address %s", udString);
+ listener.onParseComplete(null);
+ } else if (!crypto.validate(address)) {
+ Timber.d("%s address invalid", crypto);
+ listener.onParseComplete(null);
+ } else {
+ listener.onParseComplete(new BarcodeData(crypto, address, udString, null, null, Security.NORMAL));
+ }
+ }).start();
}
static public BarcodeData parseOpenAlias(String oaString, boolean dnssec) {
diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java
index f25ad19ba8..80c5766b33 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendAddressWizardFragment.java
@@ -52,6 +52,10 @@
import com.m2049r.xmrwallet.util.validator.BitcoinAddressType;
import com.m2049r.xmrwallet.util.validator.BitcoinAddressValidator;
import com.m2049r.xmrwallet.util.validator.EthAddressValidator;
+import com.unstoppabledomains.exceptions.ns.NamingServiceException;
+import com.unstoppabledomains.resolution.DomainResolution;
+import com.unstoppabledomains.resolution.Resolution;
+import com.unstoppabledomains.resolution.naming.service.NamingServiceType;
import java.util.HashMap;
import java.util.HashSet;
@@ -166,11 +170,7 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
etAddress.getEditText().setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
String enteredAddress = etAddress.getEditText().getText().toString().trim();
- String dnsOA = dnsFromOpenAlias(enteredAddress);
- Timber.d("OpenAlias is %s", dnsOA);
- if (dnsOA != null) {
- processOpenAlias(dnsOA);
- }
+ goToOpenAlias(enteredAddress);
}
});
etAddress.getEditText().addTextChangedListener(new TextWatcher() {
@@ -216,6 +216,8 @@ public void afterTextChanged(Editable editable) {
}
if (possibleCryptos.isEmpty()) {
Timber.d("other");
+ // Makes the height of tvXmrTo consistent when invisible
+ tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto_help_xmr)));
tvXmrTo.setVisibility(View.INVISIBLE);
sendListener.setMode(SendFragment.Mode.XMR);
}
@@ -237,21 +239,21 @@ public void onTextChanged(CharSequence s, int start, int before, int count) {
if (clip == null) return;
// clean it up
final String address = clip.replaceAll("( +)|(\\r?\\n?)", "");
- BarcodeData bc = BarcodeData.fromString(address);
- if (bc != null) {
- processScannedData(bc);
- final EditText et = etAddress.getEditText();
- et.setSelection(et.getText().length());
- etAddress.requestFocus();
- } else {
- Toast.makeText(getActivity(), getString(R.string.send_address_invalid), Toast.LENGTH_SHORT).show();
- }
+ BarcodeData.fromString(address, (bc) -> requireActivity().runOnUiThread(() -> {
+ if (bc != null) {
+ processScannedData(bc);
+ final EditText et = etAddress.getEditText();
+ et.setSelection(et.getText().length());
+ etAddress.requestFocus();
+ } else {
+ Toast.makeText(getActivity(), getString(R.string.send_address_invalid), Toast.LENGTH_SHORT).show();
+ }
+ }));
});
etNotes = view.findViewById(R.id.etNotes);
etNotes.getEditText().setRawInputType(InputType.TYPE_CLASS_TEXT);
etNotes.getEditText().
-
setOnEditorActionListener((v, actionId, event) -> {
if ((event != null && (event.getKeyCode() == KeyEvent.KEYCODE_ENTER) && (event.getAction() == KeyEvent.ACTION_DOWN))
|| (actionId == EditorInfo.IME_ACTION_DONE)) {
@@ -315,6 +317,8 @@ private void updateCryptoButtons(boolean noAddress) {
tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto_ambiguous)));
tvXmrTo.setVisibility(View.VISIBLE);
} else {
+ // Makes the height of tvXmrTo consistent when invisible
+ tvXmrTo.setText(Html.fromHtml(getString(R.string.info_xmrto_help_xmr)));
tvXmrTo.setVisibility(View.INVISIBLE);
}
if (noAddress) {
@@ -322,35 +326,95 @@ private void updateCryptoButtons(boolean noAddress) {
}
}
+ private void goToOpenAlias(String enteredAddress) {
+ String dnsOA = dnsFromOpenAlias(enteredAddress);
+ Timber.d("OpenAlias is %s", dnsOA);
+ if (dnsOA != null) {
+ processOpenAlias(dnsOA);
+ } else if (enteredAddress.length() == 0 || checkAddressNoError()) {
+ etAddress.setErrorEnabled(false);
+ } else {
+ // Not all UD address match Patterns.DOMAIN_NAME (eg. .888, .x)
+ processUD(enteredAddress);
+ }
+ }
+
private void processOpenAlias(String dnsOA) {
if (resolvingOA) return; // already resolving - just wait
sendListener.popBarcodeData();
- if (dnsOA != null) {
- resolvingOA = true;
- etAddress.setError(getString(R.string.send_address_resolve_openalias));
- OpenAliasHelper.resolve(dnsOA, new OpenAliasHelper.OnResolvedListener() {
- @Override
- public void onResolved(Map dataMap) {
- resolvingOA = false;
- BarcodeData barcodeData = dataMap.get(Crypto.XMR);
- if (barcodeData == null) barcodeData = dataMap.get(Crypto.BTC);
- if (barcodeData != null) {
- Timber.d("Security=%s, %s", barcodeData.security.toString(), barcodeData.address);
- processScannedData(barcodeData);
- } else {
- etAddress.setError(getString(R.string.send_address_not_openalias));
- Timber.d("NO XMR OPENALIAS TXT FOUND");
+ resolvingOA = true;
+ etAddress.setError(getString(R.string.send_address_resolve_openalias));
+ OpenAliasHelper.resolve(dnsOA, new OpenAliasHelper.OnResolvedListener() {
+ @Override
+ public void onResolved(Map dataMap) {
+ resolvingOA = false;
+ BarcodeData barcodeData = dataMap.get(Crypto.XMR);
+ if (barcodeData == null) barcodeData = dataMap.get(Crypto.BTC);
+ if (barcodeData != null) {
+ Timber.d("Security=%s, %s", barcodeData.security.toString(), barcodeData.address);
+ processScannedData(barcodeData);
+ } else {
+ Timber.d("NO XMR OPENALIAS TXT FOUND");
+ processUD(dnsOA);
+ }
+ }
+
+ @Override
+ public void onFailure() {
+ resolvingOA = false;
+ Timber.e("OA FAILED");
+ processUD(dnsOA);
+ }
+ });
+ }
+
+ private void processUD(String udString) {
+ sendListener.popBarcodeData();
+
+ DomainResolution resolution = Resolution.builder()
+ .providerUrl(NamingServiceType.ENS, "https://cloudflare-eth.com")
+ .build();
+ final boolean[] domainIsUD = {false};
+ final String[] address = {null};
+ final Crypto[] crypto = {null};
+ etAddress.setError(getString(R.string.send_address_resolve_ud));
+ new Thread(() -> {
+ for (Crypto currentCrypto: Crypto.values()) {
+ try {
+ address[0] = resolution.getAddress(udString, currentCrypto.getSymbol().toLowerCase());
+ crypto[0] = currentCrypto;
+ domainIsUD[0] = true;
+ break;
+ } catch (NamingServiceException e) {
+ Timber.d(e.getLocalizedMessage());
+ switch (e.getCode()) {
+ case UnknownCurrency:
+ case RecordNotFound:
+ domainIsUD[0] = true;
+ break;
+ default:
+ domainIsUD[0] = false;
+ break;
}
}
+ }
- @Override
- public void onFailure() {
- resolvingOA = false;
+ requireActivity().runOnUiThread(() -> {
+ if (domainIsUD[0]) {
+ if (crypto[0] == null) {
+ Timber.d("Unsupported UD address %s", udString);
+ etAddress.setError(getString(R.string.send_address_no_ud_records));
+ } else {
+ BarcodeData barcodeData = new BarcodeData(crypto[0], address[0], udString,
+ null, null, BarcodeData.Security.NORMAL);
+ processScannedData(barcodeData);
+ }
+ } else {
+ Timber.d("Non ENS / UD address %s", udString);
etAddress.setError(getString(R.string.send_address_not_openalias));
- Timber.e("OA FAILED");
}
});
- } // else ignore
+ }).start();
}
private boolean checkAddressNoError() {
@@ -405,11 +469,7 @@ public boolean onValidateFields() {
if (!checkAddressNoError()) {
shakeAddress();
String enteredAddress = etAddress.getEditText().getText().toString().trim();
- String dnsOA = dnsFromOpenAlias(enteredAddress);
- Timber.d("OpenAlias is %s", dnsOA);
- if (dnsOA != null) {
- processOpenAlias(dnsOA);
- }
+ goToOpenAlias(enteredAddress);
return false;
}
diff --git a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendFragment.java b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendFragment.java
index 14203c1f87..2fc310ff2f 100644
--- a/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendFragment.java
+++ b/app/src/main/java/com/m2049r/xmrwallet/fragment/send/SendFragment.java
@@ -55,7 +55,6 @@
import com.m2049r.xmrwallet.widget.Toolbar;
import java.lang.ref.WeakReference;
-import java.util.Objects;
import timber.log.Timber;
@@ -189,8 +188,10 @@ public void onPageScrollStateChanged(int state) {
String uri = args.getString(WalletActivity.REQUEST_URI);
Timber.d("URI: %s", uri);
if (uri != null) {
- barcodeData = BarcodeData.fromString(uri);
- Timber.d("barcodeData: %s", barcodeData != null ? barcodeData.toString() : "null");
+ BarcodeData.fromString(uri, (data) -> {
+ barcodeData = data;
+ Timber.d("barcodeData: %s", barcodeData != null ? barcodeData.toString() : "null");
+ });
}
}
diff --git a/app/src/main/res/values-cat/strings.xml b/app/src/main/res/values-cat/strings.xml
index 48c3fab91f..d0497f8e09 100644
--- a/app/src/main/res/values-cat/strings.xml
+++ b/app/src/main/res/values-cat/strings.xml
@@ -434,4 +434,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index adbfbe186a..a03ed45a0b 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -435,4 +435,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 7854246625..d89e90b7a7 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -436,4 +436,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml
index 6db51898ff..9a7f2b57f1 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -436,4 +436,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index 067eb57727..3827092041 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -427,4 +427,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index 1bddbd91d1..db8c419536 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -434,4 +434,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index c0d7b00db1..7493ca56c5 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -440,4 +440,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 877d045714..dda89bd9a6 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -438,4 +438,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index b65a7e71c3..cfab93aeaa 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -439,4 +439,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index ad491ad722..aae035625b 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -439,4 +439,7 @@
タッチして詳細情報を見る
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 7760a570bd..89d873cbd9 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -436,4 +436,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 0743afc133..6cfe397ad4 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -436,4 +436,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index ce28cbeb1f..5f125cb366 100755
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -429,4 +429,7 @@ aqui.
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml
index 90d449344c..c112cfe992 100644
--- a/app/src/main/res/values-pt/strings.xml
+++ b/app/src/main/res/values-pt/strings.xml
@@ -440,4 +440,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 1ae3c8bb42..df0584c915 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -436,4 +436,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 867abdbb4b..47882b01f7 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -440,4 +440,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index bbf7567670..4fa57f1620 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -437,4 +437,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index b6eedda28f..d534ea6b51 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -435,4 +435,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index 694c37535e..2309baaf71 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -428,4 +428,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index 93665d756d..00b7e84ee0 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -440,4 +440,7 @@
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index aafeac1abd..3212d7eb70 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -360,4 +360,7 @@
点击以查看详情
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index a6003f1ea5..52c0ff38cb 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -435,4 +435,7 @@
點選以獲得詳細資訊
Seed encryption (EXPERIMENTAL)
Seed Offset Phrase (optional)
+
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
diff --git a/app/src/main/res/values/help.xml b/app/src/main/res/values/help.xml
index 14571e0721..569e679941 100644
--- a/app/src/main/res/values/help.xml
+++ b/app/src/main/res/values/help.xml
@@ -158,6 +158,8 @@
In addition to using an XMR address, you can also use
- an OpenAlias for XMR or BTC
+ - an ENS domain
+ - an Unstoppable Domains domain
- a BTC address
Please note, that sending BTC is processed through the SideShift.ai service (see https://sideshift.ai
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a953497072..8f0e0daf25 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -221,7 +221,9 @@
Not a QR Code
Not a valid payment QR code
Not a valid address
- OpenAlias address not available
+ Resolving ENS / UD…
+ No address found for ENS / UD domain
+ ENS / UD / OpenAlias address not available
OpenAlias secure ✔
Resolving OpenAlias…
OpenAlias without DNSSEC - address may be spoofed