From df9418c7999a817eb9c551fb081e35fd8970fd11 Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Wed, 19 Feb 2020 22:14:39 +0200 Subject: [PATCH 1/6] CWA-69 | created formatDomainName() and fetchXmrAddress() in the openalias.dart. Added openalias to send page --- lib/src/domain/common/openalias.dart | 33 ++++++++++++++++++++++++++++ lib/src/screens/send/send_page.dart | 7 ++++++ pubspec.lock | 7 ++++++ pubspec.yaml | 1 + res/values/strings_ko.arb | 4 ---- 5 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 lib/src/domain/common/openalias.dart diff --git a/lib/src/domain/common/openalias.dart b/lib/src/domain/common/openalias.dart new file mode 100644 index 000000000..bdbb224f4 --- /dev/null +++ b/lib/src/domain/common/openalias.dart @@ -0,0 +1,33 @@ +import 'package:basic_utils/basic_utils.dart'; + +String formatDomainName(String name) { + if (!name.contains(".")) { + return ""; + } + + return name.replaceAll("@", "."); +} + +Future fetchXmrAddress(String name) async { + String xmrAddress = ""; + + await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true).then((txtRecord) { + if (txtRecord != null) { + String record; + + for (int i = 0; i < txtRecord.length; i++) { + record = txtRecord[i].data; + + if (record.contains("oa1:xmr") && record.contains("recipient_address")) { + record = record.replaceAll('\"', ""); + xmrAddress = record.split(" ").where((item) => (item.contains("recipient_address"))) + .toString().replaceAll("recipient_address=", "").replaceAll("\;", "") + .replaceAll("(", "").replaceAll(")", ""); + break; + } + } + } + }); + + return xmrAddress; +} \ No newline at end of file diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index f8fe0bbda..a3cb73c58 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -22,6 +22,7 @@ import 'package:cake_wallet/src/domain/common/calculate_estimated_fee.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/domain/common/sync_status.dart'; import 'package:cake_wallet/src/stores/sync/sync_store.dart'; +import 'package:cake_wallet/src/domain/common/openalias.dart'; class SendPage extends BasePage { @override @@ -358,6 +359,12 @@ class SendFormState extends State { // Hack. Don't ask me. FocusScope.of(context).requestFocus(FocusNode()); + final domainName = formatDomainName(_addressController.text); + + if (domainName != "") { + await fetchXmrAddress(domainName).then((address) => _addressController.text = address); + } + if (_formKey.currentState.validate()) { await showDialog( context: context, diff --git a/pubspec.lock b/pubspec.lock index ab6b8a29d..5c7088d15 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -43,6 +43,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.0.0" + basic_utils: + dependency: "direct main" + description: + name: basic_utils + url: "https://pub.dartlang.org" + source: hosted + version: "1.9.3" boolean_selector: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 318057f0c..58f13a7f5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -53,6 +53,7 @@ dependencies: cupertino_icons: ^0.1.2 encrypt: ^4.0.0 password: ^1.0.0 + basic_utils: ^1.0.8 dev_dependencies: flutter_test: diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 699c6caa7..230ca3197 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -342,9 +342,5 @@ "incorrect_seed" : "입력하신 텍스트가 유효하지 않습니다.", "biometric_auth_reason" : "지문을 스캔하여 인증", -<<<<<<< HEAD -======= - ->>>>>>> 4848485be8cbc34cbec847abbb76dabd075841ae "version" : "버전 ${currentVersion}" } \ No newline at end of file From 91091a8d19c3ac7a4dfb21a87c19ec3d68c3f8e4 Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Thu, 20 Feb 2020 22:50:22 +0200 Subject: [PATCH 2/6] CWA-69 | added focusNode to address_text_field, got recipient name in the openalias, added focusNode listener in the send_page --- lib/src/domain/common/openalias.dart | 31 ++++++++++++++------ lib/src/screens/send/send_page.dart | 39 +++++++++++++++++++++---- lib/src/widgets/address_text_field.dart | 3 ++ 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/lib/src/domain/common/openalias.dart b/lib/src/domain/common/openalias.dart index bdbb224f4..73afb6a3d 100644 --- a/lib/src/domain/common/openalias.dart +++ b/lib/src/domain/common/openalias.dart @@ -1,15 +1,17 @@ import 'package:basic_utils/basic_utils.dart'; String formatDomainName(String name) { - if (!name.contains(".")) { - return ""; + String formattedName = name; + + if (name.contains(".")) { + formattedName = name.replaceAll("@", "."); } - return name.replaceAll("@", "."); + return formattedName; } -Future fetchXmrAddress(String name) async { - String xmrAddress = ""; +Future> fetchXmrAddressAndRecipientName(String name) async { + final map = {"recipient_address" : name, "recipient_name" : name}; await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true).then((txtRecord) { if (txtRecord != null) { @@ -20,14 +22,25 @@ Future fetchXmrAddress(String name) async { if (record.contains("oa1:xmr") && record.contains("recipient_address")) { record = record.replaceAll('\"', ""); - xmrAddress = record.split(" ").where((item) => (item.contains("recipient_address"))) - .toString().replaceAll("recipient_address=", "").replaceAll("\;", "") - .replaceAll("(", "").replaceAll(")", ""); + + final dataList = record.split(";"); + + map["recipient_address"] = dataList.where((item) => (item.contains("recipient_address"))) + .toString().replaceAll("oa1:xmr recipient_address=", "") + .replaceAll("(", "").replaceAll(")", "").trim(); + + final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString(); + + if (recipientName.isNotEmpty) { + map["recipient_name"] = recipientName.replaceAll("recipient_name=", "") + .replaceAll("(", "").replaceAll(")", "").trim(); + } + break; } } } }); - return xmrAddress; + return map; } \ No newline at end of file diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index a3cb73c58..33f2eb254 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -49,10 +49,42 @@ class SendFormState extends State { final _cryptoAmountController = TextEditingController(); final _fiatAmountController = TextEditingController(); + final _focusNode = FocusNode(); + bool _effectsInstalled = false; final _formKey = GlobalKey(); + @override + void initState() { + _focusNode.addListener(() async { + if (_addressController.text.isNotEmpty) { + await fetchXmrAddressAndRecipientName(formatDomainName(_addressController.text)).then((map) async { + + if (_addressController.text != map["recipient_address"]) { + _addressController.text = map["recipient_address"]; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text("XMR Recipient Detected"), + content: Text("You will be sending funds to\n${map["recipient_name"]}"), + actions: [ + FlatButton( + child: Text(S.of(context).ok), + onPressed: () => Navigator.of(context).pop()) + ], + ); + }); + } + }); + } + }); + + super.initState(); + } + @override Widget build(BuildContext context) { final settingsStore = Provider.of(context); @@ -151,6 +183,7 @@ class SendFormState extends State { AddressTextField( controller: _addressController, placeholder: S.of(context).send_monero_address, + focusNode: _focusNode, onURIScanned: (uri) { var address = ''; var amount = ''; @@ -359,12 +392,6 @@ class SendFormState extends State { // Hack. Don't ask me. FocusScope.of(context).requestFocus(FocusNode()); - final domainName = formatDomainName(_addressController.text); - - if (domainName != "") { - await fetchXmrAddress(domainName).then((address) => _addressController.text = address); - } - if (_formKey.currentState.validate()) { await showDialog( context: context, diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart index c457ee485..a13132e55 100644 --- a/lib/src/widgets/address_text_field.dart +++ b/lib/src/widgets/address_text_field.dart @@ -18,6 +18,7 @@ class AddressTextField extends StatelessWidget { AddressTextFieldOption.addressBook ], this.onURIScanned, + this.focusNode, this.validator}); static const prefixIconWidth = 34.0; @@ -30,6 +31,7 @@ class AddressTextField extends StatelessWidget { final Function(Uri) onURIScanned; final List options; final FormFieldValidator validator; + FocusNode focusNode; @override Widget build(BuildContext context) { @@ -37,6 +39,7 @@ class AddressTextField extends StatelessWidget { onFieldSubmitted: (_) => FocusScope.of(context).unfocus(), enabled: isActive, controller: controller, + focusNode: focusNode, decoration: InputDecoration( suffixIcon: SizedBox( width: prefixIconWidth * options.length + From dde482c4f6bee3cdf8e86f44551caec2e8920434 Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Thu, 20 Feb 2020 23:02:41 +0200 Subject: [PATCH 3/6] CWA-69 | added focusNode to address_text_field, got recipient name in the openalias, added focusNode listener in the send_page --- lib/src/domain/common/openalias.dart | 44 +++++++++++++++------------- lib/src/screens/send/send_page.dart | 2 +- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/lib/src/domain/common/openalias.dart b/lib/src/domain/common/openalias.dart index 73afb6a3d..641c2a4bc 100644 --- a/lib/src/domain/common/openalias.dart +++ b/lib/src/domain/common/openalias.dart @@ -13,34 +13,38 @@ String formatDomainName(String name) { Future> fetchXmrAddressAndRecipientName(String name) async { final map = {"recipient_address" : name, "recipient_name" : name}; - await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true).then((txtRecord) { - if (txtRecord != null) { - String record; + try { + await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true).then((txtRecord) { + if (txtRecord != null) { + String record; - for (int i = 0; i < txtRecord.length; i++) { - record = txtRecord[i].data; + for (int i = 0; i < txtRecord.length; i++) { + record = txtRecord[i].data; - if (record.contains("oa1:xmr") && record.contains("recipient_address")) { - record = record.replaceAll('\"', ""); + if (record.contains("oa1:xmr") && record.contains("recipient_address")) { + record = record.replaceAll('\"', ""); - final dataList = record.split(";"); + final dataList = record.split(";"); - map["recipient_address"] = dataList.where((item) => (item.contains("recipient_address"))) - .toString().replaceAll("oa1:xmr recipient_address=", "") - .replaceAll("(", "").replaceAll(")", "").trim(); - - final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString(); - - if (recipientName.isNotEmpty) { - map["recipient_name"] = recipientName.replaceAll("recipient_name=", "") + map["recipient_address"] = dataList.where((item) => (item.contains("recipient_address"))) + .toString().replaceAll("oa1:xmr recipient_address=", "") .replaceAll("(", "").replaceAll(")", "").trim(); - } - break; + final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString(); + + if (recipientName.isNotEmpty) { + map["recipient_name"] = recipientName.replaceAll("recipient_name=", "") + .replaceAll("(", "").replaceAll(")", "").trim(); + } + + break; + } } } - } - }); + }); + } catch (e) { + print("${e.toString()}"); + } return map; } \ No newline at end of file diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 33f2eb254..f0a2b97ca 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -58,7 +58,7 @@ class SendFormState extends State { @override void initState() { _focusNode.addListener(() async { - if (_addressController.text.isNotEmpty) { + if (!_focusNode.hasFocus &&_addressController.text.isNotEmpty) { await fetchXmrAddressAndRecipientName(formatDomainName(_addressController.text)).then((map) async { if (_addressController.text != map["recipient_address"]) { From 28085ce057348c91b5f62bf01ddc7e9e375fe952 Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Fri, 21 Feb 2020 12:45:15 +0200 Subject: [PATCH 4/6] CWA-69 | translated title and content in the openalias alert dialog (send page) --- lib/generated/i18n.dart | 42 ++++++++++++++++++++++++++++ lib/src/domain/common/openalias.dart | 6 ++-- lib/src/screens/send/send_page.dart | 4 +-- res/values/strings_de.arb | 5 +++- res/values/strings_en.arb | 5 +++- res/values/strings_es.arb | 5 +++- res/values/strings_hi.arb | 5 +++- res/values/strings_ja.arb | 5 +++- res/values/strings_ko.arb | 5 +++- res/values/strings_nl.arb | 5 +++- res/values/strings_pl.arb | 5 +++- res/values/strings_pt.arb | 5 +++- res/values/strings_ru.arb | 5 +++- res/values/strings_zh.arb | 5 +++- 14 files changed, 91 insertions(+), 16 deletions(-) diff --git a/lib/generated/i18n.dart b/lib/generated/i18n.dart index 751fb13af..d99174a72 100644 --- a/lib/generated/i18n.dart +++ b/lib/generated/i18n.dart @@ -102,6 +102,7 @@ class S implements WidgetsLocalizations { String get nodes_list_reset_to_default_message => "Are you sure that you want to reset settings to default?"; String get offer_expires_in => "Offer expires in: "; String get ok => "OK"; + String get openalias_alert_title => "XMR Recipient Detected"; String get outgoing => "Outgoing"; String get password => "Password"; String get paste => "Paste"; @@ -280,6 +281,7 @@ class S implements WidgetsLocalizations { String failed_authentication(String state_error) => "Failed authentication. ${state_error}"; String max_value(String value, String currency) => "Max: ${value} ${currency}"; String min_value(String value, String currency) => "Min: ${value} ${currency}"; + String openalias_alert_content(String recipient_name) => "You will be sending funds to\n${recipient_name}"; String powered_by(String title) => "Powered by ${title}"; String router_no_route(String name) => "No route defined for ${name}"; String send_priority(String transactionPriority) => "Currently the fee is set at ${transactionPriority} priority.\nTransaction priority can be adjusted in the settings"; @@ -436,6 +438,8 @@ class $de extends S { @override String get contact => "Kontakt"; @override + String get openalias_alert_title => "XMR-Empfänger erkannt"; + @override String get auth_store_incorrect_password => "Falsches PIN"; @override String get transaction_priority_slow => "Schleppend"; @@ -844,6 +848,8 @@ class $de extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "Transaktion festschreiben\nMenge: ${amount}\nGebühr: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "Sie senden Geld an\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "Fehler beim Entfernen ${wallet_name} Wallet. ${error}"; @override String copied_key_to_clipboard(String key) => "Kopiert ${key} Zur Zwischenablage"; @@ -992,6 +998,8 @@ class $hi extends S { @override String get contact => "संपर्क करें"; @override + String get openalias_alert_title => "XMR प्राप्तकर्ता का पता लगाया"; + @override String get auth_store_incorrect_password => "गलत पिन"; @override String get transaction_priority_slow => "धीरे"; @@ -1400,6 +1408,8 @@ class $hi extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "लेन-देन करें\nरकम: ${amount}\nशुल्क: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "आपको धनराशि भेजी जाएगी\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "निकालने में विफल ${wallet_name} बटुआ. ${error}"; @override String copied_key_to_clipboard(String key) => "की नकल की ${key} क्लिपबोर्ड पर"; @@ -1548,6 +1558,8 @@ class $ru extends S { @override String get contact => "Контакт"; @override + String get openalias_alert_title => "Получатель XMR обнаружен"; + @override String get auth_store_incorrect_password => "Некорректный пин"; @override String get transaction_priority_slow => "Медленный"; @@ -1956,6 +1968,8 @@ class $ru extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "Подтвердить транзакцию \nСумма: ${amount}\nСбор: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "Вы будете отправлять средства\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "Ошибка при удалении ${wallet_name} кошелька. ${error}"; @override String copied_key_to_clipboard(String key) => "Скопировано ${key} в буфер обмена"; @@ -2104,6 +2118,8 @@ class $ko extends S { @override String get contact => "접촉"; @override + String get openalias_alert_title => "XMR 수신자 감지"; + @override String get auth_store_incorrect_password => "잘못된 PIN"; @override String get transaction_priority_slow => "느린"; @@ -2512,6 +2528,8 @@ class $ko extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "커밋 거래\n양: ${amount}\n보수: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "당신은에 자금을 보낼 것입니다\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "제거하지 못했습니다 ${wallet_name} 지갑. ${error}"; @override String copied_key_to_clipboard(String key) => "복사 ${key} 클립 보드로"; @@ -2660,6 +2678,8 @@ class $pt extends S { @override String get contact => "Contato"; @override + String get openalias_alert_title => "Destinatário XMR detectado"; + @override String get auth_store_incorrect_password => "PIN incorreto"; @override String get transaction_priority_slow => "Lenta"; @@ -3068,6 +3088,8 @@ class $pt extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "Confirmar transação\nQuantia: ${amount}\nTaxa: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "Você enviará fundos para\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "Falha ao remover a carteira ${wallet_name}. ${error}"; @override String copied_key_to_clipboard(String key) => "${key} copiada para a área de transferência"; @@ -3216,6 +3238,8 @@ class $ja extends S { @override String get contact => "接触"; @override + String get openalias_alert_title => "XMR受信者が検出されました"; + @override String get auth_store_incorrect_password => "間違ったPIN"; @override String get transaction_priority_slow => "スロー"; @@ -3624,6 +3648,8 @@ class $ja extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "トランザクションをコミット\n量: ${amount}\n費用: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "に送金します\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "削除できませんでした ${wallet_name} 財布. ${error}"; @override String copied_key_to_clipboard(String key) => "コピー済み ${key} クリップボードへ"; @@ -3776,6 +3802,8 @@ class $pl extends S { @override String get contact => "Kontakt"; @override + String get openalias_alert_title => "Wykryto odbiorcę XMR"; + @override String get auth_store_incorrect_password => "Niepoprawny PIN"; @override String get transaction_priority_slow => "Powolny"; @@ -4184,6 +4212,8 @@ class $pl extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "Zatwierdź transakcję\nIlość: ${amount}\nOpłata: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "Będziesz wysyłać środki na\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "Nie udało się usunąć ${wallet_name} portfel. ${error}"; @override String copied_key_to_clipboard(String key) => "Skopiowane ${key} do schowka"; @@ -4332,6 +4362,8 @@ class $es extends S { @override String get contact => "Contacto"; @override + String get openalias_alert_title => "Destinatario XMR detectado"; + @override String get auth_store_incorrect_password => "Contraseña PIN"; @override String get transaction_priority_slow => "Lento"; @@ -4740,6 +4772,8 @@ class $es extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "Confirmar transacción\nCantidad: ${amount}\nCuota: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "Enviará fondos a\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "Error al elimina ${wallet_name} billetera. ${error}"; @override String copied_key_to_clipboard(String key) => "Copiado ${key} al portapapeles"; @@ -4888,6 +4922,8 @@ class $nl extends S { @override String get contact => "Contact"; @override + String get openalias_alert_title => "XMR-ontvanger gedetecteerd"; + @override String get auth_store_incorrect_password => "Incorrect PIN"; @override String get transaction_priority_slow => "Langzaam"; @@ -5296,6 +5332,8 @@ class $nl extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "Verricht transactie\nBedrag: ${amount}\nhonorarium: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "U stuurt geld naar\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "Verwijderen mislukt ${wallet_name} portemonnee. ${error}"; @override String copied_key_to_clipboard(String key) => "Gekopieerd ${key} naar het klembord"; @@ -5444,6 +5482,8 @@ class $zh extends S { @override String get contact => "联系"; @override + String get openalias_alert_title => "檢測到XMR收件人"; + @override String get auth_store_incorrect_password => "PIN码错误"; @override String get transaction_priority_slow => "慢"; @@ -5852,6 +5892,8 @@ class $zh extends S { @override String commit_transaction_amount_fee(String amount, String fee) => "提交交易\n量: ${amount}\nFee: ${fee}"; @override + String openalias_alert_content(String recipient_name) => "您將匯款至\n${recipient_name}"; + @override String wallet_list_failed_to_remove(String wallet_name, String error) => "删除失败 ${wallet_name} 钱包. ${error}"; @override String copied_key_to_clipboard(String key) => "复制 ${key} 到剪贴板"; diff --git a/lib/src/domain/common/openalias.dart b/lib/src/domain/common/openalias.dart index 641c2a4bc..8f567bce6 100644 --- a/lib/src/domain/common/openalias.dart +++ b/lib/src/domain/common/openalias.dart @@ -30,11 +30,11 @@ Future> fetchXmrAddressAndRecipientName(String name) async { .toString().replaceAll("oa1:xmr recipient_address=", "") .replaceAll("(", "").replaceAll(")", "").trim(); - final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString(); + final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString() + .replaceAll("(", "").replaceAll(")", "").trim(); if (recipientName.isNotEmpty) { - map["recipient_name"] = recipientName.replaceAll("recipient_name=", "") - .replaceAll("(", "").replaceAll(")", "").trim(); + map["recipient_name"] = recipientName.replaceAll("recipient_name=", ""); } break; diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index f0a2b97ca..94b2dd739 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -68,8 +68,8 @@ class SendFormState extends State { context: context, builder: (BuildContext context) { return AlertDialog( - title: Text("XMR Recipient Detected"), - content: Text("You will be sending funds to\n${map["recipient_name"]}"), + title: Text(S.of(context).openalias_alert_title), + content: Text(S.of(context).openalias_alert_content(map["recipient_name"])), actions: [ FlatButton( child: Text(S.of(context).ok), diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 2dc78e7c7..c703b0a48 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "Der eingegebene Text ist ungültig.", "biometric_auth_reason" : "Scannen Sie Ihren Fingerabdruck zur Authentifizierung", - "version" : "Ausführung ${currentVersion}" + "version" : "Ausführung ${currentVersion}", + + "openalias_alert_title" : "XMR-Empfänger erkannt", + "openalias_alert_content" : "Sie senden Geld an\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 5d8b88eda..861ac43f1 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "The text entered is not valid.", "biometric_auth_reason" : "Scan your fingerprint to authenticate", - "version" : "Version ${currentVersion}" + "version" : "Version ${currentVersion}", + + "openalias_alert_title" : "XMR Recipient Detected", + "openalias_alert_content" : "You will be sending funds to\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 308833a1a..ef9b83950 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "El texto ingresado no es válido.", "biometric_auth_reason" : "Escanee su huella digital para autenticar", - "version" : "Versión ${currentVersion}" + "version" : "Versión ${currentVersion}", + + "openalias_alert_title" : "Destinatario XMR detectado", + "openalias_alert_content" : "Enviará fondos a\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index aa4a8545e..1e14ce24f 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "दर्ज किया गया पाठ मान्य नहीं है।", "biometric_auth_reason" : "प्रमाणित करने के लिए अपने फ़िंगरप्रिंट को स्कैन करें", - "version" : "संस्करण ${currentVersion}" + "version" : "संस्करण ${currentVersion}", + + "openalias_alert_title" : "XMR प्राप्तकर्ता का पता लगाया", + "openalias_alert_content" : "आपको धनराशि भेजी जाएगी\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index a23b72f4c..e3be02c0c 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "入力されたテキストは無効です。", "biometric_auth_reason" : "प指紋をスキャンして認証する", - "version" : "バージョン ${currentVersion}" + "version" : "バージョン ${currentVersion}", + + "openalias_alert_title" : "XMR受信者が検出されました", + "openalias_alert_content" : "に送金します\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 230ca3197..3204d82f3 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "입력하신 텍스트가 유효하지 않습니다.", "biometric_auth_reason" : "지문을 스캔하여 인증", - "version" : "버전 ${currentVersion}" + "version" : "버전 ${currentVersion}", + + "openalias_alert_title" : "XMR 수신자 감지", + "openalias_alert_content" : "당신은에 자금을 보낼 것입니다\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 3784383dc..9a2097500 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "De ingevoerde tekst is niet geldig.", "biometric_auth_reason" : "Scan uw vingerafdruk om te verifiëren", - "version" : "Versie ${currentVersion}" + "version" : "Versie ${currentVersion}", + + "openalias_alert_title" : "XMR-ontvanger gedetecteerd", + "openalias_alert_content" : "U stuurt geld naar\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 966ce647c..065b11309 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "Wprowadzony tekst jest nieprawidłowy.", "biometric_auth_reason" : "Zeskanuj swój odcisk palca, aby go uwierzytelnić", - "version" : "Wersja ${currentVersion}" + "version" : "Wersja ${currentVersion}", + + "openalias_alert_title" : "Wykryto odbiorcę XMR", + "openalias_alert_content" : "Będziesz wysyłać środki na\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8ef36326c..bd3d219a9 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "O texto digitado não é válido.", "biometric_auth_reason" : "Digitalize sua impressão digital para autenticar", - "version" : "Versão ${currentVersion}" + "version" : "Versão ${currentVersion}", + + "openalias_alert_title" : "Destinatário XMR detectado", + "openalias_alert_content" : "Você enviará fundos para\n${recipient_name}" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index d2d17760f..65378ccae 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "Введенный текст некорректный.", "biometric_auth_reason" : "Отсканируйте свой отпечаток пальца для аутентификации", - "version" : "Версия ${currentVersion}" + "version" : "Версия ${currentVersion}", + + "openalias_alert_title" : "Получатель XMR обнаружен", + "openalias_alert_content" : "Вы будете отправлять средства\n${recipient_name}" } \ No newline at end of file diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index d19056644..a1391719f 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -342,5 +342,8 @@ "incorrect_seed" : "输入的文字无效。", "biometric_auth_reason" : "掃描指紋以進行身份驗證", - "version" : "版 ${currentVersion}" + "version" : "版 ${currentVersion}", + + "openalias_alert_title" : "檢測到XMR收件人", + "openalias_alert_content" : "您將匯款至\n${recipient_name}" } \ No newline at end of file From 0efe8af3e0982292d07a8af9a105221313e0de7a Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Tue, 25 Feb 2020 11:28:33 +0200 Subject: [PATCH 5/6] CWA-173 | created OpenaliasRecord class, renamed fetchXmrAddressAndRecipientName method on fetchAddressAndName, used forEach instead of for loop in this method, checked entered xmr address in the send store --- lib/src/domain/common/openalias.dart | 50 ----------------- lib/src/domain/common/openalias_record.dart | 61 +++++++++++++++++++++ lib/src/screens/send/send_page.dart | 47 ++++++++-------- lib/src/stores/send/send_store.dart | 14 +++++ 4 files changed, 100 insertions(+), 72 deletions(-) delete mode 100644 lib/src/domain/common/openalias.dart create mode 100644 lib/src/domain/common/openalias_record.dart diff --git a/lib/src/domain/common/openalias.dart b/lib/src/domain/common/openalias.dart deleted file mode 100644 index 8f567bce6..000000000 --- a/lib/src/domain/common/openalias.dart +++ /dev/null @@ -1,50 +0,0 @@ -import 'package:basic_utils/basic_utils.dart'; - -String formatDomainName(String name) { - String formattedName = name; - - if (name.contains(".")) { - formattedName = name.replaceAll("@", "."); - } - - return formattedName; -} - -Future> fetchXmrAddressAndRecipientName(String name) async { - final map = {"recipient_address" : name, "recipient_name" : name}; - - try { - await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true).then((txtRecord) { - if (txtRecord != null) { - String record; - - for (int i = 0; i < txtRecord.length; i++) { - record = txtRecord[i].data; - - if (record.contains("oa1:xmr") && record.contains("recipient_address")) { - record = record.replaceAll('\"', ""); - - final dataList = record.split(";"); - - map["recipient_address"] = dataList.where((item) => (item.contains("recipient_address"))) - .toString().replaceAll("oa1:xmr recipient_address=", "") - .replaceAll("(", "").replaceAll(")", "").trim(); - - final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString() - .replaceAll("(", "").replaceAll(")", "").trim(); - - if (recipientName.isNotEmpty) { - map["recipient_name"] = recipientName.replaceAll("recipient_name=", ""); - } - - break; - } - } - } - }); - } catch (e) { - print("${e.toString()}"); - } - - return map; -} \ No newline at end of file diff --git a/lib/src/domain/common/openalias_record.dart b/lib/src/domain/common/openalias_record.dart new file mode 100644 index 000000000..dffc8487a --- /dev/null +++ b/lib/src/domain/common/openalias_record.dart @@ -0,0 +1,61 @@ +import 'package:basic_utils/basic_utils.dart'; + +class OpenaliasRecord { + + OpenaliasRecord({this.name}); + + String name; + String address; + + String get recordName => name; + String get recordAddress => address; + + String formatDomainName() { + String formattedName = name; + + if (name.contains("@")) { + formattedName = name.replaceAll("@", "."); + } + + return formattedName; + } + + Future fetchAddressAndName(String name) async { + this.name = name; + address = name; + + try { + final txtRecord = await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true); + + if (txtRecord != null) { + + for (RRecord element in txtRecord) { + String record = element.data; + + if (record.contains("oa1:xmr") && record.contains("recipient_address")) { + record = record.replaceAll('\"', ""); + + final dataList = record.split(";"); + + address = dataList.where((item) => (item.contains("recipient_address"))) + .toString().replaceAll("oa1:xmr recipient_address=", "") + .replaceAll("(", "").replaceAll(")", "").trim(); + + final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString() + .replaceAll("(", "").replaceAll(")", "").trim(); + + if (recipientName.isNotEmpty) { + this.name = recipientName.replaceAll("recipient_name=", ""); + } + + break; + } + } + } + } catch (e) { + print("${e.toString()}"); + } + } + +} + diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 94b2dd739..a77498648 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -22,7 +22,6 @@ import 'package:cake_wallet/src/domain/common/calculate_estimated_fee.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/src/domain/common/sync_status.dart'; import 'package:cake_wallet/src/stores/sync/sync_store.dart'; -import 'package:cake_wallet/src/domain/common/openalias.dart'; class SendPage extends BasePage { @override @@ -57,34 +56,38 @@ class SendFormState extends State { @override void initState() { - _focusNode.addListener(() async { + _focusNode.addListener(() { if (!_focusNode.hasFocus &&_addressController.text.isNotEmpty) { - await fetchXmrAddressAndRecipientName(formatDomainName(_addressController.text)).then((map) async { - - if (_addressController.text != map["recipient_address"]) { - _addressController.text = map["recipient_address"]; - - await showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog( - title: Text(S.of(context).openalias_alert_title), - content: Text(S.of(context).openalias_alert_content(map["recipient_name"])), - actions: [ - FlatButton( - child: Text(S.of(context).ok), - onPressed: () => Navigator.of(context).pop()) - ], - ); - }); - } - }); + getOpenaliasRecord(context); } }); super.initState(); } + void getOpenaliasRecord(BuildContext context) async { + final sendStore = Provider.of(context); + final isOpenalias = await sendStore.isOpenaliasRecord(_addressController.text); + + if (isOpenalias) { + _addressController.text = sendStore.recordAddress; + + await showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text(S.of(context).openalias_alert_title), + content: Text(S.of(context).openalias_alert_content(sendStore.recordName)), + actions: [ + FlatButton( + child: Text(S.of(context).ok), + onPressed: () => Navigator.of(context).pop()) + ], + ); + }); + } + } + @override Widget build(BuildContext context) { final settingsStore = Provider.of(context); diff --git a/lib/src/stores/send/send_store.dart b/lib/src/stores/send/send_store.dart index dbad353c4..5f6bd415a 100644 --- a/lib/src/stores/send/send_store.dart +++ b/lib/src/stores/send/send_store.dart @@ -11,6 +11,7 @@ import 'package:cake_wallet/src/stores/price/price_store.dart'; import 'package:cake_wallet/src/stores/send/sending_state.dart'; import 'package:cake_wallet/src/stores/settings/settings_store.dart'; import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/src/domain/common/openalias_record.dart'; part 'send_store.g.dart'; @@ -32,6 +33,8 @@ abstract class SendStoreBase with Store { SettingsStore settingsStore; PriceStore priceStore; Box transactionDescriptions; + String recordName; + String recordAddress; @observable SendingState state; @@ -53,6 +56,7 @@ abstract class SendStoreBase with Store { NumberFormat _cryptoNumberFormat; NumberFormat _fiatNumberFormat; String _lastRecipientAddress; + OpenaliasRecord _openaliasRecord; @action Future createTransaction( @@ -154,6 +158,16 @@ abstract class SendStoreBase with Store { } } + Future isOpenaliasRecord(String name) async { + _openaliasRecord = OpenaliasRecord(name: name); + await _openaliasRecord.fetchAddressAndName(_openaliasRecord.formatDomainName()); + + recordAddress = _openaliasRecord.recordAddress; + recordName = _openaliasRecord.recordName; + + return recordAddress != name; + } + void validateAddress(String value, {CryptoCurrency cryptoCurrency}) { // XMR (95, 106), ADA (59, 92, 105), BCH (42), BNB (42), BTC (34, 42), DASH (34), EOS (42), // ETH (42), LTC (34), NANO (64, 65), TRX (34), USDT (42), XLM (56), XRP (34) From 652ba167774cf744bfc7367e529b3482afe448de Mon Sep 17 00:00:00 2001 From: Oleksandr Sobol Date: Tue, 25 Feb 2020 14:45:06 +0200 Subject: [PATCH 6/6] CWA-69 | reworked OpenaliasRecord class --- lib/src/domain/common/openalias_record.dart | 59 +++++++++++---------- lib/src/screens/send/send_page.dart | 2 +- lib/src/stores/send/send_store.dart | 9 ++-- 3 files changed, 35 insertions(+), 35 deletions(-) diff --git a/lib/src/domain/common/openalias_record.dart b/lib/src/domain/common/openalias_record.dart index dffc8487a..cb659d533 100644 --- a/lib/src/domain/common/openalias_record.dart +++ b/lib/src/domain/common/openalias_record.dart @@ -2,15 +2,12 @@ import 'package:basic_utils/basic_utils.dart'; class OpenaliasRecord { - OpenaliasRecord({this.name}); + OpenaliasRecord({this.address, this.name}); - String name; - String address; + final String name; + final String address; - String get recordName => name; - String get recordAddress => address; - - String formatDomainName() { + static String formatDomainName(String name) { String formattedName = name; if (name.contains("@")) { @@ -20,41 +17,45 @@ class OpenaliasRecord { return formattedName; } - Future fetchAddressAndName(String name) async { - this.name = name; - address = name; + static Future fetchAddressAndName(String formattedName) async { + String address = formattedName; + String name = formattedName; - try { - final txtRecord = await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true); + if (formattedName.contains(".")) { + try { + final txtRecord = await DnsUtils.lookupRecord(formattedName, RRecordType.TXT, dnssec: true); - if (txtRecord != null) { + if (txtRecord != null) { - for (RRecord element in txtRecord) { - String record = element.data; + for (RRecord element in txtRecord) { + String record = element.data; - if (record.contains("oa1:xmr") && record.contains("recipient_address")) { - record = record.replaceAll('\"', ""); + if (record.contains("oa1:xmr") && record.contains("recipient_address")) { + record = record.replaceAll('\"', ""); - final dataList = record.split(";"); + final dataList = record.split(";"); - address = dataList.where((item) => (item.contains("recipient_address"))) - .toString().replaceAll("oa1:xmr recipient_address=", "") - .replaceAll("(", "").replaceAll(")", "").trim(); + address = dataList.where((item) => (item.contains("recipient_address"))) + .toString().replaceAll("oa1:xmr recipient_address=", "") + .replaceAll("(", "").replaceAll(")", "").trim(); - final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString() - .replaceAll("(", "").replaceAll(")", "").trim(); + final recipientName = dataList.where((item) => (item.contains("recipient_name"))).toString() + .replaceAll("(", "").replaceAll(")", "").trim(); - if (recipientName.isNotEmpty) { - this.name = recipientName.replaceAll("recipient_name=", ""); + if (recipientName.isNotEmpty) { + name = recipientName.replaceAll("recipient_name=", ""); + } + + break; } - - break; } } + } catch (e) { + print("${e.toString()}"); } - } catch (e) { - print("${e.toString()}"); } + + return OpenaliasRecord(address: address, name: name); } } diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index a77498648..07394e97d 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -65,7 +65,7 @@ class SendFormState extends State { super.initState(); } - void getOpenaliasRecord(BuildContext context) async { + Future getOpenaliasRecord(BuildContext context) async { final sendStore = Provider.of(context); final isOpenalias = await sendStore.isOpenaliasRecord(_addressController.text); diff --git a/lib/src/stores/send/send_store.dart b/lib/src/stores/send/send_store.dart index 5f6bd415a..5f0df3541 100644 --- a/lib/src/stores/send/send_store.dart +++ b/lib/src/stores/send/send_store.dart @@ -56,7 +56,6 @@ abstract class SendStoreBase with Store { NumberFormat _cryptoNumberFormat; NumberFormat _fiatNumberFormat; String _lastRecipientAddress; - OpenaliasRecord _openaliasRecord; @action Future createTransaction( @@ -159,11 +158,11 @@ abstract class SendStoreBase with Store { } Future isOpenaliasRecord(String name) async { - _openaliasRecord = OpenaliasRecord(name: name); - await _openaliasRecord.fetchAddressAndName(_openaliasRecord.formatDomainName()); + final _openaliasRecord = await OpenaliasRecord + .fetchAddressAndName(OpenaliasRecord.formatDomainName(name)); - recordAddress = _openaliasRecord.recordAddress; - recordName = _openaliasRecord.recordName; + recordAddress = _openaliasRecord.address; + recordName = _openaliasRecord.name; return recordAddress != name; }