From 7f37bd3d590a92b59a881f859223f471287e225c Mon Sep 17 00:00:00 2001 From: Serhii Date: Sat, 14 Jan 2023 23:29:47 +0200 Subject: [PATCH 01/27] update localization files --- lib/view_model/exchange/exchange_trade_view_model.dart | 2 +- res/values/strings_ar.arb | 4 +++- res/values/strings_de.arb | 4 +++- res/values/strings_en.arb | 4 +++- res/values/strings_es.arb | 4 +++- res/values/strings_fr.arb | 6 ++++-- res/values/strings_hi.arb | 6 ++++-- res/values/strings_hr.arb | 4 +++- res/values/strings_it.arb | 4 +++- res/values/strings_ja.arb | 4 +++- res/values/strings_ko.arb | 4 +++- res/values/strings_nl.arb | 4 +++- res/values/strings_pl.arb | 6 ++++-- res/values/strings_pt.arb | 4 +++- res/values/strings_ru.arb | 4 +++- res/values/strings_th.arb | 4 +++- res/values/strings_uk.arb | 4 +++- res/values/strings_zh.arb | 4 +++- 18 files changed, 55 insertions(+), 21 deletions(-) diff --git a/lib/view_model/exchange/exchange_trade_view_model.dart b/lib/view_model/exchange/exchange_trade_view_model.dart index 10ddf25e4..275de2808 100644 --- a/lib/view_model/exchange/exchange_trade_view_model.dart +++ b/lib/view_model/exchange/exchange_trade_view_model.dart @@ -143,7 +143,7 @@ abstract class ExchangeTradeViewModelBase with Store { ExchangeTradeItem( title: S.current.status, data: '${trade.state}', isCopied: false), ExchangeTradeItem( - title: S.current.widgets_address + ':', + title: S.current.send_to_this_address('${trade.from} ${trade.from.tag ?? ''}') + ':', data: trade.inputAddress ?? '', isCopied: true), ]); diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 250f29a70..7d7994b1e 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -678,5 +678,7 @@ "enabled":"ممكنة", "tor_only":"Tor فقط", "unmatched_currencies": "عملة محفظتك الحالية لا تتطابق مع عملة QR الممسوحة ضوئيًا", - "orbot_running_alert": "يرجى التأكد من تشغيل Orbot قبل الاتصال بهذه العقدة." + "orbot_running_alert": "يرجى التأكد من تشغيل Orbot قبل الاتصال بهذه العقدة.", + "send_to_this_address" : "أرسل ${currency} إلى هذا العنوان", + "arrive_in_this_address" : "سيصل ${currency} إلى هذا العنوان" } diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 2e71e8ce9..dbcf03ae2 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Die Währung Ihres aktuellen Wallets stimmt nicht mit der des gescannten QR überein", "orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.", "contact_list_contacts": "Kontakte", - "contact_list_wallets": "Meine Geldbörsen" + "contact_list_wallets": "Meine Geldbörsen", + "send_to_this_address" : "Senden Sie ${currency} an diese Adresse", + "arrive_in_this_address" : "${currency} wird an dieser Adresse ankommen" } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index a2b1cc702..602fbcde1 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Your current wallet's currency does not match that of the scanned QR", "orbot_running_alert": "Please make sure Orbot is running prior to connecting to this node.", "contact_list_contacts": "Contacts", - "contact_list_wallets": "My Wallets" + "contact_list_wallets": "My Wallets", + "send_to_this_address" : "Send ${currency} to this address", + "arrive_in_this_address" : "${currency} will arrive in this address" } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 6cbfa627a..4fdc450e0 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "La moneda de su billetera actual no coincide con la del QR escaneado", "orbot_running_alert": "Asegúrese de que Orbot se esté ejecutando antes de conectarse a este nodo.", "contact_list_contacts": "Contactos", - "contact_list_wallets": "Mis billeteras" + "contact_list_wallets": "Mis billeteras", + "send_to_this_address" : "Enviar ${currency} a esta dirección", + "arrive_in_this_address" : "${currency} llegará a esta dirección" } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 61bec11bf..34baa88d9 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -675,8 +675,10 @@ "disabled": "Désactivé", "enabled": "Activé", "tor_only": "Tor uniquement", - "orbot_running_alert": "Veuillez vous assurer qu'Orbot est en cours d'exécution avant de vous connecter à ce nœud.", "unmatched_currencies": "La devise de votre portefeuille (wallet) actuel ne correspond pas à celle du QR code scanné", + "orbot_running_alert": "Veuillez vous assurer qu'Orbot est en cours d'exécution avant de vous connecter à ce nœud.", "contact_list_contacts": "Contacts", - "contact_list_wallets": "Mes portefeuilles (wallets)" + "contact_list_wallets": "Mes portefeuilles (wallets)", + "send_to_this_address" : "Envoyez ${currency} à cette adresse", + "arrive_in_this_address" : "${currency} arrivera à cette adresse" } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index e906b3cc4..9bf6cfca2 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -677,8 +677,10 @@ "disabled": "अक्षम", "enabled": "सक्रिय", "tor_only": "Tor केवल", - "orbot_running_alert": "कृपया सुनिश्चित करें कि इस नोड से कनेक्ट करने से पहले Orbot चल रहा है।", "unmatched_currencies": "आपके वर्तमान वॉलेट की मुद्रा स्कैन किए गए क्यूआर से मेल नहीं खाती" , + "orbot_running_alert": "कृपया सुनिश्चित करें कि इस नोड से कनेक्ट करने से पहले Orbot चल रहा है।", "contact_list_contacts": "संपर्क", - "contact_list_wallets": "मेरा बटुआ" + "contact_list_wallets": "मेरा बटुआ", + "send_to_this_address" : "इस पते पर ${currency} भेजें", + "arrive_in_this_address" : "${currency} इस पते पर पहुंचेंगे" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index b44d2d6c3..27f4b3892 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Valuta vašeg trenutnog novčanika ne odgovara onoj na skeniranom QR-u", "orbot_running_alert": "Provjerite radi li Orbot prije spajanja na ovaj čvor.", "contact_list_contacts": "Kontakti", - "contact_list_wallets": "Moji novčanici" + "contact_list_wallets": "Moji novčanici", + "send_to_this_address" : "Pošaljite ${currency} na ovu adresu", + "arrive_in_this_address" : "${currency} će stići na ovu adresu" } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 6885fefa8..47d26aa9e 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "La valuta del tuo portafoglio attuale non corrisponde a quella del QR scansionato", "orbot_running_alert": "Assicurati che Orbot sia in esecuzione prima di connetterti a questo nodo.", "contact_list_contacts": "Contatti", - "contact_list_wallets": "I miei portafogli" + "contact_list_wallets": "I miei portafogli", + "send_to_this_address" : "Invia ${currency} a questo indirizzo", + "arrive_in_this_address" : "${currency} arriverà a questo indirizzo" } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index f02b76598..6c6ac91e3 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "現在のウォレットの通貨がスキャンされたQRの通貨と一致しません", "orbot_running_alert": "このノードに接続する前に、Orbot が実行されていることを確認してください", "contact_list_contacts": "連絡先", - "contact_list_wallets": "マイウォレット" + "contact_list_wallets": "マイウォレット", + "send_to_this_address" : "${currency} をこのアドレスに送金", + "arrive_in_this_address" : "${currency} はこの住所に到着します" } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index b7678fa85..e458aed0d 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "현재 지갑의 통화가 스캔한 QR의 통화와 일치하지 않습니다.", "orbot_running_alert": "이 노드에 연결하기 전에 Orbot이 실행 중인지 확인하십시오.", "contact_list_contacts": "콘택트 렌즈", - "contact_list_wallets": "내 지갑" + "contact_list_wallets": "내 지갑", + "send_to_this_address" : "이 주소로 ${currency} 송금", + "arrive_in_this_address" : "${currency}이(가) 이 주소로 도착합니다" } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 802c0e9ac..b8edbc0c1 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "De valuta van uw huidige portemonnee komt niet overeen met die van de gescande QR", "orbot_running_alert": "Zorg ervoor dat Orbot actief is voordat u verbinding maakt met dit knooppunt.", "contact_list_contacts": "Contacten", - "contact_list_wallets": "Mijn portefeuilles" + "contact_list_wallets": "Mijn portefeuilles", + "send_to_this_address" : "Stuur ${currency} naar dit adres", + "arrive_in_this_address" : "${currency} komt aan op dit adres" } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 1b49c6ef1..1bf2cf5b8 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -675,10 +675,12 @@ "disable_fiat": "Wyłącz waluty FIAT", "fiat_api": "API Walut FIAT", "disabled": "Wyłączone", - "orbot_running_alert": "Upewnij się, że Orbot działa przed połączeniem z tym węzłem.", "enabled": "Włączone", "tor_only": "Tylko sieć Tor", "unmatched_currencies": "Waluta Twojego obecnego portfela nie zgadza się z waluctą zeskanowanego kodu QR", + "orbot_running_alert": "Upewnij się, że Orbot działa przed połączeniem z tym węzłem.", "contact_list_contacts": "Łączność", - "contact_list_wallets": "Moje portfele" + "contact_list_wallets": "Moje portfele", + "send_to_this_address" : "Wyślij ${currency} na ten adres", + "arrive_in_this_address" : "${currency} dotrze na ten adres" } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8daba6193..7e4a66379 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -679,5 +679,7 @@ "unmatched_currencies": "A moeda da sua carteira atual não corresponde à do QR digitalizado", "orbot_running_alert": "Certifique-se de que o Orbot esteja em execução antes de se conectar a este nó.", "contact_list_contacts": "Contatos", - "contact_list_wallets": "minhas carteiras" + "contact_list_wallets": "minhas carteiras", + "send_to_this_address" : "Envie ${currency} para este endereço", + "arrive_in_this_address" : "${currency} chegará neste endereço" } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 17640af6d..979c3517d 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -680,5 +680,7 @@ "unmatched_currencies": "Валюта вашего текущего кошелька не соответствует валюте отсканированного QR-кода.", "orbot_running_alert": "Перед подключением к этому узлу убедитесь, что Orbot запущен.", "contact_list_contacts": "Контакты", - "contact_list_wallets": "Мои кошельки" + "contact_list_wallets": "Мои кошельки", + "send_to_this_address" : "Отправить ${currency} на этот адрес", + "arrive_in_this_address" : "${currency} придет на этот адрес" } diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 6934d9630..48e1ed0be 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -678,5 +678,7 @@ "unmatched_currencies" : "สกุลเงินของกระเป๋าปัจจุบันของคุณไม่ตรงกับของ QR ที่สแกน", "orbot_running_alert": "โปรดตรวจสอบว่า Orbot กำลังทำงานก่อนที่จะเชื่อมต่อกับโหนดนี้", "contact_list_contacts": "ติดต่อ", - "contact_list_wallets": "กระเป๋าเงินของฉัน" + "contact_list_wallets": "กระเป๋าเงินของฉัน", + "send_to_this_address" : "ส่ง ${currency} ไปยังที่อยู่นี้", + "arrive_in_this_address" : "${currency} จะมาถึงที่อยู่นี้" } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index b9311e8ef..05fbf2e00 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -679,5 +679,7 @@ "unmatched_currencies": "Валюта вашого гаманця не збігається з валютою сканованого QR-коду", "orbot_running_alert": "Перед підключенням до цього вузла переконайтеся, що Orbot запущено.", "contact_list_contacts": "Контакти", - "contact_list_wallets": "Мої гаманці" + "contact_list_wallets": "Мої гаманці", + "send_to_this_address" : "Надіслати ${currency} на цю адресу", + "arrive_in_this_address" : "${currency} надійде на цю адресу" } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 5b6608671..e7e63764d 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -678,5 +678,7 @@ "unmatched_currencies": "您当前钱包的货币与扫描的 QR 的货币不匹配", "orbot_running_alert": "请确保 Orbot 在连接到此节点之前正在运行。", "contact_list_contacts": "联系人", - "contact_list_wallets": "我的钱包" + "contact_list_wallets": "我的钱包", + "send_to_this_address" : "发送 ${currency} 到这个地址", + "arrive_in_this_address" : "${currency} 将到达此地址" } From b4249f21a9cd484a613c0a7706fa9b443791745e Mon Sep 17 00:00:00 2001 From: Serhii Date: Mon, 16 Jan 2023 17:27:49 +0200 Subject: [PATCH 02/27] add payout address item to confirmation screen --- lib/exchange/changenow/changenow_exchange_provider.dart | 8 ++++++-- lib/exchange/sideshift/sideshift_exchange_provider.dart | 3 +++ lib/exchange/simpleswap/simpleswap_exchange_provider.dart | 4 ++++ lib/exchange/trade.dart | 6 +++++- lib/view_model/exchange/exchange_trade_view_model.dart | 4 ++++ 5 files changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index a9fb7c9ca..fc60be18e 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -143,6 +143,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider { final inputAddress = responseJSON['payinAddress'] as String; final refundAddress = responseJSON['refundAddress'] as String; final extraId = responseJSON['payinExtraId'] as String?; + final payoutAddress = responseJSON['payoutAddress'] as String; return Trade( id: id, @@ -154,7 +155,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider { extraId: extraId, createdAt: DateTime.now(), amount: responseJSON['fromAmount']?.toString() ?? _request.fromAmount, - state: TradeState.created); + state: TradeState.created, + payoutAddress: payoutAddress); } @override @@ -192,6 +194,7 @@ class ChangeNowExchangeProvider extends ExchangeProvider { final extraId = responseJSON['payinExtraId'] as String; final outputTransaction = responseJSON['payoutHash'] as String; final expiredAtRaw = responseJSON['validUntil'] as String; + final payoutAddress = responseJSON['payoutAddress'] as String; final expiredAt = DateTime.tryParse(expiredAtRaw)?.toLocal(); return Trade( @@ -204,7 +207,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider { state: state, extraId: extraId, expiredAt: expiredAt, - outputTransaction: outputTransaction); + outputTransaction: outputTransaction, + payoutAddress: payoutAddress); } @override diff --git a/lib/exchange/sideshift/sideshift_exchange_provider.dart b/lib/exchange/sideshift/sideshift_exchange_provider.dart index 59d7964cb..2fc593988 100644 --- a/lib/exchange/sideshift/sideshift_exchange_provider.dart +++ b/lib/exchange/sideshift/sideshift_exchange_provider.dart @@ -150,6 +150,7 @@ class SideShiftExchangeProvider extends ExchangeProvider { refundAddress: settleAddress, state: TradeState.created, amount: _request.depositAmount, + payoutAddress: settleAddress, createdAt: DateTime.now(), ); } @@ -244,6 +245,7 @@ class SideShiftExchangeProvider extends ExchangeProvider { final inputAddress = responseJSON['depositAddress']['address'] as String; final expectedSendAmount = responseJSON['depositAmount'].toString(); final deposits = responseJSON['deposits'] as List?; + final settleAddress = responseJSON['settleAddress']['address'] as String; TradeState? state; String? status; @@ -264,6 +266,7 @@ class SideShiftExchangeProvider extends ExchangeProvider { amount: expectedSendAmount, state: state, expiredAt: expiredAt, + payoutAddress: settleAddress ); } diff --git a/lib/exchange/simpleswap/simpleswap_exchange_provider.dart b/lib/exchange/simpleswap/simpleswap_exchange_provider.dart index 2521c1486..e965e5331 100644 --- a/lib/exchange/simpleswap/simpleswap_exchange_provider.dart +++ b/lib/exchange/simpleswap/simpleswap_exchange_provider.dart @@ -108,6 +108,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider { final responseJSON = json.decode(response.body) as Map; final id = responseJSON['id'] as String; final inputAddress = responseJSON['address_from'] as String; + final payoutAddress = responseJSON['address_to'] as String; final settleAddress = responseJSON['user_refund_address'] as String; final extraId = responseJSON['extra_id_from'] as String?; return Trade( @@ -120,6 +121,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider { extraId: extraId, state: TradeState.created, amount: _request.amount, + payoutAddress: payoutAddress, createdAt: DateTime.now(), ); } @@ -189,6 +191,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider { final expectedSendAmount = responseJSON['expected_amount'].toString(); final extraId = responseJSON['extra_id_from'] as String?; final status = responseJSON['status'] as String; + final payoutAddress = responseJSON['address_to'] as String; final state = TradeState.deserialize(raw: status); return Trade( @@ -200,6 +203,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider { inputAddress: inputAddress, amount: expectedSendAmount, state: state, + payoutAddress: payoutAddress, ); } diff --git a/lib/exchange/trade.dart b/lib/exchange/trade.dart index 99b73e789..f20a080b7 100644 --- a/lib/exchange/trade.dart +++ b/lib/exchange/trade.dart @@ -21,7 +21,8 @@ class Trade extends HiveObject { this.extraId, this.outputTransaction, this.refundAddress, - this.walletId}) { + this.walletId, + this.payoutAddress}) { if (provider != null) { providerRaw = provider.raw; } @@ -88,6 +89,9 @@ class Trade extends HiveObject { @HiveField(12) String? walletId; + @HiveField(13) + String? payoutAddress; + static Trade fromMap(Map map) { return Trade( id: map['id'] as String, diff --git a/lib/view_model/exchange/exchange_trade_view_model.dart b/lib/view_model/exchange/exchange_trade_view_model.dart index 275de2808..2ec91b49b 100644 --- a/lib/view_model/exchange/exchange_trade_view_model.dart +++ b/lib/view_model/exchange/exchange_trade_view_model.dart @@ -146,6 +146,10 @@ abstract class ExchangeTradeViewModelBase with Store { title: S.current.send_to_this_address('${trade.from} ${trade.from.tag ?? ''}') + ':', data: trade.inputAddress ?? '', isCopied: true), + ExchangeTradeItem( + title: S.current.arrive_in_this_address('${trade.to} ${trade.to.tag ?? ''}') + ':', + data: trade.payoutAddress ?? '', + isCopied: true), ]); } } From 4636aacae71d511ae090e5f8d11bf75a9b602c39 Mon Sep 17 00:00:00 2001 From: Serhii Date: Mon, 16 Jan 2023 17:31:31 +0200 Subject: [PATCH 03/27] formatting --- .../exchange/exchange_trade_view_model.dart | 52 ++++++++----------- 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/lib/view_model/exchange/exchange_trade_view_model.dart b/lib/view_model/exchange/exchange_trade_view_model.dart index 2ec91b49b..8b578faa5 100644 --- a/lib/view_model/exchange/exchange_trade_view_model.dart +++ b/lib/view_model/exchange/exchange_trade_view_model.dart @@ -18,19 +18,18 @@ import 'package:cake_wallet/generated/i18n.dart'; part 'exchange_trade_view_model.g.dart'; -class ExchangeTradeViewModel = ExchangeTradeViewModelBase - with _$ExchangeTradeViewModel; +class ExchangeTradeViewModel = ExchangeTradeViewModelBase with _$ExchangeTradeViewModel; abstract class ExchangeTradeViewModelBase with Store { ExchangeTradeViewModelBase( {required this.wallet, - required this.trades, - required this.tradesStore, - required this.sendViewModel}) - : trade = tradesStore.trade!, - isSendable = tradesStore.trade!.from == wallet.currency || - tradesStore.trade!.provider == ExchangeProviderDescription.xmrto, - items = ObservableList() { + required this.trades, + required this.tradesStore, + required this.sendViewModel}) + : trade = tradesStore.trade!, + isSendable = tradesStore.trade!.from == wallet.currency || + tradesStore.trade!.provider == ExchangeProviderDescription.xmrto, + items = ObservableList() { switch (trade.provider) { case ExchangeProviderDescription.xmrto: _provider = XMRTOExchangeProvider(); @@ -67,22 +66,20 @@ abstract class ExchangeTradeViewModelBase with Store { @computed String get extraInfo => trade.from == CryptoCurrency.xlm - ? '\n\n' + S.current.xlm_extra_info - : trade.from == CryptoCurrency.xrp - ? '\n\n' + S.current.xrp_extra_info - : ''; + ? '\n\n' + S.current.xlm_extra_info + : trade.from == CryptoCurrency.xrp + ? '\n\n' + S.current.xrp_extra_info + : ''; @computed - String get pendingTransactionFiatAmountValueFormatted => - sendViewModel.isFiatDisabled - ? '' : sendViewModel.pendingTransactionFiatAmount - + ' ' + sendViewModel.fiat.title; + String get pendingTransactionFiatAmountValueFormatted => sendViewModel.isFiatDisabled + ? '' + : sendViewModel.pendingTransactionFiatAmount + ' ' + sendViewModel.fiat.title; @computed - String get pendingTransactionFeeFiatAmountFormatted => - sendViewModel.isFiatDisabled - ? '' : sendViewModel.pendingTransactionFeeFiatAmount - + ' ' + sendViewModel.fiat.title; + String get pendingTransactionFeeFiatAmountFormatted => sendViewModel.isFiatDisabled + ? '' + : sendViewModel.pendingTransactionFeeFiatAmount + ' ' + sendViewModel.fiat.title; @observable ObservableList items; @@ -130,18 +127,15 @@ abstract class ExchangeTradeViewModelBase with Store { final title = trade.from == CryptoCurrency.xrp ? S.current.destination_tag : trade.from == CryptoCurrency.xlm - ? S.current.memo - : S.current.extra_id; + ? S.current.memo + : S.current.extra_id; - items.add(ExchangeTradeItem( - title: title, data: '${trade.extraId}', isCopied: false)); + items.add(ExchangeTradeItem(title: title, data: '${trade.extraId}', isCopied: false)); } items.addAll([ - ExchangeTradeItem( - title: S.current.amount, data: '${trade.amount}', isCopied: false), - ExchangeTradeItem( - title: S.current.status, data: '${trade.state}', isCopied: false), + ExchangeTradeItem(title: S.current.amount, data: '${trade.amount}', isCopied: false), + ExchangeTradeItem(title: S.current.status, data: '${trade.state}', isCopied: false), ExchangeTradeItem( title: S.current.send_to_this_address('${trade.from} ${trade.from.tag ?? ''}') + ':', data: trade.inputAddress ?? '', From 8c016e946cc2a1913d3c16d7213cb447faad6e98 Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 17 Jan 2023 14:14:02 +0200 Subject: [PATCH 04/27] fix editing label subaddresses --- lib/src/screens/subaddress/address_edit_or_create_page.dart | 2 -- .../wallet_address_edit_or_create_view_model.dart | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/src/screens/subaddress/address_edit_or_create_page.dart b/lib/src/screens/subaddress/address_edit_or_create_page.dart index dac9e3881..b7394182c 100644 --- a/lib/src/screens/subaddress/address_edit_or_create_page.dart +++ b/lib/src/screens/subaddress/address_edit_or_create_page.dart @@ -17,8 +17,6 @@ class AddressEditOrCreatePage extends BasePage { _labelController.addListener( () => addressEditOrCreateViewModel.label = _labelController.text); _labelController.text = addressEditOrCreateViewModel.label; - print(_labelController.text); - print(addressEditOrCreateViewModel.label); } final WalletAddressEditOrCreateViewModel addressEditOrCreateViewModel; diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart index 43db6099f..c9d2c77f5 100644 --- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart @@ -30,7 +30,7 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { {required WalletBase wallet, dynamic item}) : isEdit = item != null, state = AddressEditOrCreateStateInitial(), - label = item?.fullName as String? ?? '', + label = item?.name as String? ?? '', _item = item, _wallet = wallet; From b8f74e50db1920ec8c93eb870b60f16b45d3672b Mon Sep 17 00:00:00 2001 From: Serhii Date: Fri, 20 Jan 2023 14:48:44 +0200 Subject: [PATCH 05/27] [skip ci] specify class type --- .../wallet_address_edit_or_create_view_model.dart | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart index c9d2c77f5..c29a256df 100644 --- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart @@ -1,3 +1,4 @@ +import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; import 'package:mobx/mobx.dart'; import 'package:flutter/foundation.dart'; import 'package:cw_core/wallet_base.dart'; @@ -27,10 +28,10 @@ class AddressEditOrCreateStateFailure extends AddressEditOrCreateState { abstract class WalletAddressEditOrCreateViewModelBase with Store { WalletAddressEditOrCreateViewModelBase( - {required WalletBase wallet, dynamic item}) + {required WalletBase wallet, WalletAddressListItem? item}) : isEdit = item != null, state = AddressEditOrCreateStateInitial(), - label = item?.name as String? ?? '', + label = item?.name ?? '', _item = item, _wallet = wallet; @@ -42,7 +43,7 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { bool isEdit; - final dynamic _item; + final WalletAddressListItem? _item; final WalletBase _wallet; Future save() async { @@ -105,7 +106,7 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { .setLabelSubaddress( wallet, accountIndex: monero!.getCurrentAccount(wallet).id, - addressIndex: _item.id as int, + addressIndex: _item?.id as int, label: label); await wallet.save(); } @@ -116,7 +117,7 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { .setLabelSubaddress( wallet, accountIndex: haven!.getCurrentAccount(wallet).id, - addressIndex: _item.id as int, + addressIndex: _item?.id as int, label: label); await wallet.save(); } From af01cb32435cc22c858c7556df02c2f3c238ff69 Mon Sep 17 00:00:00 2001 From: Serhii Date: Fri, 20 Jan 2023 21:44:08 +0200 Subject: [PATCH 06/27] minor fixes --- lib/di.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/di.dart b/lib/di.dart index 1acdad2dd..78fde59e7 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -37,6 +37,7 @@ import 'package:cake_wallet/view_model/settings/other_settings_view_model.dart'; import 'package:cake_wallet/view_model/settings/privacy_settings_view_model.dart'; import 'package:cake_wallet/view_model/settings/security_settings_view_model.dart'; import 'package:cake_wallet/view_model/advanced_privacy_settings_view_model.dart'; +import 'package:cake_wallet/view_model/wallet_address_list/wallet_address_list_item.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/core/backup_service.dart'; import 'package:cw_core/wallet_service.dart'; @@ -365,8 +366,8 @@ Future setup( addressListViewModel: getIt.get(), walletViewModel: getIt.get())); - getIt.registerFactoryParam( - (dynamic item, _) => WalletAddressEditOrCreateViewModel( + getIt.registerFactoryParam( + (WalletAddressListItem item, _) => WalletAddressEditOrCreateViewModel( wallet: getIt.get().wallet!, item: item)); getIt.registerFactoryParam( From 2fa7365218572fe59381267707e6275076035a5d Mon Sep 17 00:00:00 2001 From: Serhii Date: Fri, 20 Jan 2023 21:50:45 +0200 Subject: [PATCH 07/27] small fix --- lib/di.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/di.dart b/lib/di.dart index 78fde59e7..ae55c0ce6 100644 --- a/lib/di.dart +++ b/lib/di.dart @@ -366,8 +366,8 @@ Future setup( addressListViewModel: getIt.get(), walletViewModel: getIt.get())); - getIt.registerFactoryParam( - (WalletAddressListItem item, _) => WalletAddressEditOrCreateViewModel( + getIt.registerFactoryParam( + (WalletAddressListItem? item, _) => WalletAddressEditOrCreateViewModel( wallet: getIt.get().wallet!, item: item)); getIt.registerFactoryParam( From 912a4af86646328bd454a4f6f359de73b2a72fbe Mon Sep 17 00:00:00 2001 From: Serhii Date: Fri, 20 Jan 2023 23:18:58 +0200 Subject: [PATCH 08/27] fix nullable type --- ...let_address_edit_or_create_view_model.dart | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart index c29a256df..2cca395ab 100644 --- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart @@ -99,27 +99,22 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { await wallet.walletAddresses.updateAddress(_item.address as String); await wallet.save(); }*/ - - if (wallet.type == WalletType.monero) { - await monero - !.getSubaddressList(wallet) - .setLabelSubaddress( - wallet, - accountIndex: monero!.getCurrentAccount(wallet).id, - addressIndex: _item?.id as int, - label: label); - await wallet.save(); - } - - if (wallet.type == WalletType.haven) { - await haven - !.getSubaddressList(wallet) - .setLabelSubaddress( - wallet, - accountIndex: haven!.getCurrentAccount(wallet).id, - addressIndex: _item?.id as int, - label: label); - await wallet.save(); + final index = _item?.id; + if (index != null) { + if (wallet.type == WalletType.monero) { + await monero!.getSubaddressList(wallet).setLabelSubaddress(wallet, + accountIndex: monero!.getCurrentAccount(wallet).id, addressIndex: index, label: label); + await wallet.save(); + return; + } + if (wallet.type == WalletType.haven) { + await haven!.getSubaddressList(wallet).setLabelSubaddress(wallet, + accountIndex: haven!.getCurrentAccount(wallet).id, + addressIndex: _item?.id as int, + label: label); + await wallet.save(); + return; + } } } } From 83c1907e31460d7fc5f4679249e52f6dfe1ed1e4 Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 24 Jan 2023 20:24:46 +0200 Subject: [PATCH 09/27] add twitter api --- lib/core/address_validator.dart | 18 +++++++++ lib/entities/parse_address_from_domain.dart | 30 ++++++++++++--- lib/entities/parsed_address.dart | 11 +++++- .../widgets/extract_address_from_parsed.dart | 5 +++ lib/twitter/twitter_api.dart | 37 +++++++++++++++++++ lib/twitter/twitter_user.dart | 16 ++++++++ 6 files changed, 110 insertions(+), 7 deletions(-) create mode 100644 lib/twitter/twitter_api.dart create mode 100644 lib/twitter/twitter_user.dart diff --git a/lib/core/address_validator.dart b/lib/core/address_validator.dart index 519cd92a3..20cb66a4d 100644 --- a/lib/core/address_validator.dart +++ b/lib/core/address_validator.dart @@ -198,4 +198,22 @@ class AddressValidator extends TextValidator { return []; } } + + static String? getAddressFromStringPattern(CryptoCurrency type) { + switch (type) { + case CryptoCurrency.xmr: + return '([^0-9a-zA-Z]|^)4[0-9a-zA-Z]{94}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)8[0-9a-zA-Z]{94}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)[0-9a-zA-Z]{106}([^0-9a-zA-Z]|\$)'; + case CryptoCurrency.btc: + return '([^0-9a-zA-Z]|^)1[0-9a-zA-Z]{32}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)1[0-9a-zA-Z]{33}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)3[0-9a-zA-Z]{32}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)3[0-9a-zA-Z]{33}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)bc1[0-9a-zA-Z]{39}([^0-9a-zA-Z]|\$)' + '|([^0-9a-zA-Z]|^)bc1[0-9a-zA-Z]{59}([^0-9a-zA-Z]|\$)'; + default: + return null; + } + } } diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 775f6e229..0affa1d7e 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -1,18 +1,19 @@ +import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/core/yat_service.dart'; import 'package:cake_wallet/entities/openalias_record.dart'; import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/entities/emoji_string_extension.dart'; +import 'package:cake_wallet/twitter/twitter_api.dart'; +import 'package:cw_core/crypto_currency.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:cake_wallet/entities/fio_address_provider.dart'; class AddressResolver { - AddressResolver({required this.yatService, required this.walletType}); - final YatService yatService; final WalletType walletType; - + static const unstoppableDomains = [ 'crypto', 'zil', @@ -26,9 +27,28 @@ class AddressResolver { 'blockchain' ]; + static String? extractAddressByType({required String raw, required CryptoCurrency type}) { + final addressPattern = AddressValidator.getAddressFromStringPattern(type); + + if (addressPattern == null) { + throw 'Unexpected token: $type for getAddressFromStringPattern'; + } + + final match = RegExp(addressPattern).firstMatch(raw); + return match?.group(0)?.replaceAll(RegExp('[^0-9a-zA-Z]'), ''); + } + Future resolve(String text, String ticker) async { try { - if (text.contains('@') && !text.contains('.')) { + if (text.startsWith('@') && !text.substring(1).contains('@')) { + final formattedName = text.substring(1); + final twitterUser = await TwitterApi.lookupUserByName(userName: formattedName); + final address = extractAddressByType(raw: twitterUser.description ?? '', type: CryptoCurrency.fromString(ticker)); + if (address != null) { + return ParsedAddress.fetchTwitterAddress(address: address, name: text); + } + } + if (!text.startsWith('@') && text.contains('@') && !text.contains('.')) { final bool isFioRegistered = await FioAddressProvider.checkAvail(text); if (isFioRegistered) { final address = await FioAddressProvider.getPubAddress(text, ticker); @@ -58,7 +78,7 @@ class AddressResolver { final record = await OpenaliasRecord.fetchAddressAndName( formattedName: formattedName, ticker: ticker); return ParsedAddress.fetchOpenAliasAddress(record: record, name: text); - + } catch (e) { print(e.toString()); } diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart index 09cecbf04..afadb7b98 100644 --- a/lib/entities/parsed_address.dart +++ b/lib/entities/parsed_address.dart @@ -1,8 +1,7 @@ import 'package:cake_wallet/entities/openalias_record.dart'; import 'package:cake_wallet/entities/yat_record.dart'; -import 'package:flutter/material.dart'; -enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed } +enum ParseFrom { unstoppableDomains, openAlias, yatRecord, fio, notParsed, twitter } class ParsedAddress { ParsedAddress({ @@ -62,6 +61,14 @@ class ParsedAddress { ); } + factory ParsedAddress.fetchTwitterAddress({required String address, required String name}){ + return ParsedAddress( + addresses: [address], + name: name, + parseFrom: ParseFrom.twitter, + ); + } + final List addresses; final String name; final String description; diff --git a/lib/src/screens/send/widgets/extract_address_from_parsed.dart b/lib/src/screens/send/widgets/extract_address_from_parsed.dart index 4ddd6ada0..1cd7bf0b9 100644 --- a/lib/src/screens/send/widgets/extract_address_from_parsed.dart +++ b/lib/src/screens/send/widgets/extract_address_from_parsed.dart @@ -28,6 +28,11 @@ Future extractAddressFromParsed( content = S.of(context).openalias_alert_content(parsedAddress.name); address = parsedAddress.addresses.first; break; + case ParseFrom.twitter: + title = S.of(context).address_detected; + content = S.of(context).openalias_alert_content(parsedAddress.name); + address = parsedAddress.addresses.first; + break; case ParseFrom.yatRecord: if (parsedAddress.name.isEmpty) { title = S.of(context).yat_error; diff --git a/lib/twitter/twitter_api.dart b/lib/twitter/twitter_api.dart new file mode 100644 index 000000000..bd03e6e00 --- /dev/null +++ b/lib/twitter/twitter_api.dart @@ -0,0 +1,37 @@ +import 'dart:convert'; +import 'package:cake_wallet/twitter/twitter_user.dart'; +import 'package:http/http.dart' as http; +import 'package:cake_wallet/.secrets.g.dart' as secrets; + +class TwitterApi { + static const twitterBearerToken = secrets.twitterBearerToken; + static const httpsScheme = 'https'; + static const apiHost = 'api.twitter.com'; + static const userPath = '/2/users/by/username/'; + + static Future lookupUserByName({required String userName}) async { + final queryParams = {'user.fields': 'description'}; + + final headers = {'authorization': 'Bearer ${secrets.twitterBearerToken}'}; + + final uri = Uri( + scheme: httpsScheme, + host: apiHost, + path: userPath + userName, + queryParameters: queryParams, + ); + + var response = await http.get(uri, headers: headers); + + if (response.statusCode != 200) { + throw Exception('Unexpected http status: ${response.statusCode}'); + } + final responseJSON = json.decode(response.body) as Map; + + if (responseJSON['errors'] != null) { + throw Exception(responseJSON['errors'][0]['detail']); + } + + return TwitterUser.fromJson(responseJSON['data'] as Map); + } +} diff --git a/lib/twitter/twitter_user.dart b/lib/twitter/twitter_user.dart new file mode 100644 index 000000000..c4bda7859 --- /dev/null +++ b/lib/twitter/twitter_user.dart @@ -0,0 +1,16 @@ +class TwitterUser { + TwitterUser({required this.id, required this.username, required this.name, this.description}); + + final String id; + final String username; + final String name; + final String? description; + + factory TwitterUser.fromJson(Map json) { + return TwitterUser( + id: json['id'] as String, + username: json['username'] as String, + name: json['name'] as String, + description: json['description'] as String?); + } +} From 5ef568ec507b47057fb91c7151737cccda3cde60 Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 24 Jan 2023 21:33:09 +0200 Subject: [PATCH 10/27] add keys --- tool/utils/secret_key.dart | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index e5202a829..ca41542ed 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -29,6 +29,9 @@ class SecretKey { SecretKey('anypayToken', () => ''), SecretKey('onramperApiKey', () => ''), SecretKey('ioniaClientId', () => ''), + SecretKey('twitterAPIKey', () => ''), + SecretKey('twitterAPIKeySecret', () => ''), + SecretKey('twitterBearerToken', () => ''), ]; final String name; From ddd5b1ecb3637bf12993198a97723ec9a215ce61 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 25 Jan 2023 15:29:59 +0200 Subject: [PATCH 11/27] Fix QR scheme to compare with currency full name not the abbreviated one --- lib/view_model/send/send_view_model.dart | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index b6604789a..e0ae5dab8 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -180,7 +180,8 @@ abstract class SendViewModelBase with Store { WalletType get walletType => _wallet.type; - String? get walletCurrencyName => _wallet.currency.name?.toLowerCase(); + String? get walletCurrencyName => + _wallet.currency.fullName?.toLowerCase() ?? _wallet.currency.name; bool get hasCurrecyChanger => walletType == WalletType.haven; From 3b23f68b2769df0786c7346795d43e2db18b6ed4 Mon Sep 17 00:00:00 2001 From: Justin Ehrenhofer Date: Wed, 25 Jan 2023 11:09:02 -0600 Subject: [PATCH 12/27] usdcpoly -> usdcmatic for ChangeNOW --- lib/exchange/changenow/changenow_exchange_provider.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index a9fb7c9ca..d8c7bbd14 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -271,6 +271,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider { switch(currency) { case CryptoCurrency.zec: return 'zec'; + case CryptoCurrency.usdcpoly: + return 'usdcmatic'; default: return currency.title.toLowerCase(); } From cce56a61a36bfe3a753aa368d003d1a5037f4828 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 26 Jan 2023 13:33:33 +0200 Subject: [PATCH 13/27] minor fixes --- lib/view_model/exchange/exchange_trade_view_model.dart | 7 ++++--- res/values/strings_ar.arb | 4 ++-- res/values/strings_de.arb | 4 ++-- res/values/strings_en.arb | 4 ++-- res/values/strings_es.arb | 4 ++-- res/values/strings_fr.arb | 4 ++-- res/values/strings_hi.arb | 4 ++-- res/values/strings_hr.arb | 4 ++-- res/values/strings_it.arb | 4 ++-- res/values/strings_ja.arb | 4 ++-- res/values/strings_ko.arb | 4 ++-- res/values/strings_my.arb | 4 +++- res/values/strings_nl.arb | 4 ++-- res/values/strings_pl.arb | 4 ++-- res/values/strings_pt.arb | 4 ++-- res/values/strings_ru.arb | 4 ++-- res/values/strings_th.arb | 4 ++-- res/values/strings_tr.arb | 4 +++- res/values/strings_uk.arb | 4 ++-- res/values/strings_zh.arb | 4 ++-- 20 files changed, 44 insertions(+), 39 deletions(-) diff --git a/lib/view_model/exchange/exchange_trade_view_model.dart b/lib/view_model/exchange/exchange_trade_view_model.dart index 8b578faa5..541b74396 100644 --- a/lib/view_model/exchange/exchange_trade_view_model.dart +++ b/lib/view_model/exchange/exchange_trade_view_model.dart @@ -119,6 +119,8 @@ abstract class ExchangeTradeViewModelBase with Store { } void _updateItems() { + final tagFrom = trade.from.tag != null ? '${trade.from.tag}' + ' ' : ''; + final tagTo = trade.to.tag != null ? '${trade.to.tag}' + ' ' : ''; items.clear(); items.add(ExchangeTradeItem( title: "${trade.provider.title} ${S.current.id}", data: '${trade.id}', isCopied: true)); @@ -135,13 +137,12 @@ abstract class ExchangeTradeViewModelBase with Store { items.addAll([ ExchangeTradeItem(title: S.current.amount, data: '${trade.amount}', isCopied: false), - ExchangeTradeItem(title: S.current.status, data: '${trade.state}', isCopied: false), ExchangeTradeItem( - title: S.current.send_to_this_address('${trade.from} ${trade.from.tag ?? ''}') + ':', + title: S.current.send_to_this_address('${trade.from}', tagFrom) + ':', data: trade.inputAddress ?? '', isCopied: true), ExchangeTradeItem( - title: S.current.arrive_in_this_address('${trade.to} ${trade.to.tag ?? ''}') + ':', + title: S.current.arrive_in_this_address('${trade.to}', tagTo) + ':', data: trade.payoutAddress ?? '', isCopied: true), ]); diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 7d7994b1e..e111bb467 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -679,6 +679,6 @@ "tor_only":"Tor فقط", "unmatched_currencies": "عملة محفظتك الحالية لا تتطابق مع عملة QR الممسوحة ضوئيًا", "orbot_running_alert": "يرجى التأكد من تشغيل Orbot قبل الاتصال بهذه العقدة.", - "send_to_this_address" : "أرسل ${currency} إلى هذا العنوان", - "arrive_in_this_address" : "سيصل ${currency} إلى هذا العنوان" + "send_to_this_address" : "أرسل ${currency} ${tag}إلى هذا العنوان", + "arrive_in_this_address" : "سيصل ${currency} ${tag}إلى هذا العنوان" } diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 8a9e90c5e..018aa7e7c 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Bitte stellen Sie sicher, dass Orbot läuft, bevor Sie sich mit diesem Knoten verbinden.", "contact_list_contacts": "Kontakte", "contact_list_wallets": "Meine Geldbörsen", - "send_to_this_address" : "Senden Sie ${currency} an diese Adresse", - "arrive_in_this_address" : "${currency} wird an dieser Adresse ankommen", + "send_to_this_address" : "Senden Sie ${currency} ${tag}an diese Adresse", + "arrive_in_this_address" : "${currency} ${tag}wird an dieser Adresse ankommen", "do_not_send": "Nicht senden", "error_dialog_content": "Hoppla, wir haben einen Fehler.\n\nBitte senden Sie den Absturzbericht an unser Support-Team, um die Anwendung zu verbessern." } diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 7718f3c39..24baded77 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Please make sure Orbot is running prior to connecting to this node.", "contact_list_contacts": "Contacts", "contact_list_wallets": "My Wallets", - "send_to_this_address" : "Send ${currency} to this address", - "arrive_in_this_address" : "${currency} will arrive in this address", + "send_to_this_address" : "Send ${currency} ${tag}to this address", + "arrive_in_this_address" : "${currency} ${tag}will arrive in this address", "do_not_send": "Don't send", "error_dialog_content": "Oops, we got some error.\n\nPlease send the crash report to our support team to make the application better." } diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 999f0bc47..82889df37 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Asegúrese de que Orbot se esté ejecutando antes de conectarse a este nodo.", "contact_list_contacts": "Contactos", "contact_list_wallets": "Mis billeteras", - "send_to_this_address" : "Enviar ${currency} a esta dirección", - "arrive_in_this_address" : "${currency} llegará a esta dirección", + "send_to_this_address" : "Enviar ${currency} ${tag}a esta dirección", + "arrive_in_this_address" : "${currency} ${tag}llegará a esta dirección", "do_not_send": "no enviar", "error_dialog_content": "Vaya, tenemos un error.\n\nEnvíe el informe de bloqueo a nuestro equipo de soporte para mejorar la aplicación." } diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 7fcf71478..a3288f958 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -679,8 +679,8 @@ "orbot_running_alert": "Veuillez vous assurer qu'Orbot est en cours d'exécution avant de vous connecter à ce nœud.", "contact_list_contacts": "Contacts", "contact_list_wallets": "Mes portefeuilles (wallets)", - "send_to_this_address" : "Envoyez ${currency} à cette adresse", - "arrive_in_this_address" : "${currency} arrivera à cette adresse", + "send_to_this_address" : "Envoyez ${currency} ${tag}à cette adresse", + "arrive_in_this_address" : "${currency} ${tag}arrivera à cette adresse", "do_not_send": "N'envoyez pas", "error_dialog_content": "Oups, nous avons eu une erreur.\n\nVeuillez envoyer le rapport de plantage à notre équipe d'assistance pour améliorer l'application." } diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 9127fb576..7ec7de38d 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "कृपया सुनिश्चित करें कि इस नोड से कनेक्ट करने से पहले Orbot चल रहा है।", "contact_list_contacts": "संपर्क", "contact_list_wallets": "मेरा बटुआ", - "send_to_this_address" : "इस पते पर ${currency} भेजें", - "arrive_in_this_address" : "${currency} इस पते पर पहुंचेंगे", + "send_to_this_address" : "इस पते पर ${currency} ${tag}भेजें", + "arrive_in_this_address" : "${currency} ${tag}इस पते पर पहुंचेंगे", "do_not_send": "मत भेजो", "error_dialog_content": "ओह, हमसे कुछ गड़बड़ी हुई है.\n\nएप्लिकेशन को बेहतर बनाने के लिए कृपया क्रैश रिपोर्ट हमारी सहायता टीम को भेजें।" } diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 0f097a087..79bad1e66 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Provjerite radi li Orbot prije spajanja na ovaj čvor.", "contact_list_contacts": "Kontakti", "contact_list_wallets": "Moji novčanici", - "send_to_this_address" : "Pošaljite ${currency} na ovu adresu", - "arrive_in_this_address" : "${currency} će stići na ovu adresu", + "send_to_this_address" : "Pošaljite ${currency} ${tag}na ovu adresu", + "arrive_in_this_address" : "${currency} ${tag}će stići na ovu adresu", "do_not_send": "Ne šalji", "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju." } diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index 3f78da499..28f502cd6 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Assicurati che Orbot sia in esecuzione prima di connetterti a questo nodo.", "contact_list_contacts": "Contatti", "contact_list_wallets": "I miei portafogli", - "send_to_this_address" : "Invia ${currency} a questo indirizzo", - "arrive_in_this_address" : "${currency} arriverà a questo indirizzo", + "send_to_this_address" : "Invia ${currency} ${tag}a questo indirizzo", + "arrive_in_this_address" : "${currency} ${tag}arriverà a questo indirizzo", "do_not_send": "Non inviare", "error_dialog_content": "Ups, imamo grešku.\n\nPošaljite izvješće o padu našem timu za podršku kako bismo poboljšali aplikaciju." } diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 50aacb432..f1a05b987 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "このノードに接続する前に、Orbot が実行されていることを確認してください", "contact_list_contacts": "連絡先", "contact_list_wallets": "マイウォレット", - "send_to_this_address" : "${currency} をこのアドレスに送金", - "arrive_in_this_address" : "${currency} はこの住所に到着します", + "send_to_this_address" : "${currency} ${tag}をこのアドレスに送金", + "arrive_in_this_address" : "${currency} ${tag}はこの住所に到着します", "do_not_send": "送信しない", "error_dialog_content": "Spiacenti, abbiamo riscontrato un errore.\n\nSi prega di inviare il rapporto sull'arresto anomalo al nostro team di supporto per migliorare l'applicazione." } diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index d84014e55..fa8565e6d 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "이 노드에 연결하기 전에 Orbot이 실행 중인지 확인하십시오.", "contact_list_contacts": "콘택트 렌즈", "contact_list_wallets": "내 지갑", - "send_to_this_address" : "이 주소로 ${currency} 송금", - "arrive_in_this_address" : "${currency}이(가) 이 주소로 도착합니다", + "send_to_this_address" : "이 주소로 ${currency} ${tag}송금", + "arrive_in_this_address" : "${currency} ${tag}이(가) 이 주소로 도착합니다", "do_not_send": "보내지 마세요", "error_dialog_content": "죄송합니다. 오류가 발생했습니다.\n\n응용 프로그램을 개선하려면 지원 팀에 충돌 보고서를 보내주십시오." } diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 352b8d191..0979948c1 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -679,5 +679,7 @@ "tor_only" : "Tor သာ", "unmatched_currencies" : "သင့်လက်ရှိပိုက်ဆံအိတ်၏ငွေကြေးသည် စကင်ဖတ်ထားသော QR နှင့် မကိုက်ညီပါ။", "contact_list_contacts" : "အဆက်အသွယ်များ", - "contact_list_wallets" : "ကျွန်ုပ်၏ ပိုက်ဆံအိတ်များ" + "contact_list_wallets" : "ကျွန်ုပ်၏ ပိုက်ဆံအိတ်များ", + "send_to_this_address" : "ဤလိပ်စာသို့ ${currency} ${tag}သို့ ပို့ပါ။", + "arrive_in_this_address" : "${currency} ${tag}ဤလိပ်စာသို့ ရောက်ရှိပါမည်။" } diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 67613d461..c10b1722f 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Zorg ervoor dat Orbot actief is voordat u verbinding maakt met dit knooppunt.", "contact_list_contacts": "Contacten", "contact_list_wallets": "Mijn portefeuilles", - "send_to_this_address" : "Stuur ${currency} naar dit adres", - "arrive_in_this_address" : "${currency} komt aan op dit adres", + "send_to_this_address" : "Stuur ${currency} ${tag}naar dit adres", + "arrive_in_this_address" : "${currency} ${tag}komt aan op dit adres", "do_not_send": "Niet sturen", "error_dialog_content": "Oeps, er is een fout opgetreden.\n\nStuur het crashrapport naar ons ondersteuningsteam om de applicatie te verbeteren." } diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index a38da0e28..72b93a08b 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Upewnij się, że Orbot działa przed połączeniem z tym węzłem.", "contact_list_contacts": "Łączność", "contact_list_wallets": "Moje portfele", - "send_to_this_address" : "Wyślij ${currency} na ten adres", - "arrive_in_this_address" : "${currency} dotrze na ten adres", + "send_to_this_address" : "Wyślij ${currency} ${tag}na ten adres", + "arrive_in_this_address" : "${currency} ${tag}dotrze na ten adres", "do_not_send": "Nie wysyłaj", "error_dialog_content": "Ups, wystąpił błąd.\n\nPrześlij raport o awarii do naszego zespołu wsparcia, aby ulepszyć aplikację." } diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 8d81eda26..4ed4df754 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -680,8 +680,8 @@ "orbot_running_alert": "Certifique-se de que o Orbot esteja em execução antes de se conectar a este nó.", "contact_list_contacts": "Contatos", "contact_list_wallets": "minhas carteiras", - "send_to_this_address" : "Envie ${currency} para este endereço", - "arrive_in_this_address" : "${currency} chegará neste endereço", + "send_to_this_address" : "Envie ${currency} ${tag}para este endereço", + "arrive_in_this_address" : "${currency} ${tag}chegará neste endereço", "do_not_send": "não envie", "error_dialog_content": "Ops, houve algum erro.\n\nPor favor, envie o relatório de falha para nossa equipe de suporte para melhorar o aplicativo." } diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 161d33580..8482a1bda 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -681,8 +681,8 @@ "orbot_running_alert": "Перед подключением к этому узлу убедитесь, что Orbot запущен.", "contact_list_contacts": "Контакты", "contact_list_wallets": "Мои кошельки", - "send_to_this_address" : "Отправить ${currency} на этот адрес", - "arrive_in_this_address" : "${currency} придет на этот адрес", + "send_to_this_address" : "Отправить ${currency} ${tag}на этот адрес", + "arrive_in_this_address" : "${currency} ${tag}придет на этот адрес", "do_not_send": "Не отправлять", "error_dialog_content": "Ой, у нас какая-то ошибка.\n\nПожалуйста, отправьте отчет о сбое в нашу службу поддержки, чтобы сделать приложение лучше." } diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 0104bbb02..8e108f6c7 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -679,8 +679,8 @@ "orbot_running_alert": "โปรดตรวจสอบว่า Orbot กำลังทำงานก่อนที่จะเชื่อมต่อกับโหนดนี้", "contact_list_contacts": "ติดต่อ", "contact_list_wallets": "กระเป๋าเงินของฉัน", - "send_to_this_address" : "ส่ง ${currency} ไปยังที่อยู่นี้", - "arrive_in_this_address" : "${currency} จะมาถึงที่อยู่นี้", + "send_to_this_address" : "ส่ง ${currency} ${tag}ไปยังที่อยู่นี้", + "arrive_in_this_address" : "${currency} ${tag}จะมาถึงที่อยู่นี้", "do_not_send": "อย่าส่ง", "error_dialog_content": "อ๊ะ เราพบข้อผิดพลาดบางอย่าง\n\nโปรดส่งรายงานข้อขัดข้องไปยังทีมสนับสนุนของเราเพื่อปรับปรุงแอปพลิเคชันให้ดียิ่งขึ้น" } diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 678b3609f..46f7213d4 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -679,5 +679,7 @@ "tor_only": "Yalnızca Tor", "unmatched_currencies": "Mevcut cüzdanınızın para birimi taranan QR ile eşleşmiyor", "contact_list_contacts": "Rehberim", - "contact_list_wallets": "Cüzdanlarım" + "contact_list_wallets": "Cüzdanlarım", + "send_to_this_address" : "Bu adrese ${currency} ${tag}gönder", + "arrive_in_this_address" : "${currency} ${tag}bu adrese ulaşacak" } diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index 1f0c2b2ee..2ed7c7fdb 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -680,8 +680,8 @@ "orbot_running_alert": "Перед підключенням до цього вузла переконайтеся, що Orbot запущено.", "contact_list_contacts": "Контакти", "contact_list_wallets": "Мої гаманці", - "send_to_this_address" : "Надіслати ${currency} на цю адресу", - "arrive_in_this_address" : "${currency} надійде на цю адресу", + "send_to_this_address" : "Надіслати ${currency} ${tag}на цю адресу", + "arrive_in_this_address" : "${currency} ${tag}надійде на цю адресу", "do_not_send": "Не надсилайте", "error_dialog_content": "На жаль, ми отримали помилку.\n\nБудь ласка, надішліть звіт про збій нашій команді підтримки, щоб покращити додаток." } diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index e2e8dd82a..7355ac3bd 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -679,8 +679,8 @@ "orbot_running_alert": "请确保 Orbot 在连接到此节点之前正在运行。", "contact_list_contacts": "联系人", "contact_list_wallets": "我的钱包", - "send_to_this_address" : "发送 ${currency} 到这个地址", - "arrive_in_this_address" : "${currency} 将到达此地址", + "send_to_this_address" : "发送 ${currency} ${tag}到这个地址", + "arrive_in_this_address" : "${currency} ${tag}将到达此地址", "do_not_send": "不要发送", "error_dialog_content": "糟糕,我们遇到了一些错误。\n\n请将崩溃报告发送给我们的支持团队,以改进应用程序。" } From ed30cf1e13668d1d1068e51e69b3a0ededd2e4e2 Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 26 Jan 2023 19:07:19 +0200 Subject: [PATCH 14/27] [skip ci] minor fixes --- .../wallet_address_edit_or_create_view_model.dart | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart index 2cca395ab..a4eb3d386 100644 --- a/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart +++ b/lib/view_model/wallet_address_list/wallet_address_edit_or_create_view_model.dart @@ -105,15 +105,13 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store { await monero!.getSubaddressList(wallet).setLabelSubaddress(wallet, accountIndex: monero!.getCurrentAccount(wallet).id, addressIndex: index, label: label); await wallet.save(); - return; } if (wallet.type == WalletType.haven) { await haven!.getSubaddressList(wallet).setLabelSubaddress(wallet, accountIndex: haven!.getCurrentAccount(wallet).id, - addressIndex: _item?.id as int, + addressIndex: index, label: label); await wallet.save(); - return; } } } From 6825b6e625e9900b1c445711e91195811a55324d Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 26 Jan 2023 20:05:09 +0200 Subject: [PATCH 15/27] minor fixes --- .github/workflows/pr_test_build.yml | 1 + lib/twitter/twitter_api.dart | 2 +- tool/utils/secret_key.dart | 2 -- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index 84ac69197..0f61d11ac 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -110,6 +110,7 @@ jobs: echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart + echo "const ioniaClientId = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart - name: Rename app run: sed -i -e "s/\${APP_NAME}/$GITHUB_HEAD_REF/g" /opt/android/cake_wallet/android/app/src/main/AndroidManifest.xml diff --git a/lib/twitter/twitter_api.dart b/lib/twitter/twitter_api.dart index bd03e6e00..27fb7d1a2 100644 --- a/lib/twitter/twitter_api.dart +++ b/lib/twitter/twitter_api.dart @@ -12,7 +12,7 @@ class TwitterApi { static Future lookupUserByName({required String userName}) async { final queryParams = {'user.fields': 'description'}; - final headers = {'authorization': 'Bearer ${secrets.twitterBearerToken}'}; + final headers = {'authorization': 'Bearer $twitterBearerToken'}; final uri = Uri( scheme: httpsScheme, diff --git a/tool/utils/secret_key.dart b/tool/utils/secret_key.dart index ca41542ed..d0fa39bfc 100644 --- a/tool/utils/secret_key.dart +++ b/tool/utils/secret_key.dart @@ -29,8 +29,6 @@ class SecretKey { SecretKey('anypayToken', () => ''), SecretKey('onramperApiKey', () => ''), SecretKey('ioniaClientId', () => ''), - SecretKey('twitterAPIKey', () => ''), - SecretKey('twitterAPIKeySecret', () => ''), SecretKey('twitterBearerToken', () => ''), ]; From 34db9e5d505d335a4b5478d0ed496934c0f85d1f Mon Sep 17 00:00:00 2001 From: Serhii Date: Thu, 26 Jan 2023 20:20:01 +0200 Subject: [PATCH 16/27] fix key name --- .github/workflows/pr_test_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pr_test_build.yml b/.github/workflows/pr_test_build.yml index 0f61d11ac..c3c61865f 100644 --- a/.github/workflows/pr_test_build.yml +++ b/.github/workflows/pr_test_build.yml @@ -110,7 +110,7 @@ jobs: echo "const onramperApiKey = '${{ secrets.ONRAMPER_API_KEY }}';" >> lib/.secrets.g.dart echo "const anypayToken = '${{ secrets.ANY_PAY_TOKEN }}';" >> lib/.secrets.g.dart echo "const ioniaClientId = '${{ secrets.IONIA_CLIENT_ID }}';" >> lib/.secrets.g.dart - echo "const ioniaClientId = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart + echo "const twitterBearerToken = '${{ secrets.TWITTER_BEARER_TOKEN }}';" >> lib/.secrets.g.dart - name: Rename app run: sed -i -e "s/\${APP_NAME}/$GITHUB_HEAD_REF/g" /opt/android/cake_wallet/android/app/src/main/AndroidManifest.xml From ae0f9df04152e966947db7ff6225fc49411a07e4 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Fri, 27 Jan 2023 03:49:25 +0200 Subject: [PATCH 17/27] Prevent multiple UI errors from showing multiple alerts [skip ci] --- lib/main.dart | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index a8d0064f4..0dcbe6b6d 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -50,6 +50,7 @@ import 'package:cake_wallet/wallet_type_utils.dart'; final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); final RouteObserver routeObserver = RouteObserver(); +bool hasError = false; Future main() async { @@ -206,11 +207,16 @@ void _sendExceptionFile() async { } void _onError(FlutterErrorDetails errorDetails) { + if (hasError) { + return; + } + + hasError = true; _saveException(errorDetails.exception.toString(), errorDetails.stack); WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) { - showPopUp( + (timeStamp) async { + await showPopUp( context: navigatorKey.currentContext!, builder: (context) { return AlertWithTwoActions( @@ -229,6 +235,8 @@ void _onError(FlutterErrorDetails errorDetails) { ); }, ); + + hasError = false; }, ); } From 4353e778bb7b949c5ae23e825dd558b30de2c682 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Sat, 28 Jan 2023 15:47:44 +0200 Subject: [PATCH 18/27] Increase QR version to support longer addresses --- lib/src/screens/receive/widgets/qr_image.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/src/screens/receive/widgets/qr_image.dart b/lib/src/screens/receive/widgets/qr_image.dart index c0c1b0666..9e33080e0 100644 --- a/lib/src/screens/receive/widgets/qr_image.dart +++ b/lib/src/screens/receive/widgets/qr_image.dart @@ -8,7 +8,7 @@ class QrImage extends StatelessWidget { this.size = 100.0, this.backgroundColor, Color foregroundColor = Colors.black, - int version = 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ??? + int version = 13, // Previous value: 9 BTC & LTC wallets addresses are longer than ver. 9 int errorCorrectionLevel = QrErrorCorrectLevel.L, }) : _painter = QrPainter(data, foregroundColor, version, errorCorrectionLevel); From 4704d7060527931bea1c4f2d0218db845e27ffe1 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 30 Jan 2023 19:33:40 +0200 Subject: [PATCH 19/27] Save exceptions if happened while there is an already existing report dialog [skip ci] --- lib/main.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/main.dart b/lib/main.dart index 0dcbe6b6d..af7bb9eff 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -207,12 +207,12 @@ void _sendExceptionFile() async { } void _onError(FlutterErrorDetails errorDetails) { + _saveException(errorDetails.exception.toString(), errorDetails.stack); + if (hasError) { return; } - hasError = true; - _saveException(errorDetails.exception.toString(), errorDetails.stack); WidgetsBinding.instance.addPostFrameCallback( (timeStamp) async { From 425914ade3a04648229c1c045b4b9709046ecbc8 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Mon, 30 Jan 2023 20:03:47 +0200 Subject: [PATCH 20/27] - Replace QR package with another reade made one to exclude error being from painting QR - Revert QR version change so its re-producible if it happens again --- lib/src/screens/receive/widgets/qr_image.dart | 34 +++++++------- .../screens/receive/widgets/qr_painter.dart | 47 ------------------- pubspec_base.yaml | 2 +- 3 files changed, 19 insertions(+), 64 deletions(-) delete mode 100644 lib/src/screens/receive/widgets/qr_painter.dart diff --git a/lib/src/screens/receive/widgets/qr_image.dart b/lib/src/screens/receive/widgets/qr_image.dart index 9e33080e0..3936f847e 100644 --- a/lib/src/screens/receive/widgets/qr_image.dart +++ b/lib/src/screens/receive/widgets/qr_image.dart @@ -1,30 +1,32 @@ import 'package:flutter/material.dart'; -import 'package:qr/qr.dart'; -import 'package:cake_wallet/src/screens/receive/widgets/qr_painter.dart'; +import 'package:qr_flutter/qr_flutter.dart' as qr; class QrImage extends StatelessWidget { QrImage({ - required String data, + required this.data, this.size = 100.0, this.backgroundColor, - Color foregroundColor = Colors.black, - int version = 13, // Previous value: 9 BTC & LTC wallets addresses are longer than ver. 9 - int errorCorrectionLevel = QrErrorCorrectLevel.L, - }) : _painter = QrPainter(data, foregroundColor, version, errorCorrectionLevel); + this.foregroundColor = Colors.black, + this.version = 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ??? + this.errorCorrectionLevel = qr.QrErrorCorrectLevel.L, + }); - final QrPainter _painter; final Color? backgroundColor; final double size; + final String data; + final int version; + final int errorCorrectionLevel; + final Color foregroundColor; @override Widget build(BuildContext context) { - return Container( - width: size, - height: size, - color: backgroundColor, - child: CustomPaint( - painter: _painter, - ), + return qr.QrImage( + data: data, + errorCorrectionLevel: errorCorrectionLevel, + version: version, + size: size, + foregroundColor: foregroundColor, + padding: EdgeInsets.zero, ); } -} \ No newline at end of file +} diff --git a/lib/src/screens/receive/widgets/qr_painter.dart b/lib/src/screens/receive/widgets/qr_painter.dart deleted file mode 100644 index e4af59f1a..000000000 --- a/lib/src/screens/receive/widgets/qr_painter.dart +++ /dev/null @@ -1,47 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:qr/qr.dart'; - -class QrPainter extends CustomPainter { - QrPainter( - String data, - this.color, - this.version, - this.errorCorrectionLevel, - ) : this._qr = QrCode(version, errorCorrectionLevel)..addData(data) { - _p.color = this.color; - _qrImage = QrImage(_qr); - } - - final int version; - final int errorCorrectionLevel; - final Color color; - - final QrCode _qr; - final _p = Paint()..style = PaintingStyle.fill; - late QrImage _qrImage; - - @override - void paint(Canvas canvas, Size size) { - final squareSize = size.shortestSide / _qr.moduleCount; - for (int x = 0; x < _qr.moduleCount; x++) { - for (int y = 0; y < _qr.moduleCount; y++) { - if (_qrImage.isDark(y, x)) { - final squareRect = Rect.fromLTWH( - x * squareSize, y * squareSize, squareSize, squareSize); - canvas.drawRect(squareRect, _p); - } - } - } - } - - @override - bool shouldRepaint(CustomPainter oldDelegate) { - if (oldDelegate is QrPainter) { - return this.color != oldDelegate.color || - this.errorCorrectionLevel != oldDelegate.errorCorrectionLevel || - this.version != oldDelegate.version; - } - - return false; - } -} diff --git a/pubspec_base.yaml b/pubspec_base.yaml index b37fd519c..2caa9052f 100644 --- a/pubspec_base.yaml +++ b/pubspec_base.yaml @@ -6,7 +6,7 @@ dependencies: flutter_cupertino_localizations: ^1.0.1 intl: ^0.17.0 url_launcher: ^6.1.4 - qr: ^3.0.1 + qr_flutter: ^4.0.0 uuid: 3.0.6 shared_preferences: ^2.0.15 flutter_secure_storage: From 9869cd60cc38fef4d9a3f919e1b27ceebad1ad97 Mon Sep 17 00:00:00 2001 From: Serhii Date: Mon, 30 Jan 2023 21:15:10 +0200 Subject: [PATCH 21/27] udate alert text --- lib/entities/parse_address_from_domain.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 0affa1d7e..6e46e5a66 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -45,7 +45,7 @@ class AddressResolver { final twitterUser = await TwitterApi.lookupUserByName(userName: formattedName); final address = extractAddressByType(raw: twitterUser.description ?? '', type: CryptoCurrency.fromString(ticker)); if (address != null) { - return ParsedAddress.fetchTwitterAddress(address: address, name: text); + return ParsedAddress.fetchTwitterAddress(address: address, name: '$text on Twitter'); } } if (!text.startsWith('@') && text.contains('@') && !text.contains('.')) { From 50d19e706fd97b4789278230ebeea8ff6df1064c Mon Sep 17 00:00:00 2001 From: Justin Ehrenhofer Date: Mon, 30 Jan 2023 14:05:17 -0600 Subject: [PATCH 22/27] Fix bttc, maticpoly, matic bttc mapped to trx, so changed the label instead of changing the mapping maticpoly was mislabeled on changenow maticpoly and matic were mislabeled on simpleswap --- cw_core/lib/crypto_currency.dart | 2 +- lib/exchange/changenow/changenow_exchange_provider.dart | 2 ++ lib/exchange/simpleswap/simpleswap_exchange_provider.dart | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cw_core/lib/crypto_currency.dart b/cw_core/lib/crypto_currency.dart index 85331ee31..90051f1f7 100644 --- a/cw_core/lib/crypto_currency.dart +++ b/cw_core/lib/crypto_currency.dart @@ -119,7 +119,7 @@ class CryptoCurrency extends EnumerableItem with Serializable { static const ape = CryptoCurrency(title: 'APE', tag: 'ETH', fullName: 'ApeCoin', raw: 30, name: 'ape', iconPath: 'assets/images/ape_icon.png'); static const avaxc = CryptoCurrency(title: 'AVAX', tag: 'C-CHAIN', raw: 31, name: 'avaxc', iconPath: 'assets/images/avaxc_icon.png'); static const btt = CryptoCurrency(title: 'BTT', tag: 'ETH', fullName: 'BitTorrent', raw: 32, name: 'btt', iconPath: 'assets/images/btt_icon.png'); - static const bttc = CryptoCurrency(title: 'BTTC', tag: 'BSC', fullName: 'BitTorrent-NEW', raw: 33, name: 'bttc', iconPath: 'assets/images/bttbsc_icon.png'); + static const bttc = CryptoCurrency(title: 'BTTC', tag: 'TRX', fullName: 'BitTorrent-NEW', raw: 33, name: 'bttc', iconPath: 'assets/images/bttbsc_icon.png'); static const doge = CryptoCurrency(title: 'DOGE', fullName: 'Dogecoin', raw: 34, name: 'doge', iconPath: 'assets/images/doge_icon.png'); static const firo = CryptoCurrency(title: 'FIRO', raw: 35, name: 'firo', iconPath: 'assets/images/firo_icon.png'); static const usdttrc20 = CryptoCurrency(title: 'USDT', tag: 'TRX', fullName: 'USDT Tether', raw: 36, name: 'usdttrc20', iconPath: 'assets/images/usdttrc20_icon.png'); diff --git a/lib/exchange/changenow/changenow_exchange_provider.dart b/lib/exchange/changenow/changenow_exchange_provider.dart index d8c7bbd14..8eed66cf0 100644 --- a/lib/exchange/changenow/changenow_exchange_provider.dart +++ b/lib/exchange/changenow/changenow_exchange_provider.dart @@ -273,6 +273,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider { return 'zec'; case CryptoCurrency.usdcpoly: return 'usdcmatic'; + case CryptoCurrency.maticpoly: + return 'maticmainnet'; default: return currency.title.toLowerCase(); } diff --git a/lib/exchange/simpleswap/simpleswap_exchange_provider.dart b/lib/exchange/simpleswap/simpleswap_exchange_provider.dart index 2521c1486..6e57e8fc3 100644 --- a/lib/exchange/simpleswap/simpleswap_exchange_provider.dart +++ b/lib/exchange/simpleswap/simpleswap_exchange_provider.dart @@ -231,6 +231,10 @@ class SimpleSwapExchangeProvider extends ExchangeProvider { return 'usdcpoly'; case CryptoCurrency.usdcsol: return 'usdcspl'; + case CryptoCurrency.matic: + return 'maticerc20'; + case CryptoCurrency.maticpoly: + return 'matic'; default: return currency.title.toLowerCase(); } From 81f59cacd984533700376db5ffc7218d48b52ded Mon Sep 17 00:00:00 2001 From: Justin Ehrenhofer Date: Mon, 30 Jan 2023 15:18:19 -0600 Subject: [PATCH 23/27] Change to parentheses This way we don't need to translate and create different strings for the "on", which will appear odd in languages other than English. I also added it for FIO and OpenAlias. Further, I removed the 1 instance of openalias_alert_title. It can be removed from the localization file if/when it's convenient. I did NOT change anything for Unstoppable, because that appeared to touch a dependency. That has its own custom (but similar) text response --- lib/entities/parse_address_from_domain.dart | 6 +++--- .../screens/send/widgets/extract_address_from_parsed.dart | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 6e46e5a66..a52613d46 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -45,14 +45,14 @@ class AddressResolver { final twitterUser = await TwitterApi.lookupUserByName(userName: formattedName); final address = extractAddressByType(raw: twitterUser.description ?? '', type: CryptoCurrency.fromString(ticker)); if (address != null) { - return ParsedAddress.fetchTwitterAddress(address: address, name: '$text on Twitter'); + return ParsedAddress.fetchTwitterAddress(address: address, name: '$text (Twitter)'); } } if (!text.startsWith('@') && text.contains('@') && !text.contains('.')) { final bool isFioRegistered = await FioAddressProvider.checkAvail(text); if (isFioRegistered) { final address = await FioAddressProvider.getPubAddress(text, ticker); - return ParsedAddress.fetchFioAddress(address: address, name: text); + return ParsedAddress.fetchFioAddress(address: address, name: '$text (FIO)'); } } @@ -77,7 +77,7 @@ class AddressResolver { final record = await OpenaliasRecord.fetchAddressAndName( formattedName: formattedName, ticker: ticker); - return ParsedAddress.fetchOpenAliasAddress(record: record, name: text); + return ParsedAddress.fetchOpenAliasAddress(record: record, name: '$text (OpenAlias)'); } catch (e) { print(e.toString()); diff --git a/lib/src/screens/send/widgets/extract_address_from_parsed.dart b/lib/src/screens/send/widgets/extract_address_from_parsed.dart index 1cd7bf0b9..dcb0edc89 100644 --- a/lib/src/screens/send/widgets/extract_address_from_parsed.dart +++ b/lib/src/screens/send/widgets/extract_address_from_parsed.dart @@ -19,7 +19,7 @@ Future extractAddressFromParsed( address = parsedAddress.addresses.first; break; case ParseFrom.openAlias: - title = S.of(context).openalias_alert_title; + title = S.of(context).address_detected; content = S.of(context).openalias_alert_content(parsedAddress.name); address = parsedAddress.addresses.first; break; From 0e9d30c915b5295c600b5b5d468dd41a1fd179f6 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Tue, 31 Jan 2023 17:31:42 +0200 Subject: [PATCH 24/27] Fixate QR background and foreground colors in all themes --- lib/src/screens/exchange_trade/exchange_trade_page.dart | 9 +-------- lib/src/screens/receive/fullscreen_qr_page.dart | 9 ++------- lib/src/screens/receive/widgets/qr_image.dart | 7 ++----- lib/src/screens/receive/widgets/qr_widget.dart | 6 +----- 4 files changed, 6 insertions(+), 25 deletions(-) diff --git a/lib/src/screens/exchange_trade/exchange_trade_page.dart b/lib/src/screens/exchange_trade/exchange_trade_page.dart index 5aacf3f1f..1fe4983f6 100644 --- a/lib/src/screens/exchange_trade/exchange_trade_page.dart +++ b/lib/src/screens/exchange_trade/exchange_trade_page.dart @@ -165,14 +165,7 @@ class ExchangeTradeState extends State { .color! ) ), - child: QrImage( - data: trade.inputAddress ?? fetchingLabel, - backgroundColor: Colors.transparent, - foregroundColor: Theme.of(context) - .accentTextTheme! - .subtitle2! - .color!, - ), + child: QrImage(data: trade.inputAddress ?? fetchingLabel), )))), Spacer(flex: 3) ]), diff --git a/lib/src/screens/receive/fullscreen_qr_page.dart b/lib/src/screens/receive/fullscreen_qr_page.dart index 165adff12..0966c8ac8 100644 --- a/lib/src/screens/receive/fullscreen_qr_page.dart +++ b/lib/src/screens/receive/fullscreen_qr_page.dart @@ -1,7 +1,6 @@ import 'package:cake_wallet/src/screens/receive/widgets/qr_image.dart'; import 'package:cake_wallet/themes/theme_base.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/cupertino.dart'; import 'package:cake_wallet/src/screens/base_page.dart'; class FullscreenQRPage extends BasePage { @@ -69,14 +68,10 @@ class FullscreenQRPage extends BasePage { child: AspectRatio( aspectRatio: 1.0, child: Container( - padding: EdgeInsets.all(5), + padding: EdgeInsets.all(10), decoration: BoxDecoration( border: Border.all(width: 3, color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!)), - child: QrImage( - data: qrData, - backgroundColor: isLight ? Colors.transparent : Colors.black, - foregroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!, - ), + child: QrImage(data: qrData), ), ), ), diff --git a/lib/src/screens/receive/widgets/qr_image.dart b/lib/src/screens/receive/widgets/qr_image.dart index 3936f847e..6e17dbcfc 100644 --- a/lib/src/screens/receive/widgets/qr_image.dart +++ b/lib/src/screens/receive/widgets/qr_image.dart @@ -5,18 +5,14 @@ class QrImage extends StatelessWidget { QrImage({ required this.data, this.size = 100.0, - this.backgroundColor, - this.foregroundColor = Colors.black, this.version = 9, // Previous value: 7 something happened after flutter upgrade monero wallets addresses are longer than ver. 7 ??? this.errorCorrectionLevel = qr.QrErrorCorrectLevel.L, }); - final Color? backgroundColor; final double size; final String data; final int version; final int errorCorrectionLevel; - final Color foregroundColor; @override Widget build(BuildContext context) { @@ -25,7 +21,8 @@ class QrImage extends StatelessWidget { errorCorrectionLevel: errorCorrectionLevel, version: version, size: size, - foregroundColor: foregroundColor, + foregroundColor: Colors.black, + backgroundColor: Colors.white, padding: EdgeInsets.zero, ); } diff --git a/lib/src/screens/receive/widgets/qr_widget.dart b/lib/src/screens/receive/widgets/qr_widget.dart index 99bea1adc..a590293a6 100644 --- a/lib/src/screens/receive/widgets/qr_widget.dart +++ b/lib/src/screens/receive/widgets/qr_widget.dart @@ -89,11 +89,7 @@ class QRWidget extends StatelessWidget { color: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!, ), ), - child: QrImage( - data: addressListViewModel.uri.toString(), - backgroundColor: isLight ? Colors.transparent : Colors.black, - foregroundColor: Theme.of(context).accentTextTheme!.headline2!.backgroundColor!, - ), + child: QrImage(data: addressListViewModel.uri.toString()), ), ), ), From ef01554fdbfbf47bc042aaf42403a8aa84526bde Mon Sep 17 00:00:00 2001 From: Serhii Date: Tue, 31 Jan 2023 21:39:08 +0200 Subject: [PATCH 25/27] fix openAlias address resolv --- lib/entities/openalias_record.dart | 102 +++++++++--------- lib/entities/parse_address_from_domain.dart | 45 ++++---- lib/entities/parsed_address.dart | 6 +- .../widgets/extract_address_from_parsed.dart | 6 +- res/values/strings_ar.arb | 1 - res/values/strings_de.arb | 1 - res/values/strings_en.arb | 1 - res/values/strings_es.arb | 1 - res/values/strings_fr.arb | 1 - res/values/strings_hi.arb | 1 - res/values/strings_hr.arb | 1 - res/values/strings_it.arb | 1 - res/values/strings_ja.arb | 1 - res/values/strings_ko.arb | 1 - res/values/strings_my.arb | 1 - res/values/strings_nl.arb | 1 - res/values/strings_pl.arb | 1 - res/values/strings_pt.arb | 1 - res/values/strings_ru.arb | 1 - res/values/strings_th.arb | 1 - res/values/strings_tr.arb | 1 - res/values/strings_uk.arb | 1 - res/values/strings_zh.arb | 1 - 23 files changed, 79 insertions(+), 99 deletions(-) diff --git a/lib/entities/openalias_record.dart b/lib/entities/openalias_record.dart index 9e2b3f680..842a711fe 100644 --- a/lib/entities/openalias_record.dart +++ b/lib/entities/openalias_record.dart @@ -1,5 +1,4 @@ import 'package:basic_utils/basic_utils.dart'; -import 'package:cw_core/wallet_type.dart'; class OpenaliasRecord { OpenaliasRecord({ @@ -22,69 +21,68 @@ class OpenaliasRecord { return formattedName; } - static Future fetchAddressAndName({ + static Future?> lookupOpenAliasRecord(String name) async { + try { + final txtRecord = await DnsUtils.lookupRecord(name, RRecordType.TXT, dnssec: true); + + return txtRecord; + } catch (e) { + print("${e.toString()}"); + return null; + } + } + + static OpenaliasRecord fetchAddressAndName({ required String formattedName, required String ticker, - }) async { + required List txtRecord, + }) { String address = formattedName; String name = formattedName; String note = ''; - if (formattedName.contains(".")) { - try { - final txtRecord = await DnsUtils.lookupRecord( - formattedName, RRecordType.TXT, - dnssec: true); + for (RRecord element in txtRecord) { + String record = element.data; - if (txtRecord != null) { - for (RRecord element in txtRecord) { - String record = element.data; + if (record.contains("oa1:$ticker") && record.contains("recipient_address")) { + record = record.replaceAll('\"', ""); - if (record.contains("oa1:$ticker") && - 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:$ticker recipient_address=", "") + .replaceAll("(", "") + .replaceAll(")", "") + .trim(); - address = dataList - .where((item) => (item.contains("recipient_address"))) - .toString() - .replaceAll("oa1:$ticker 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) { - name = recipientName.replaceAll("recipient_name=", ""); - } - - final description = dataList - .where((item) => (item.contains("tx_description"))) - .toString() - .replaceAll("(", "") - .replaceAll(")", "") - .trim(); - - if (description.isNotEmpty) { - note = description.replaceAll("tx_description=", ""); - } - - break; - } - } + if (recipientName.isNotEmpty) { + name = recipientName.replaceAll("recipient_name=", ""); } - } catch (e) { - print("${e.toString()}"); - } - } - return OpenaliasRecord(address: address, name: name, description: note); + final description = dataList + .where((item) => (item.contains("tx_description"))) + .toString() + .replaceAll("(", "") + .replaceAll(")", "") + .trim(); + + if (description.isNotEmpty) { + note = description.replaceAll("tx_description=", ""); + } + + break; + } + } + return OpenaliasRecord(address: address, name: name, description: note); +} } diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index a52613d46..6574d26fd 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -11,21 +11,22 @@ import 'package:cake_wallet/entities/fio_address_provider.dart'; class AddressResolver { AddressResolver({required this.yatService, required this.walletType}); + final YatService yatService; final WalletType walletType; static const unstoppableDomains = [ - 'crypto', - 'zil', - 'x', - 'coin', - 'wallet', - 'bitcoin', - '888', - 'nft', - 'dao', - 'blockchain' -]; + 'crypto', + 'zil', + 'x', + 'coin', + 'wallet', + 'bitcoin', + '888', + 'nft', + 'dao', + 'blockchain' + ]; static String? extractAddressByType({required String raw, required CryptoCurrency type}) { final addressPattern = AddressValidator.getAddressFromStringPattern(type); @@ -43,18 +44,18 @@ class AddressResolver { if (text.startsWith('@') && !text.substring(1).contains('@')) { final formattedName = text.substring(1); final twitterUser = await TwitterApi.lookupUserByName(userName: formattedName); - final address = extractAddressByType(raw: twitterUser.description ?? '', type: CryptoCurrency.fromString(ticker)); + final address = extractAddressByType( + raw: twitterUser.description ?? '', type: CryptoCurrency.fromString(ticker)); if (address != null) { - return ParsedAddress.fetchTwitterAddress(address: address, name: '$text (Twitter)'); + return ParsedAddress.fetchTwitterAddress(address: address, name: text); } } if (!text.startsWith('@') && text.contains('@') && !text.contains('.')) { final bool isFioRegistered = await FioAddressProvider.checkAvail(text); if (isFioRegistered) { final address = await FioAddressProvider.getPubAddress(text, ticker); - return ParsedAddress.fetchFioAddress(address: address, name: '$text (FIO)'); - } - + return ParsedAddress.fetchFioAddress(address: address, name: text); + } } if (text.hasOnlyEmojis) { if (walletType != WalletType.haven) { @@ -75,10 +76,14 @@ class AddressResolver { return ParsedAddress.fetchUnstoppableDomainAddress(address: address, name: text); } - final record = await OpenaliasRecord.fetchAddressAndName( - formattedName: formattedName, ticker: ticker); - return ParsedAddress.fetchOpenAliasAddress(record: record, name: '$text (OpenAlias)'); - + if (formattedName.contains(".")) { + final txtRecord = await OpenaliasRecord.lookupOpenAliasRecord(formattedName); + if (txtRecord != null) { + final record = await OpenaliasRecord.fetchAddressAndName( + formattedName: formattedName, ticker: ticker, txtRecord: txtRecord); + return ParsedAddress.fetchOpenAliasAddress(record: record, name: text); + } + } } catch (e) { print(e.toString()); } diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart index afadb7b98..a73b44e33 100644 --- a/lib/entities/parsed_address.dart +++ b/lib/entities/parsed_address.dart @@ -40,11 +40,7 @@ class ParsedAddress { ); } - factory ParsedAddress.fetchOpenAliasAddress({OpenaliasRecord? record, required String name}){ - final formattedName = OpenaliasRecord.formatDomainName(name); - if (record == null || record.address.contains(formattedName)) { - return ParsedAddress(addresses: [name]); - } + factory ParsedAddress.fetchOpenAliasAddress({required OpenaliasRecord record, required String name}){ return ParsedAddress( addresses: [record.address], name: record.name, diff --git a/lib/src/screens/send/widgets/extract_address_from_parsed.dart b/lib/src/screens/send/widgets/extract_address_from_parsed.dart index dcb0edc89..ab5778739 100644 --- a/lib/src/screens/send/widgets/extract_address_from_parsed.dart +++ b/lib/src/screens/send/widgets/extract_address_from_parsed.dart @@ -20,17 +20,17 @@ Future extractAddressFromParsed( break; case ParseFrom.openAlias: title = S.of(context).address_detected; - content = S.of(context).openalias_alert_content(parsedAddress.name); + content = S.of(context).openalias_alert_content('${parsedAddress.name} (OpenAlias)'); address = parsedAddress.addresses.first; break; case ParseFrom.fio: title = S.of(context).address_detected; - content = S.of(context).openalias_alert_content(parsedAddress.name); + content = S.of(context).openalias_alert_content('${parsedAddress.name} (FIO)'); address = parsedAddress.addresses.first; break; case ParseFrom.twitter: title = S.of(context).address_detected; - content = S.of(context).openalias_alert_content(parsedAddress.name); + content = S.of(context).openalias_alert_content('${parsedAddress.name} (Twitter)'); address = parsedAddress.addresses.first; break; case ParseFrom.yatRecord: diff --git a/res/values/strings_ar.arb b/res/values/strings_ar.arb index 250f29a70..e7f4386b0 100644 --- a/res/values/strings_ar.arb +++ b/res/values/strings_ar.arb @@ -398,7 +398,6 @@ "biometric_auth_reason":"امسح بصمة إصبعك للمصادقة", "version":"الإصدار ${currentVersion}", - "openalias_alert_title":"تم ايجاد العنوان", "openalias_alert_content":"سوف ترسل الأموال إلى\n${recipient_name}", "card_address":"العنوان:", diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index a3fd4f585..b57a4374e 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Scannen Sie Ihren Fingerabdruck zur Authentifizierung", "version" : "Version ${currentVersion}", - "openalias_alert_title" : "Adresse Erkannt", "openalias_alert_content" : "Sie senden Geld an\n${recipient_name}", "card_address" : "Adresse:", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 87629cbd8..8bfeb0193 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Scan your fingerprint to authenticate", "version" : "Version ${currentVersion}", - "openalias_alert_title" : "Address Detected", "openalias_alert_content" : "You will be sending funds to\n${recipient_name}", "card_address" : "Address:", diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index b6d4cd358..90f0f5293 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Escanee su huella digital para autenticar", "version" : "Versión ${currentVersion}", - "openalias_alert_title" : "Destinatario detectado", "openalias_alert_content" : "Enviará fondos a\n${recipient_name}", "card_address" : "Dirección:", diff --git a/res/values/strings_fr.arb b/res/values/strings_fr.arb index 7b9e8da07..2b65a919e 100644 --- a/res/values/strings_fr.arb +++ b/res/values/strings_fr.arb @@ -396,7 +396,6 @@ "biometric_auth_reason" : "Scannez votre empreinte digitale pour vous authentifier", "version" : "Version ${currentVersion}", - "openalias_alert_title" : "Adresse Détectée", "openalias_alert_content" : "Vous allez envoyer des fonds à\n${recipient_name}", "card_address" : "Adresse :", diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index c8e454aae..044e72b52 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "प्रमाणित करने के लिए अपने फ़िंगरप्रिंट को स्कैन करें", "version" : "संस्करण ${currentVersion}", - "openalias_alert_title" : "पता मिला", "openalias_alert_content" : "आपको धनराशि भेजी जाएगी\n${recipient_name}", "card_address" : "पता:", diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index 239a175c2..74177bd50 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Skenirajte svoj otisak prsta za autentifikaciju", "version" : "Verzija ${currentVersion}", - "openalias_alert_title" : "Otkrivena je adresa", "openalias_alert_content" : "Poslat ćete sredstva primatelju\n${recipient_name}", "card_address" : "Adresa:", diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index f3ddf8af2..ebbf11bf9 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Scansiona la tua impronta per autenticarti", "version" : "Versione ${currentVersion}", - "openalias_alert_title" : "Indirizzo Rilevato", "openalias_alert_content" : "Invierai i tuoi fondi a\n${recipient_name}", "card_address" : "Indirizzo:", diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index b3746aaa1..6bb31cc95 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "प指紋をスキャンして認証する", "version" : "バージョン ${currentVersion}", - "openalias_alert_title" : "アドレスが検出されました", "openalias_alert_content" : "に送金します\n${recipient_name}", "card_address" : "住所:", diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index db6778fd6..d538b99a7 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "지문을 스캔하여 인증", "version" : "버전 ${currentVersion}", - "openalias_alert_title" : "주소 감지됨", "openalias_alert_content" : "당신은에 자금을 보낼 것입니다\n${recipient_name}", "card_address" : "주소:", diff --git a/res/values/strings_my.arb b/res/values/strings_my.arb index 352b8d191..a10c1d18d 100644 --- a/res/values/strings_my.arb +++ b/res/values/strings_my.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "စစ်မှန်ကြောင်းအထောက်အထားပြရန် သင့်လက်ဗွေကို စကန်ဖတ်ပါ။", "version" : "ဗားရှင်း ${currentVersion}", - "openalias_alert_title" : "လိပ်စာကို ရှာတွေ့သည်။", "openalias_alert_content" : "သင်သည် \n${recipient_name} သို့ ရန်ပုံငွေများ ပေးပို့ပါမည်", "card_address" : "လိပ်စာ-", diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index faac8f702..6a28e108b 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Scan uw vingerafdruk om te verifiëren", "version" : "Versie ${currentVersion}", - "openalias_alert_title" : "Adres Gedetecteerd", "openalias_alert_content" : "U stuurt geld naar\n${recipient_name}", "card_address" : "Adres:", diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 0f0e14959..5320c6981 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Zeskanuj swój odcisk palca, aby uwierzytelnić", "version" : "Wersja ${currentVersion}", - "openalias_alert_title" : "Wykryto Adres", "openalias_alert_content" : "Wysyłasz środki na\n${recipient_name}", "card_address" : "Adres:", diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 90d477369..c3d4eb986 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Digitalize sua impressão digital para autenticar", "version" : "Versão ${currentVersion}", - "openalias_alert_title" : "Endereço Detectado", "openalias_alert_content" : "Você enviará fundos para\n${recipient_name}", "card_address" : "Endereço:", diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 8789dd4a0..47a1f0309 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Отсканируйте свой отпечаток пальца для аутентификации", "version" : "Версия ${currentVersion}", - "openalias_alert_title" : "Адрес Обнаружен", "openalias_alert_content" : "Вы будете отправлять средства\n${recipient_name}", "card_address" : "Адрес:", diff --git a/res/values/strings_th.arb b/res/values/strings_th.arb index 5e1428fac..54002b73d 100644 --- a/res/values/strings_th.arb +++ b/res/values/strings_th.arb @@ -396,7 +396,6 @@ "biometric_auth_reason" : "สแกนลายนิ้วมือของคุณเพื่อยืนยันตัวตน", "version" : "เวอร์ชัน ${currentVersion}", - "openalias_alert_title" : "พบที่อยู่", "openalias_alert_content" : "คุณกำลังจะส่งเงินไปยัง\n${recipient_name}", "card_address" : "ที่อยู่:", diff --git a/res/values/strings_tr.arb b/res/values/strings_tr.arb index 678b3609f..3975451b0 100644 --- a/res/values/strings_tr.arb +++ b/res/values/strings_tr.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "Kimlik doğrulaması için parmak izini okutun", "version" : "Sürüm ${currentVersion}", - "openalias_alert_title" : "Adres tespit edildi", "openalias_alert_content" : "Parayı buraya gönderceksin:\n${recipient_name}", "card_address" : "Adres:", diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index b6ac3a511..ebd2ada04 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -397,7 +397,6 @@ "biometric_auth_reason" : "Відскануйте свій відбиток пальця для аутентифікації", "version" : "Версія ${currentVersion}", - "openalias_alert_title" : "Виявлено адресу", "openalias_alert_content" : "Ви будете відправляти кошти\n${recipient_name}", "card_address" : "Адреса:", diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index ba2f3f839..71acbed61 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -398,7 +398,6 @@ "biometric_auth_reason" : "扫描指纹进行身份认证", "version" : "版本 ${currentVersion}", - "openalias_alert_title" : "检测到地址", "openalias_alert_content" : "您将汇款至\n${recipient_name}", "card_address" : "地址:", From 08ff37e23c1f6992dba1a717df7ddce57143dc04 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 1 Feb 2023 17:24:36 +0200 Subject: [PATCH 26/27] Add Exception for user's network issues to not be reported [skip ci] --- lib/main.dart | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/main.dart b/lib/main.dart index af7bb9eff..720865060 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -207,6 +207,11 @@ void _sendExceptionFile() async { } void _onError(FlutterErrorDetails errorDetails) { + // Add Exception for user's network connection issues to not be reported + if (errorDetails.exception.toString().contains("Software caused connection abort")) { + return; + } + _saveException(errorDetails.exception.toString(), errorDetails.stack); if (hasError) { From 15e7395fe9084b7d15a3501246f85f1c60cd2596 Mon Sep 17 00:00:00 2001 From: OmarHatem Date: Wed, 1 Feb 2023 17:37:18 +0200 Subject: [PATCH 27/27] Separate Exception Handler class from main [skip ci] --- lib/main.dart | 108 ++----------------------------- lib/utils/exception_handler.dart | 104 +++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 104 deletions(-) create mode 100644 lib/utils/exception_handler.dart diff --git a/lib/main.dart b/lib/main.dart index 720865060..7ba1f204a 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,22 +1,12 @@ import 'dart:async'; -import 'dart:convert'; -import 'dart:io'; -import 'dart:isolate'; -import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/entities/language_service.dart'; import 'package:cake_wallet/buy/order.dart'; -import 'package:cake_wallet/entities/preferences_key.dart'; -import 'package:cake_wallet/ionia/ionia_category.dart'; -import 'package:cake_wallet/ionia/ionia_merchant.dart'; -import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/store/yat/yat_store.dart'; -import 'package:cake_wallet/themes/theme_list.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:cake_wallet/utils/exception_handler.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_mailer/flutter_mailer.dart'; import 'package:hive/hive.dart'; import 'package:cake_wallet/di.dart'; import 'package:path_provider/path_provider.dart'; @@ -50,21 +40,18 @@ import 'package:cake_wallet/wallet_type_utils.dart'; final navigatorKey = GlobalKey(); final rootKey = GlobalKey(); final RouteObserver routeObserver = RouteObserver(); -bool hasError = false; Future main() async { await runZonedGuarded(() async { WidgetsFlutterBinding.ensureInitialized(); - FlutterError.onError = (errorDetails) { - _onError(errorDetails); - }; + FlutterError.onError = ExceptionHandler.onError; /// A callback that is invoked when an unhandled error occurs in the root /// isolate. PlatformDispatcher.instance.onError = (error, stack) { - _onError(FlutterErrorDetails(exception: error, stack: stack)); + ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stack)); return true; }; @@ -155,97 +142,10 @@ Future main() async { initialMigrationVersion: 19); runApp(App()); }, (error, stackTrace) async { - _onError(FlutterErrorDetails(exception: error, stack: stackTrace)); + ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace)); }); } -void _saveException(String? error, StackTrace? stackTrace) async { - final appDocDir = await getApplicationDocumentsDirectory(); - - final file = File('${appDocDir.path}/error.txt'); - final exception = { - "${DateTime.now()}": { - "Error": error, - "StackTrace": stackTrace.toString(), - } - }; - - const String separator = - '''\n\n========================================================== - ==========================================================\n\n'''; - - await file.writeAsString( - jsonEncode(exception) + separator, - mode: FileMode.append, - ); -} - -void _sendExceptionFile() async { - try { - final appDocDir = await getApplicationDocumentsDirectory(); - - final file = File('${appDocDir.path}/error.txt'); - - final MailOptions mailOptions = MailOptions( - subject: 'Mobile App Issue', - recipients: ['support@cakewallet.com'], - attachments: [file.path], - ); - - final result = await FlutterMailer.send(mailOptions); - - // Clear file content if the error was sent or saved. - // On android we can't know if it was sent or saved - if (result.name == MailerResponse.sent.name || - result.name == MailerResponse.saved.name || - result.name == MailerResponse.android.name) { - file.writeAsString("", mode: FileMode.write); - } - } catch (e, s) { - _saveException(e.toString(), s); - } -} - -void _onError(FlutterErrorDetails errorDetails) { - // Add Exception for user's network connection issues to not be reported - if (errorDetails.exception.toString().contains("Software caused connection abort")) { - return; - } - - _saveException(errorDetails.exception.toString(), errorDetails.stack); - - if (hasError) { - return; - } - hasError = true; - - WidgetsBinding.instance.addPostFrameCallback( - (timeStamp) async { - await showPopUp( - context: navigatorKey.currentContext!, - builder: (context) { - return AlertWithTwoActions( - isDividerExist: true, - alertTitle: S.of(context).error, - alertContent: S.of(context).error_dialog_content, - rightButtonText: S.of(context).send, - leftButtonText: S.of(context).do_not_send, - actionRightButton: () { - Navigator.of(context).pop(); - _sendExceptionFile(); - }, - actionLeftButton: () { - Navigator.of(context).pop(); - }, - ); - }, - ); - - hasError = false; - }, - ); -} - Future initialSetup( {required SharedPreferences sharedPreferences, required Box nodes, diff --git a/lib/utils/exception_handler.dart b/lib/utils/exception_handler.dart new file mode 100644 index 000000000..b5d57eba1 --- /dev/null +++ b/lib/utils/exception_handler.dart @@ -0,0 +1,104 @@ +import 'dart:convert'; +import 'dart:io'; + +import 'package:cake_wallet/generated/i18n.dart'; +import 'package:cake_wallet/main.dart'; +import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_mailer/flutter_mailer.dart'; +import 'package:path_provider/path_provider.dart'; + +class ExceptionHandler { + static bool _hasError = false; + + static void _saveException(String? error, StackTrace? stackTrace) async { + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); + final exception = { + "${DateTime.now()}": { + "Error": error, + "StackTrace": stackTrace.toString(), + } + }; + + const String separator = '''\n\n========================================================== + ==========================================================\n\n'''; + + await file.writeAsString( + jsonEncode(exception) + separator, + mode: FileMode.append, + ); + } + + static void _sendExceptionFile() async { + try { + final appDocDir = await getApplicationDocumentsDirectory(); + + final file = File('${appDocDir.path}/error.txt'); + + final MailOptions mailOptions = MailOptions( + subject: 'Mobile App Issue', + recipients: ['support@cakewallet.com'], + attachments: [file.path], + ); + + final result = await FlutterMailer.send(mailOptions); + + // Clear file content if the error was sent or saved. + // On android we can't know if it was sent or saved + if (result.name == MailerResponse.sent.name || + result.name == MailerResponse.saved.name || + result.name == MailerResponse.android.name) { + file.writeAsString("", mode: FileMode.write); + } + } catch (e, s) { + _saveException(e.toString(), s); + } + } + + static void onError(FlutterErrorDetails errorDetails) { + if (_isErrorFromUser(errorDetails.exception.toString())) { + return; + } + + _saveException(errorDetails.exception.toString(), errorDetails.stack); + + if (_hasError) { + return; + } + _hasError = true; + + WidgetsBinding.instance.addPostFrameCallback( + (timeStamp) async { + await showPopUp( + context: navigatorKey.currentContext!, + builder: (context) { + return AlertWithTwoActions( + isDividerExist: true, + alertTitle: S.of(context).error, + alertContent: S.of(context).error_dialog_content, + rightButtonText: S.of(context).send, + leftButtonText: S.of(context).do_not_send, + actionRightButton: () { + Navigator.of(context).pop(); + _sendExceptionFile(); + }, + actionLeftButton: () { + Navigator.of(context).pop(); + }, + ); + }, + ); + + _hasError = false; + }, + ); + } + + /// User related errors to be added as exceptions here to not report + static bool _isErrorFromUser(String error) { + return error.contains("Software caused connection abort"); // User connection issue + } +}