From ae9efb0ae8ae35e0c33bcfe7ba3473ddc9b4d0ae Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Tue, 20 Apr 2021 20:49:53 +0300 Subject: [PATCH 01/12] CAKE-192 | implemented unstoppable domain address to the app --- android/app/build.gradle | 5 +- .../cakewallet/cake_wallet/MainActivity.java | 46 ++++++++++- android/build.gradle | 2 +- .../gradle/wrapper/gradle-wrapper.properties | 4 +- ios/Podfile | 3 +- ios/Podfile.lock | 18 ++++- ios/Runner/AppDelegate.swift | 40 +++++++++ lib/entities/unstoppable_domain_address.dart | 22 +++++ lib/src/screens/exchange/exchange_page.dart | 81 +++++++++++++++++-- .../exchange/exchange_template_page.dart | 11 ++- .../exchange/widgets/exchange_card.dart | 10 ++- lib/src/screens/send/send_page.dart | 34 ++++++-- lib/src/screens/send/send_template_page.dart | 4 +- .../unstoppable_domain_address_alert.dart | 17 ++++ lib/src/widgets/address_text_field.dart | 6 +- .../exchange/exchange_view_model.dart | 5 ++ lib/view_model/send/send_view_model.dart | 5 ++ res/values/strings_de.arb | 5 +- res/values/strings_en.arb | 5 +- res/values/strings_es.arb | 5 +- res/values/strings_hi.arb | 5 +- res/values/strings_ja.arb | 5 +- res/values/strings_ko.arb | 5 +- res/values/strings_nl.arb | 5 +- res/values/strings_pl.arb | 5 +- res/values/strings_pt.arb | 5 +- res/values/strings_ru.arb | 5 +- res/values/strings_uk.arb | 5 +- res/values/strings_zh.arb | 5 +- 29 files changed, 327 insertions(+), 46 deletions(-) create mode 100644 lib/entities/unstoppable_domain_address.dart create mode 100644 lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 0c6a46dc4..cef66608c 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -81,6 +81,7 @@ flutter { dependencies { testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test:runner:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1' + androidTestImplementation 'androidx.test:runner:1.3.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' + implementation 'com.unstoppabledomains:resolution:1.13.0' } diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java index cf650375f..7efe1606c 100644 --- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java +++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java @@ -5,11 +5,55 @@ import io.flutter.embedding.android.FlutterFragmentActivity; import io.flutter.embedding.engine.FlutterEngine; import io.flutter.plugins.GeneratedPluginRegistrant; +import com.unstoppabledomains.resolution.DomainResolution; +import com.unstoppabledomains.resolution.Resolution; + +import android.os.AsyncTask; +import android.os.Handler; +import android.os.Looper; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; public class MainActivity extends FlutterFragmentActivity { - + final String UNSTOPPABLE_DOMAIN_CHANNEL = "com.cakewallet.cake_wallet/unstoppable-domain"; + @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); + + MethodChannel unstoppableDomainChannel = + new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), + UNSTOPPABLE_DOMAIN_CHANNEL); + + unstoppableDomainChannel.setMethodCallHandler(this::handle); + } + + private void handle(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + try { + if (call.method.equals("getUnstoppableDomainAddress")) { + getUnstoppableDomainAddress(call, result); + } else { + result.notImplemented(); + } + } catch (Exception e) { + result.error("UNCAUGHT_ERROR", e.getMessage(), null); + } + } + + private void getUnstoppableDomainAddress(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + DomainResolution resolution = new Resolution(); + Handler handler = new Handler(Looper.getMainLooper()); + String domain = call.argument("domain"); + String ticker = call.argument("ticker"); + + AsyncTask.execute(() -> { + try { + String address = resolution.getAddress(domain, ticker); + handler.post(() -> result.success(address)); + } catch (Exception e) { + handler.post(() -> result.error("INVALID DOMAIN", e.getMessage(), null)); + } + }); } } diff --git a/android/build.gradle b/android/build.gradle index 0baed694d..fab3c2e17 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -5,7 +5,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.4' + classpath 'com.android.tools.build:gradle:4.1.3' } } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 296b146b7..b7ca2e6de 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Fri Jun 23 08:50:38 CEST 2017 +#Mon Apr 19 18:19:26 EEST 2021 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip diff --git a/ios/Podfile b/ios/Podfile index e26de900c..8248dde48 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '9.0' +platform :ios, '11.0' source 'https://github.com/CocoaPods/Specs.git' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. @@ -36,6 +36,7 @@ target 'Runner' do # Cake Wallet (Legacy) pod 'CryptoSwift' + pod 'UnstoppableDomainsResolution', '~> 0.3.6' end post_install do |installer| diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 03302eab3..f627ed23f 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -3,6 +3,7 @@ PODS: - Flutter - MTBBarcodeScanner - SwiftProtobuf + - BigInt (5.2.0) - connectivity (0.0.1): - Flutter - Reachability @@ -59,6 +60,8 @@ PODS: - SwiftyGif - esys_flutter_share (0.0.1): - Flutter + - EthereumAddress (1.3.0): + - CryptoSwift (~> 1.0) - file_picker (0.0.1): - DKImagePickerController/PhotoGallery - Flutter @@ -84,6 +87,10 @@ PODS: - Flutter - SwiftProtobuf (1.12.0) - SwiftyGif (5.3.0) + - UnstoppableDomainsResolution (0.3.6): + - BigInt + - CryptoSwift (~> 1.0) + - EthereumAddress (~> 1.3) - url_launcher (0.0.1): - Flutter - webview_flutter (0.0.1): @@ -105,19 +112,23 @@ DEPENDENCIES: - permission_handler (from `.symlinks/plugins/permission_handler/ios`) - share (from `.symlinks/plugins/share/ios`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) + - UnstoppableDomainsResolution (~> 0.3.6) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) SPEC REPOS: https://github.com/CocoaPods/Specs.git: + - BigInt - CryptoSwift - DKImagePickerController - DKPhotoGallery + - EthereumAddress - MTBBarcodeScanner - Reachability - SDWebImage - SwiftProtobuf - SwiftyGif + - UnstoppableDomainsResolution EXTERNAL SOURCES: barcode_scan: @@ -155,6 +166,7 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 + BigInt: f668a80089607f521586bbe29513d708491ef2f7 connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467 CryptoSwift: 093499be1a94b0cae36e6c26b70870668cb56060 cw_monero: 2e1f79929880cc2293b5bc1b25e28152e4d84649 @@ -162,6 +174,7 @@ SPEC CHECKSUMS: DKImagePickerController: b5eb7f7a388e4643264105d648d01f727110fc3d DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4 + EthereumAddress: 39fe8e11cf04e4e9902b55ae653dbc4e0aee5f30 file_picker: 3e6c3790de664ccf9b882732d9db5eaf6b8d4eb1 Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c flutter_secure_storage: 7953c38a04c3fdbb00571bcd87d8e3b5ceb9daec @@ -176,9 +189,10 @@ SPEC CHECKSUMS: shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d SwiftProtobuf: 4ef85479c18ca85b5482b343df9c319c62bda699 SwiftyGif: e466e86c660d343357ab944a819a101c4127cb40 + UnstoppableDomainsResolution: 63abb84858d3e91eb838a5bfa6f7e3c0e0593f24 url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b -PODFILE CHECKSUM: 5b5f101b119a1b6eb857c967d462832a9062dec4 +PODFILE CHECKSUM: 2172f10eb8ff8378f8d6e3e2c1366a0e6cdea018 -COCOAPODS: 1.9.3 +COCOAPODS: 1.10.1 diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 01aa14195..8b6264a04 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,8 +1,13 @@ import UIKit import Flutter +import UnstoppableDomainsResolution @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { + lazy var resolution : Resolution? = { + return try? Resolution() + }() + override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? @@ -10,6 +15,8 @@ import Flutter let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let batteryChannel = FlutterMethodChannel(name: "com.cakewallet.cakewallet/legacy_wallet_migration", binaryMessenger: controller.binaryMessenger) + let unstoppableDomainChannel = FlutterMethodChannel(name: "com.cakewallet.cake_wallet/unstoppable-domain", binaryMessenger: controller.binaryMessenger) + batteryChannel.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in @@ -52,6 +59,39 @@ import Flutter } }) + unstoppableDomainChannel.setMethodCallHandler({ [weak self] + (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + switch call.method { + case "getUnstoppableDomainAddress": + guard let args = call.arguments as? Dictionary<String, String>, + let domain = args["domain"], + let ticker = args["ticker"] else { + result(nil) + return + } + + guard let resolution = self?.resolution else { + result(nil) + return + } + + resolution.addr(domain: domain, ticker: ticker) { addrResult in + var address : String = "" + + switch addrResult { + case .success(let returnValue): + address = returnValue + case .failure(let error): + print("Expected Address, but got \(error)") + } + + result(address) + } + default: + result(FlutterMethodNotImplemented) + } + }) + GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/entities/unstoppable_domain_address.dart b/lib/entities/unstoppable_domain_address.dart new file mode 100644 index 000000000..494782d54 --- /dev/null +++ b/lib/entities/unstoppable_domain_address.dart @@ -0,0 +1,22 @@ +import 'package:flutter/services.dart'; + +const channel = MethodChannel('com.cakewallet.cake_wallet/unstoppable-domain'); + +Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async { + String address; + + try { + address = await channel.invokeMethod( + 'getUnstoppableDomainAddress', + <String, String> { + 'domain' : domain, + 'ticker' : ticker + } + ); + } catch (e) { + print('Unstoppable domain error: ${e.toString()}'); + address = ''; + } + + return address; +} \ No newline at end of file diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 82d7dd80e..853ff9876 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -1,7 +1,7 @@ import 'dart:ui'; import 'package:cake_wallet/entities/sync_status.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; -import 'package:cake_wallet/exchange/changenow/changenow_exchange_provider.dart'; +import 'package:cake_wallet/src/screens/send/widgets/unstoppable_domain_address_alert.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; @@ -9,8 +9,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_mobx/flutter_mobx.dart'; import 'package:keyboard_actions/keyboard_actions.dart'; import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/exchange/exchange_provider.dart'; -import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/exchange/exchange_template.dart'; import 'package:cake_wallet/exchange/exchange_trade_state.dart'; import 'package:cake_wallet/exchange/limits_state.dart'; @@ -23,7 +21,6 @@ import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/routes.dart'; import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; -import 'package:cake_wallet/exchange/xmrto/xmrto_exchange_provider.dart'; import 'package:cake_wallet/src/screens/exchange/widgets/exchange_card.dart'; import 'package:cake_wallet/src/widgets/primary_button.dart'; import 'package:cake_wallet/src/widgets/scollable_with_bottom_section.dart'; @@ -42,7 +39,9 @@ class ExchangePage extends BasePage { final checkBoxKey = GlobalKey<StandardCheckboxState>(); final _formKey = GlobalKey<FormState>(); final _depositAmountFocus = FocusNode(); + final _depositAddressFocus = FocusNode(); final _receiveAmountFocus = FocusNode(); + final _receiveAddressFocus = FocusNode(); var _isReactionsSet = false; @override @@ -52,7 +51,7 @@ class ExchangePage extends BasePage { Color get titleColor => Colors.white; @override - bool get resizeToAvoidBottomPadding => false; + bool get resizeToAvoidBottomInset => false; @override bool get extendBodyBehindAppBar => true; @@ -171,6 +170,7 @@ class ExchangePage extends BasePage { .calculateDepositAllAmount() : null, amountFocusNode: _depositAmountFocus, + addressFocusNode: _depositAddressFocus, key: depositKey, title: S.of(context).you_will_send, initialCurrency: @@ -223,6 +223,15 @@ class ExchangePage extends BasePage { type: exchangeViewModel.wallet.type), addressTextFieldValidator: AddressValidator( type: exchangeViewModel.depositCurrency), + onPushPasteButton: (context) async { + final domain = + exchangeViewModel.depositAddress; + final ticker = + exchangeViewModel.depositCurrency.title; + exchangeViewModel.depositAddress = + await applyUnstoppableDomainAddress( + context, domain, ticker); + }, ), ), ), @@ -232,6 +241,7 @@ class ExchangePage extends BasePage { child: Observer( builder: (_) => ExchangeCard( amountFocusNode: _receiveAmountFocus, + addressFocusNode: _receiveAddressFocus, key: receiveKey, title: S.of(context).you_will_get, initialCurrency: @@ -268,6 +278,15 @@ class ExchangePage extends BasePage { AddressValidator( type: exchangeViewModel .receiveCurrency), + onPushPasteButton: (context) async { + final domain = + exchangeViewModel.receiveAddress; + final ticker = + exchangeViewModel.receiveCurrency.title; + exchangeViewModel.receiveAddress = + await applyUnstoppableDomainAddress( + context, domain, ticker); + }, )), ) ], @@ -371,7 +390,7 @@ class ExchangePage extends BasePage { from: template.depositCurrency, to: template.receiveCurrency, onTap: () { - applyTemplate( + applyTemplate(context, exchangeViewModel, template); }, onRemove: () { @@ -472,8 +491,8 @@ class ExchangePage extends BasePage { )); } - void applyTemplate( - ExchangeViewModel exchangeViewModel, ExchangeTemplate template) { + void applyTemplate(BuildContext context, + ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async { exchangeViewModel.changeDepositCurrency( currency: CryptoCurrency.fromString(template.depositCurrency)); exchangeViewModel.changeReceiveCurrency( @@ -491,6 +510,16 @@ class ExchangePage extends BasePage { exchangeViewModel.receiveAddress = template.receiveAddress; exchangeViewModel.isReceiveAmountEntered = false; exchangeViewModel.isFixedRateMode = false; + + var domain = template.depositAddress; + var ticker = template.depositCurrency; + exchangeViewModel.depositAddress = + await applyUnstoppableDomainAddress(context, domain, ticker); + + domain = template.receiveAddress; + ticker = template.receiveCurrency; + exchangeViewModel.receiveAddress = + await applyUnstoppableDomainAddress(context, domain, ticker); } void _setReactions( @@ -656,6 +685,26 @@ class ExchangePage extends BasePage { } }); + _depositAddressFocus.addListener(() async { + if (!_depositAddressFocus.hasFocus && + depositAddressController.text.isNotEmpty) { + final domain = depositAddressController.text; + final ticker = exchangeViewModel.depositCurrency.title; + exchangeViewModel.depositAddress = + await applyUnstoppableDomainAddress(context, domain, ticker); + } + }); + + _receiveAddressFocus.addListener(() async { + if (!_receiveAddressFocus.hasFocus && + receiveAddressController.text.isNotEmpty) { + final domain = receiveAddressController.text; + final ticker = exchangeViewModel.receiveCurrency.title; + exchangeViewModel.receiveAddress = + await applyUnstoppableDomainAddress(context, domain, ticker); + } + }); + _receiveAmountFocus.addListener(() { if (_receiveAmountFocus.hasFocus && !exchangeViewModel.isFixedRateMode) { showPopUp<void>( @@ -726,4 +775,20 @@ class ExchangePage extends BasePage { key.currentState.addressController.text = null; } } + + Future<String> applyUnstoppableDomainAddress(BuildContext context, + String domain, String ticker) async { + try { + final address = + await exchangeViewModel.getUnstoppableDomainAddress(domain, ticker); + if ((address != null)&&address.isNotEmpty) { + unstoppableDomainAddressAlert(context, domain); + return address; + } + } catch (e) { + print(e.toString()); + } + + return domain; + } } diff --git a/lib/src/screens/exchange/exchange_template_page.dart b/lib/src/screens/exchange/exchange_template_page.dart index 5437703ce..1be8d1d6d 100644 --- a/lib/src/screens/exchange/exchange_template_page.dart +++ b/lib/src/screens/exchange/exchange_template_page.dart @@ -37,7 +37,7 @@ class ExchangeTemplatePage extends BasePage { Color get titleColor => Colors.white; @override - bool get resizeToAvoidBottomPadding => false; + bool get resizeToAvoidBottomInset => false; @override bool get extendBodyBehindAppBar => true; @@ -150,9 +150,8 @@ class ExchangeTemplatePage extends BasePage { .color, currencyValueValidator: AmountValidator( type: exchangeViewModel.wallet.type), - addressTextFieldValidator: AddressValidator( - type: - exchangeViewModel.depositCurrency), + //addressTextFieldValidator: AddressValidator( + // type: exchangeViewModel.depositCurrency), ), ), ), @@ -190,8 +189,8 @@ class ExchangeTemplatePage extends BasePage { .decorationColor, currencyValueValidator: AmountValidator( type: exchangeViewModel.wallet.type), - addressTextFieldValidator: AddressValidator( - type: exchangeViewModel.receiveCurrency), + //addressTextFieldValidator: AddressValidator( + // type: exchangeViewModel.receiveCurrency), )), ) ], diff --git a/lib/src/screens/exchange/widgets/exchange_card.dart b/lib/src/screens/exchange/widgets/exchange_card.dart index 7af57e28b..f534cccad 100644 --- a/lib/src/screens/exchange/widgets/exchange_card.dart +++ b/lib/src/screens/exchange/widgets/exchange_card.dart @@ -28,8 +28,10 @@ class ExchangeCard extends StatefulWidget { this.currencyValueValidator, this.addressTextFieldValidator, this.amountFocusNode, + this.addressFocusNode, this.hasAllAmount = false, - this.allAmount}) + this.allAmount, + this.onPushPasteButton}) : super(key: key); final List<CryptoCurrency> currencies; @@ -49,8 +51,10 @@ class ExchangeCard extends StatefulWidget { final FormFieldValidator<String> currencyValueValidator; final FormFieldValidator<String> addressTextFieldValidator; final FocusNode amountFocusNode; + final FocusNode addressFocusNode; final bool hasAllAmount; - Function allAmount; + final Function allAmount; + final Function(BuildContext context) onPushPasteButton; @override ExchangeCardState createState() => ExchangeCardState(); @@ -288,6 +292,7 @@ class ExchangeCardState extends State<ExchangeCard> { ? Padding( padding: EdgeInsets.only(top: 20), child: AddressTextField( + focusNode: widget.addressFocusNode, controller: addressController, placeholder: widget.hasRefundAddress ? S.of(context).refund_address @@ -311,6 +316,7 @@ class ExchangeCardState extends State<ExchangeCard> { .decorationColor), buttonColor: widget.addressButtonsColor, validator: widget.addressTextFieldValidator, + onPushPasteButton: widget.onPushPasteButton, ), ) : Padding( diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 9fae0ec23..e40657b1d 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,6 +1,6 @@ import 'dart:ui'; -import 'package:cake_wallet/entities/monero_transaction_priority.dart'; import 'package:cake_wallet/entities/transaction_priority.dart'; +import 'package:cake_wallet/src/screens/send/widgets/unstoppable_domain_address_alert.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; @@ -38,9 +38,10 @@ class SendPage extends BasePage { _cryptoAmountFocus = FocusNode(), _fiatAmountFocus = FocusNode(), _addressFocusNode = FocusNode() { - _addressFocusNode.addListener(() { + _addressFocusNode.addListener(() async { if (!_addressFocusNode.hasFocus && _addressController.text.isNotEmpty) { - getOpenaliasRecord(_addressFocusNode.context); + await getOpenaliasRecord(_addressFocusNode.context); + await applyUnstoppableDomainAddress(_addressFocusNode.context); } }); } @@ -67,7 +68,7 @@ class SendPage extends BasePage { Color get titleColor => Colors.white; @override - bool get resizeToAvoidBottomPadding => false; + bool get resizeToAvoidBottomInset => false; @override bool get extendBodyBehindAppBar => true; @@ -173,6 +174,10 @@ class SendPage extends BasePage { .headline .decorationColor), validator: sendViewModel.addressValidator, + onPushPasteButton: (context) async { + await getOpenaliasRecord(context); + await applyUnstoppableDomainAddress(context); + }, ), Observer( builder: (_) => Padding( @@ -513,12 +518,13 @@ class SendPage extends BasePage { to: template.name, amount: template.amount, from: template.cryptoCurrency, - onTap: () { + onTap: () async { _addressController.text = template.address; _cryptoAmountController.text = template.amount; - getOpenaliasRecord(context); + await getOpenaliasRecord(context); + await applyUnstoppableDomainAddress(context); }, onRemove: () { showPopUp<void>( @@ -770,4 +776,20 @@ class SendPage extends BasePage { ), context: context); } + + Future<void> applyUnstoppableDomainAddress(BuildContext context) async { + try { + final address = await sendViewModel + .getUnstoppableDomainAddress( + _addressController.text); + + if ((address != null)&&address.isNotEmpty) { + unstoppableDomainAddressAlert( + context, _addressController.text); + _addressController.text = address; + } + } catch (e) { + print(e.toString()); + } + } } diff --git a/lib/src/screens/send/send_template_page.dart b/lib/src/screens/send/send_template_page.dart index 6d3ac7132..3880bd2fb 100644 --- a/lib/src/screens/send/send_template_page.dart +++ b/lib/src/screens/send/send_template_page.dart @@ -34,7 +34,7 @@ class SendTemplatePage extends BasePage { Color get titleColor => Colors.white; @override - bool get resizeToAvoidBottomPadding => false; + bool get resizeToAvoidBottomInset => false; @override bool get extendBodyBehindAppBar => true; @@ -145,7 +145,7 @@ class SendTemplatePage extends BasePage { .primaryTextTheme .headline .decorationColor), - validator: sendViewModel.addressValidator, + //validator: sendViewModel.addressValidator, ), ), Observer(builder: (_) { diff --git a/lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart b/lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart new file mode 100644 index 000000000..011a36794 --- /dev/null +++ b/lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart @@ -0,0 +1,17 @@ +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +void unstoppableDomainAddressAlert(BuildContext context, String domain) async { + await showPopUp<void>( + context: context, + builder: (BuildContext context) { + + return AlertWithOneAction( + alertTitle: S.of(context).address_detected, + alertContent: S.of(context).address_from_domain(domain), + buttonText: S.of(context).ok, + buttonAction: () => Navigator.of(context).pop()); + }); +} \ No newline at end of file diff --git a/lib/src/widgets/address_text_field.dart b/lib/src/widgets/address_text_field.dart index 8e2c069f1..130912a2f 100644 --- a/lib/src/widgets/address_text_field.dart +++ b/lib/src/widgets/address_text_field.dart @@ -24,7 +24,8 @@ class AddressTextField extends StatelessWidget { this.iconColor, this.textStyle, this.hintStyle, - this.validator}); + this.validator, + this.onPushPasteButton}); static const prefixIconWidth = 34.0; static const prefixIconHeight = 34.0; @@ -43,6 +44,7 @@ class AddressTextField extends StatelessWidget { final TextStyle textStyle; final TextStyle hintStyle; final FocusNode focusNode; + final Function(BuildContext context) onPushPasteButton; @override Widget build(BuildContext context) { @@ -225,5 +227,7 @@ class AddressTextField extends StatelessWidget { if (address?.isNotEmpty ?? false) { controller.text = address; } + + onPushPasteButton?.call(context); } } diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index fc860e011..2bcec3565 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -4,6 +4,7 @@ import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; import 'package:cake_wallet/entities/sync_status.dart'; +import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/exchange/exchange_provider.dart'; import 'package:cake_wallet/exchange/limits.dart'; @@ -417,4 +418,8 @@ abstract class ExchangeViewModelBase with Store { }*/ isReceiveAmountEditable = false; } + + Future<String> getUnstoppableDomainAddress(String domain, String ticker) async { + return await fetchUnstoppableDomainAddress(domain, ticker.toLowerCase()); + } } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index b92672ff8..f36261f73 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -4,6 +4,7 @@ import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/transaction_priority.dart'; +import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/monero/monero_amount_format.dart'; import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; import 'package:hive/hive.dart'; @@ -267,6 +268,10 @@ abstract class SendViewModelBase with Store { return record.name != name ? record : null; } + Future<String> getUnstoppableDomainAddress(String domain) async { + return await fetchUnstoppableDomainAddress(domain, currency.title.toLowerCase()); + } + @action void _updateFiatAmount() { try { diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 6d1d66b84..34cef6078 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Unbestätigt", "displayable" : "Anzeigebar", - "submit_request" : "Einen Antrag stellen" + "submit_request" : "Einen Antrag stellen", + + "address_detected" : "Adresse erkannt", + "address_from_domain" : "Sie haben die Adresse von der unaufhaltsamen Domain ${domain} erhalten" } \ No newline at end of file diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index b0d98b7c9..a641fabf1 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Unconfirmed", "displayable" : "Displayable", - "submit_request" : "submit a request" + "submit_request" : "submit a request", + + "address_detected" : "Address detected", + "address_from_domain" : "You got address from unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 190ad4304..95a34e230 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Inconfirmado", "displayable" : "Visualizable", - "submit_request" : "presentar una solicitud" + "submit_request" : "presentar una solicitud", + + "address_detected" : "Dirección detectada", + "address_from_domain" : "Tienes la dirección de unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index 6eac14e99..0db4e7216 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -469,5 +469,8 @@ "unconfirmed" : "अपुष्ट", "displayable" : "प्रदर्शन योग्य", - "submit_request" : "एक अनुरोध सबमिट करें" + "submit_request" : "एक अनुरोध सबमिट करें", + + "address_detected" : "पता लग गया", + "address_from_domain" : "आपको अजेय डोमेन ${domain} से पता मिला है" } \ No newline at end of file diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 291d5afd3..89556602a 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -469,5 +469,8 @@ "unconfirmed" : "未確認", "displayable" : "表示可能", - "submit_request" : "リクエストを送信する" + "submit_request" : "リクエストを送信する", + + "address_detected" : "アドレスが検出されました", + "address_from_domain" : "あなたはからアドレスを得ました unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 781df8d8a..9433a4189 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -469,5 +469,8 @@ "unconfirmed" : "미확인", "displayable" : "표시 가능", - "submit_request" : "요청을 제출" + "submit_request" : "요청을 제출", + + "address_detected" : "주소 감지", + "address_from_domain" : "주소는 unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_nl.arb b/res/values/strings_nl.arb index 9a6183efb..8b8bef453 100644 --- a/res/values/strings_nl.arb +++ b/res/values/strings_nl.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Niet bevestigd", "displayable" : "Weer te geven", - "submit_request" : "een verzoek indienen" + "submit_request" : "een verzoek indienen", + + "address_detected" : "Adres gedetecteerd", + "address_from_domain" : "Je adres is van unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_pl.arb b/res/values/strings_pl.arb index 6db66958e..b5291e227 100644 --- a/res/values/strings_pl.arb +++ b/res/values/strings_pl.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Niepotwierdzony", "displayable" : "Wyświetlane", - "submit_request" : "złożyć wniosek" + "submit_request" : "złożyć wniosek", + + "address_detected" : "Wykryto adres", + "address_from_domain" : "Dostałeś adres od unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_pt.arb b/res/values/strings_pt.arb index 631be8f42..8e955310f 100644 --- a/res/values/strings_pt.arb +++ b/res/values/strings_pt.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Não confirmado", "displayable" : "Exibível", - "submit_request" : "enviar um pedido" + "submit_request" : "enviar um pedido", + + "address_detected" : "Endereço detectado", + "address_from_domain" : "Você obteve o endereço de unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_ru.arb b/res/values/strings_ru.arb index 333a823d8..142ae0dd1 100644 --- a/res/values/strings_ru.arb +++ b/res/values/strings_ru.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Неподтвержденный", "displayable" : "Отображаемый", - "submit_request" : "отправить запрос" + "submit_request" : "отправить запрос", + + "address_detected" : "Обнаружен адрес", + "address_from_domain" : "Вы получили адрес из unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_uk.arb b/res/values/strings_uk.arb index cc10a2d89..6c659bcea 100644 --- a/res/values/strings_uk.arb +++ b/res/values/strings_uk.arb @@ -469,5 +469,8 @@ "unconfirmed" : "Непідтверджений", "displayable" : "Відображуваний", - "submit_request" : "надіслати запит" + "submit_request" : "надіслати запит", + + "address_detected" : "Виявлено адресу", + "address_from_domain" : "Ви отримали адресу від unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index 639babcbc..f1560941e 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -469,5 +469,8 @@ "unconfirmed" : "未经证实", "displayable" : "可显示", - "submit_request" : "提交請求" + "submit_request" : "提交請求", + + "address_detected" : "檢測到地址", + "address_from_domain" : "您有以下地址 unstoppable domain ${domain}" } \ No newline at end of file From 2e22dc814a5177838169a07657b812557515a08b Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Wed, 21 Apr 2021 20:05:38 +0300 Subject: [PATCH 02/12] CAKE-192 | configured build.gradle --- android/app/build.gradle | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index cef66608c..e8d8aa315 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -67,7 +67,8 @@ android { release { signingConfig signingConfigs.release - minifyEnabled true + shrinkResources false + minifyEnabled false useProguard true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' From 9f1f4575ddaaa9db3f6ab70d887f8e69daf7fd5e Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Thu, 22 Apr 2021 19:16:47 +0300 Subject: [PATCH 03/12] CAKE-192 | configured build.gradle --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index e8d8aa315..8c89aee52 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -69,7 +69,7 @@ android { shrinkResources false minifyEnabled false - useProguard true + useProguard false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } From 4d6cc87529cb25f860d227992a962ea70c623cd7 Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Mon, 24 May 2021 21:06:12 +0300 Subject: [PATCH 04/12] CAKE-192 | merged main branch into current; fixed call unstoppable domains api for different sdk versions; fixed italian and croatian locales --- .../cakewallet/cake_wallet/MainActivity.java | 68 +++++++--------- ios/Runner/AppDelegate.swift | 78 +++++++++---------- pubspec.lock | 6 +- res/values/strings_de.arb | 2 +- res/values/strings_en.arb | 2 +- res/values/strings_es.arb | 2 +- res/values/strings_hi.arb | 2 +- res/values/strings_hr.arb | 5 +- res/values/strings_it.arb | 5 +- res/values/strings_ja.arb | 2 +- res/values/strings_ko.arb | 2 +- res/values/strings_zh.arb | 1 + 12 files changed, 85 insertions(+), 90 deletions(-) diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java index 074ce247f..f796e5417 100644 --- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java +++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java @@ -10,29 +10,29 @@ import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import android.os.AsyncTask; +import android.os.Build; import android.os.Handler; import android.os.Looper; -import java.security.SecureRandom; import com.unstoppabledomains.resolution.DomainResolution; import com.unstoppabledomains.resolution.Resolution; -import android.os.AsyncTask; -import android.os.Handler; -import android.os.Looper; - -import io.flutter.plugin.common.MethodCall; -import io.flutter.plugin.common.MethodChannel; +import java.security.SecureRandom; public class MainActivity extends FlutterFragmentActivity { final String UTILS_CHANNEL = "com.cake_wallet/native_utils"; - final String UNSTOPPABLE_DOMAIN_CHANNEL = "com.cakewallet.cake_wallet/unstoppable-domain"; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { GeneratedPluginRegistrant.registerWith(flutterEngine); + MethodChannel utilsChannel = + new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), + UTILS_CHANNEL); + + utilsChannel.setMethodCallHandler(this::handle); + MethodChannel unstoppableDomainChannel = new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), UNSTOPPABLE_DOMAIN_CHANNEL); @@ -41,14 +41,30 @@ public class MainActivity extends FlutterFragmentActivity { } private void handle(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { + Handler handler = new Handler(Looper.getMainLooper()); + try { - if (call.method.equals("getUnstoppableDomainAddress")) { - getUnstoppableDomainAddress(call, result); - } else { - result.notImplemented(); + switch (call.method) { + case "sec_random": + int count = call.argument("count"); + SecureRandom random = new SecureRandom(); + byte bytes[] = new byte[count]; + random.nextBytes(bytes); + handler.post(() -> result.success(bytes)); + break; + case "getUnstoppableDomainAddress": + int version = Build.VERSION.SDK_INT; + if (version >= 24) { + getUnstoppableDomainAddress(call, result); + } else { + handler.post(() -> result.success("")); + } + break; + default: + handler.post(() -> result.notImplemented()); } } catch (Exception e) { - result.error("UNCAUGHT_ERROR", e.getMessage(), null); + handler.post(() -> result.error("UNCAUGHT_ERROR", e.getMessage(), null)); } } @@ -66,29 +82,5 @@ public class MainActivity extends FlutterFragmentActivity { handler.post(() -> result.error("INVALID DOMAIN", e.getMessage(), null)); } }); - - MethodChannel utilsChannel = - new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), - UTILS_CHANNEL); - - utilsChannel.setMethodCallHandler(this::handle); } - - private void handle(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { - Handler handler = new Handler(Looper.getMainLooper()); - - try { - if (call.method.equals("sec_random")) { - int count = call.argument("count"); - SecureRandom random = new SecureRandom(); - byte bytes[] = new byte[count]; - random.nextBytes(bytes); - handler.post(() -> result.success(bytes)); - } else { - handler.post(() -> result.notImplemented()); - } - } catch (Exception e) { - handler.post(() -> result.error("UNCAUGHT_ERROR", e.getMessage(), null)); - } - } -} +} \ No newline at end of file diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index dbd935316..5a50892ec 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -5,9 +5,9 @@ import UnstoppableDomainsResolution @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { lazy var resolution : Resolution? = { - return try? Resolution() - }() - + return try? Resolution() + }() + override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? @@ -17,11 +17,6 @@ import UnstoppableDomainsResolution name: "com.cakewallet.cakewallet/legacy_wallet_migration", binaryMessenger: controller.binaryMessenger) legacyMigrationChannel.setMethodCallHandler({ - let batteryChannel = FlutterMethodChannel(name: "com.cakewallet.cakewallet/legacy_wallet_migration", - binaryMessenger: controller.binaryMessenger) - let unstoppableDomainChannel = FlutterMethodChannel(name: "com.cakewallet.cake_wallet/unstoppable-domain", binaryMessenger: controller.binaryMessenger) - - batteryChannel.setMethodCallHandler({ (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in switch call.method { @@ -62,7 +57,7 @@ import UnstoppableDomainsResolution result(FlutterMethodNotImplemented) } }) - + let utilsChannel = FlutterMethodChannel( name: "com.cake_wallet/native_utils", binaryMessenger: controller.binaryMessenger) @@ -80,40 +75,41 @@ import UnstoppableDomainsResolution result(FlutterMethodNotImplemented) } }) - + + let unstoppableDomainChannel = FlutterMethodChannel(name: "com.cakewallet.cake_wallet/unstoppable-domain", binaryMessenger: controller.binaryMessenger) unstoppableDomainChannel.setMethodCallHandler({ [weak self] - (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in - switch call.method { - case "getUnstoppableDomainAddress": - guard let args = call.arguments as? Dictionary<String, String>, - let domain = args["domain"], - let ticker = args["ticker"] else { - result(nil) - return - } - - guard let resolution = self?.resolution else { - result(nil) - return - } - - resolution.addr(domain: domain, ticker: ticker) { addrResult in - var address : String = "" - - switch addrResult { - case .success(let returnValue): - address = returnValue - case .failure(let error): - print("Expected Address, but got \(error)") + (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in + switch call.method { + case "getUnstoppableDomainAddress": + guard let args = call.arguments as? Dictionary<String, String>, + let domain = args["domain"], + let ticker = args["ticker"] else { + result(nil) + return + } + + guard let resolution = self?.resolution else { + result(nil) + return + } + + resolution.addr(domain: domain, ticker: ticker) { addrResult in + var address : String = "" + + switch addrResult { + case .success(let returnValue): + address = returnValue + case .failure(let error): + print("Expected Address, but got \(error)") + } + + result(address) + } + default: + result(FlutterMethodNotImplemented) } - - result(address) - } - default: - result(FlutterMethodNotImplemented) - } - }) - + }) + GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/pubspec.lock b/pubspec.lock index 3ff596074..207f4b18a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -70,7 +70,7 @@ packages: path: "." ref: cake resolved-ref: "02fef082f20af13de00b4e64efb93a2c1e5e1cf2" - url: "git@github.com:cake-tech/bech32.git" + url: "https://github.com/cake-tech/bech32.git" source: git version: "0.2.0" bip32: @@ -92,8 +92,8 @@ packages: description: path: "." ref: cake - resolved-ref: b3ab2926c665f0e68b74a4a5f31059f7fcd817b7 - url: "git@github.com:cake-tech/bitcoin_flutter.git" + resolved-ref: cbabfd87b6ce3cae6051a3e86ddb56e7a934e188 + url: "https://github.com/cake-tech/bitcoin_flutter.git" source: git version: "2.0.2" boolean_selector: diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index da4d4975b..fe64bc855 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -474,7 +474,7 @@ "buy_alert_content" : "Derzeit unterstützen wir nur den Kauf von Bitcoin. Um Bitcoin zu kaufen, erstellen Sie bitte Ihre Bitcoin-Brieftasche oder wechseln Sie zu dieser", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", "address_detected" : "Adresse erkannt", "address_from_domain" : "Sie haben die Adresse von der unaufhaltsamen Domain ${domain} erhalten" diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index e43ec7318..e0e254762 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -474,7 +474,7 @@ "buy_alert_content" : "Currently we only support the purchase of Bitcoin. To buy Bitcoin, please create or switch to your Bitcoin wallet", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", "address_detected" : "Address detected", "address_from_domain" : "You got address from unstoppable domain ${domain}" diff --git a/res/values/strings_es.arb b/res/values/strings_es.arb index 09dae1e32..a1efe9c9b 100644 --- a/res/values/strings_es.arb +++ b/res/values/strings_es.arb @@ -474,7 +474,7 @@ "buy_alert_content" : "Actualmente solo apoyamos la compra de Bitcoin. Para comprar Bitcoin, cree o cambie a su billetera Bitcoin", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", "address_detected" : "Dirección detectada", "address_from_domain" : "Tienes la dirección de unstoppable domain ${domain}" diff --git a/res/values/strings_hi.arb b/res/values/strings_hi.arb index b9a873265..899a6d9a8 100644 --- a/res/values/strings_hi.arb +++ b/res/values/strings_hi.arb @@ -474,7 +474,7 @@ "buy_alert_content" : "वर्तमान में हम केवल बिटकॉइन की खरीद का समर्थन करते हैं। बिटकॉइन खरीदने के लिए, कृपया अपना बिटकॉइन वॉलेट बनाएं या स्विच करें", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", "address_detected" : "पता लग गया", "address_from_domain" : "आपको अजेय डोमेन ${domain} से पता मिला है" diff --git a/res/values/strings_hr.arb b/res/values/strings_hr.arb index d449fca1b..857bb7905 100644 --- a/res/values/strings_hr.arb +++ b/res/values/strings_hr.arb @@ -474,5 +474,8 @@ "buy_alert_content" : "Currently we only support the purchase of Bitcoin. To buy Bitcoin, please create or switch to your Bitcoin wallet", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", + + "address_detected" : "Adresa je otkrivena", + "address_from_domain" : "Dobili ste adresu od unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_it.arb b/res/values/strings_it.arb index e8c4da26d..7d5fd783f 100644 --- a/res/values/strings_it.arb +++ b/res/values/strings_it.arb @@ -474,5 +474,8 @@ "buy_alert_content" : "Currently we only support the purchase of Bitcoin. To buy Bitcoin, please create or switch to your Bitcoin wallet", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", + + "address_detected" : "Indirizzo rilevato", + "address_from_domain" : "Hai l'indirizzo da unstoppable domain ${domain}" } \ No newline at end of file diff --git a/res/values/strings_ja.arb b/res/values/strings_ja.arb index 5fb875578..94ddea3de 100644 --- a/res/values/strings_ja.arb +++ b/res/values/strings_ja.arb @@ -474,7 +474,7 @@ "buy_alert_content" : "現在、ビットコインの購入のみをサポートしています。 ビットコインを購入するには、ビットコインウォレットを作成するか切り替えてください", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", "address_detected" : "アドレスが検出されました", "address_from_domain" : "あなたはからアドレスを得ました unstoppable domain ${domain}" diff --git a/res/values/strings_ko.arb b/res/values/strings_ko.arb index 0d64ea4fc..836e36d52 100644 --- a/res/values/strings_ko.arb +++ b/res/values/strings_ko.arb @@ -474,7 +474,7 @@ "buy_alert_content" : "현재 우리는 비트 코인 구매 만 지원합니다. 비트 코인을 구매하려면 비트 코인 지갑을 생성하거나 전환하십시오", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", - "understand" : "I understand" + "understand" : "I understand", "address_detected" : "주소 감지", "address_from_domain" : "주소는 unstoppable domain ${domain}" diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index ce831a4b3..274108fc4 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -469,6 +469,7 @@ "displayable" : "可显示", "submit_request" : "提交请求", + "buy_alert_content" : "目前,我們僅支持購買比特幣。 要購買比特幣,請創建或切換到您的比特幣錢包", "outdated_electrum_wallet_desceription" : "New Bitcoin wallets created in Cake now have a 24-word seed. It is mandatory that you create a new Bitcoin wallet and transfer all of your funds to the new 24-word wallet, and stop using wallets with a 12-word seed. Please do this immediately to secure your funds.", From f324d6599d1e1c4fa634f0fc80ed17ac45365ce4 Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Tue, 25 May 2021 16:53:35 +0300 Subject: [PATCH 05/12] CAKE-192 | added final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK to MainActivity.java --- .../src/main/java/com/cakewallet/cake_wallet/MainActivity.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java index f796e5417..fa6930a05 100644 --- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java +++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java @@ -22,6 +22,7 @@ import java.security.SecureRandom; public class MainActivity extends FlutterFragmentActivity { final String UTILS_CHANNEL = "com.cake_wallet/native_utils"; final String UNSTOPPABLE_DOMAIN_CHANNEL = "com.cakewallet.cake_wallet/unstoppable-domain"; + final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24; @Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { @@ -54,7 +55,7 @@ public class MainActivity extends FlutterFragmentActivity { break; case "getUnstoppableDomainAddress": int version = Build.VERSION.SDK_INT; - if (version >= 24) { + if (version >= UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK) { getUnstoppableDomainAddress(call, result); } else { handler.post(() -> result.success("")); From 7ddbc6b8f420cea82b10291b7408ffdfaf617fdc Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Tue, 15 Jun 2021 22:43:50 +0300 Subject: [PATCH 06/12] CAKE-192 | added verification of open alias and unstoppable domains in exchange_page.dart and send_page.dart --- lib/src/screens/exchange/exchange_page.dart | 23 +++++++++------ lib/src/screens/send/send_page.dart | 31 +++++++++++++++------ res/values/strings_de.arb | 2 +- res/values/strings_en.arb | 2 +- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 853ff9876..7b57c251f 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -778,15 +778,22 @@ class ExchangePage extends BasePage { Future<String> applyUnstoppableDomainAddress(BuildContext context, String domain, String ticker) async { - try { - final address = - await exchangeViewModel.getUnstoppableDomainAddress(domain, ticker); - if ((address != null)&&address.isNotEmpty) { - unstoppableDomainAddressAlert(context, domain); - return address; + const topLevelDomain = 'crypto'; + + if (domain.contains('.')) { + final name = domain.split('.').last; + if (name.isNotEmpty && (name == topLevelDomain)) { + try { + final address = + await exchangeViewModel.getUnstoppableDomainAddress(domain, ticker); + if ((address != null)&&address.isNotEmpty) { + unstoppableDomainAddressAlert(context, domain); + return address; + } + } catch (e) { + print(e.toString()); + } } - } catch (e) { - print(e.toString()); } return domain; diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index e40657b1d..c3072b725 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -38,10 +38,9 @@ class SendPage extends BasePage { _cryptoAmountFocus = FocusNode(), _fiatAmountFocus = FocusNode(), _addressFocusNode = FocusNode() { - _addressFocusNode.addListener(() async { + _addressFocusNode.addListener(() { if (!_addressFocusNode.hasFocus && _addressController.text.isNotEmpty) { - await getOpenaliasRecord(_addressFocusNode.context); - await applyUnstoppableDomainAddress(_addressFocusNode.context); + applyOpenaliasOrUnstoppableDomains(_addressFocusNode.context); } }); } @@ -174,9 +173,8 @@ class SendPage extends BasePage { .headline .decorationColor), validator: sendViewModel.addressValidator, - onPushPasteButton: (context) async { - await getOpenaliasRecord(context); - await applyUnstoppableDomainAddress(context); + onPushPasteButton: (context) { + applyOpenaliasOrUnstoppableDomains(context); }, ), Observer( @@ -518,13 +516,12 @@ class SendPage extends BasePage { to: template.name, amount: template.amount, from: template.cryptoCurrency, - onTap: () async { + onTap: () { _addressController.text = template.address; _cryptoAmountController.text = template.amount; - await getOpenaliasRecord(context); - await applyUnstoppableDomainAddress(context); + applyOpenaliasOrUnstoppableDomains(context); }, onRemove: () { showPopUp<void>( @@ -792,4 +789,20 @@ class SendPage extends BasePage { print(e.toString()); } } + + void applyOpenaliasOrUnstoppableDomains(BuildContext context) async { + const topLevelDomain = 'crypto'; + final address = _addressController.text; + + if (address.contains('.')) { + final name = address.split('.').last; + if (name.isNotEmpty) { + if (name == topLevelDomain) { + await applyUnstoppableDomainAddress(context); + } else { + await getOpenaliasRecord(context); + } + } + } + } } diff --git a/res/values/strings_de.arb b/res/values/strings_de.arb index 5df364ff8..99c6f53b9 100644 --- a/res/values/strings_de.arb +++ b/res/values/strings_de.arb @@ -480,7 +480,7 @@ "moonpay_alert_text" : "Der Wert des Betrags muss größer oder gleich sein ${minAmount} ${fiatCurrency}", "outdated_electrum_wallet_receive_warning": "Wenn diese Brieftasche einen 12-Wort-Seed hat und in Cake erstellt wurde, zahlen Sie KEINE Bitcoins in diese Brieftasche ein. Alle auf diese Wallet übertragenen BTC können verloren gehen. Erstellen Sie eine neue 24-Wort-Wallet (tippen Sie auf das Menü oben rechts, wählen Sie Wallets, wählen Sie Create New Wallet und dann Bitcoin) und verschieben Sie Ihre BTC SOFORT dorthin. Neue (24 Wörter) BTC-Wallets von Cake sind sicher", - "do_not_show_me": "Zeig mir das nicht noch einmal" + "do_not_show_me": "Zeig mir das nicht noch einmal", "outdated_electrum_wallet_description" : "Neue Bitcoin-Geldbörsen, die in Cake erstellt wurden, haben jetzt einen Startwert von 24 Wörtern. Es ist obligatorisch, dass Sie eine neue Bitcoin-Brieftasche erstellen, Ihr gesamtes Geld in die neue 24-Wörter-Brieftasche überweisen und keine Brieftaschen mit einem 12-Wörter-Startwert mehr verwenden. Bitte tun Sie dies sofort, um Ihr Geld zu sichern.", "understand" : "Ich verstehe", diff --git a/res/values/strings_en.arb b/res/values/strings_en.arb index 3dd03a13c..922e00f6a 100644 --- a/res/values/strings_en.arb +++ b/res/values/strings_en.arb @@ -483,7 +483,7 @@ "moonpay_alert_text" : "Value of the amount must be more or equal to ${minAmount} ${fiatCurrency}", "outdated_electrum_wallet_receive_warning": "If this wallet has a 12-word seed and was created in Cake, DO NOT deposit Bitcoin into this wallet. Any BTC transferred to this wallet may be lost. Create a new 24-word wallet (tap the menu at the top right, select Wallets, choose Create New Wallet, then select Bitcoin) and IMMEDIATELY move your BTC there. New (24-word) BTC wallets from Cake are secure", - "do_not_show_me": "Do not show me this again" + "do_not_show_me": "Do not show me this again", "address_detected" : "Address detected", "address_from_domain" : "You got address from unstoppable domain ${domain}" From 3a5932f3dfc629209536004f7fae26d2d2546268 Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Wed, 16 Jun 2021 11:44:20 +0300 Subject: [PATCH 07/12] CAKE-192 | renamed applyUnstoppableDomainAddress() to getUnstoppableDomainAddress() in the send_page.dart; fixed applyOpenaliasOrUnstoppableDomains() (send_page.dart) and applyUnstoppableDomainAddress() (exchange_page.dart) --- lib/src/screens/exchange/exchange_page.dart | 2 +- lib/src/screens/send/send_page.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 7b57c251f..aa81bd1d4 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -782,7 +782,7 @@ class ExchangePage extends BasePage { if (domain.contains('.')) { final name = domain.split('.').last; - if (name.isNotEmpty && (name == topLevelDomain)) { + if (name == topLevelDomain) { try { final address = await exchangeViewModel.getUnstoppableDomainAddress(domain, ticker); diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index c3072b725..5a755f26d 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -774,7 +774,7 @@ class SendPage extends BasePage { context: context); } - Future<void> applyUnstoppableDomainAddress(BuildContext context) async { + Future<void> getUnstoppableDomainAddress(BuildContext context) async { try { final address = await sendViewModel .getUnstoppableDomainAddress( @@ -798,7 +798,7 @@ class SendPage extends BasePage { final name = address.split('.').last; if (name.isNotEmpty) { if (name == topLevelDomain) { - await applyUnstoppableDomainAddress(context); + await getUnstoppableDomainAddress(context); } else { await getOpenaliasRecord(context); } From bb219e4da27b9cbf5bcd6198be6e1e653b5fc9ac Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Tue, 22 Jun 2021 11:29:30 +0300 Subject: [PATCH 08/12] CAKE-192 | created parse_address_from_domain.dart; applied parseAddressFromDomain() to send_page.dart and exchange_page.dart; deleted unstoppable_domain_address_alert.dart --- lib/src/screens/exchange/exchange_page.dart | 53 +++++------------- .../send/parse_address_from_domain.dart | 53 ++++++++++++++++++ lib/src/screens/send/send_page.dart | 55 ++----------------- .../unstoppable_domain_address_alert.dart | 17 ------ .../exchange/exchange_view_model.dart | 5 -- lib/view_model/send/send_view_model.dart | 15 ----- res/values/strings_zh.arb | 8 +-- 7 files changed, 77 insertions(+), 129 deletions(-) create mode 100644 lib/src/screens/send/parse_address_from_domain.dart delete mode 100644 lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index aa81bd1d4..fa69d5da2 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -1,7 +1,7 @@ import 'dart:ui'; import 'package:cake_wallet/entities/sync_status.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; -import 'package:cake_wallet/src/screens/send/widgets/unstoppable_domain_address_alert.dart'; +import 'package:cake_wallet/src/screens/send/parse_address_from_domain.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; @@ -226,10 +226,10 @@ class ExchangePage extends BasePage { onPushPasteButton: (context) async { final domain = exchangeViewModel.depositAddress; - final ticker = - exchangeViewModel.depositCurrency.title; + final ticker = exchangeViewModel + .depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await applyUnstoppableDomainAddress( + await parseAddressFromDomain( context, domain, ticker); }, ), @@ -281,10 +281,10 @@ class ExchangePage extends BasePage { onPushPasteButton: (context) async { final domain = exchangeViewModel.receiveAddress; - final ticker = - exchangeViewModel.receiveCurrency.title; + final ticker = exchangeViewModel + .receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await applyUnstoppableDomainAddress( + await parseAddressFromDomain( context, domain, ticker); }, )), @@ -512,14 +512,14 @@ class ExchangePage extends BasePage { exchangeViewModel.isFixedRateMode = false; var domain = template.depositAddress; - var ticker = template.depositCurrency; + var ticker = template.depositCurrency.toLowerCase(); exchangeViewModel.depositAddress = - await applyUnstoppableDomainAddress(context, domain, ticker); + await parseAddressFromDomain(context, domain, ticker); domain = template.receiveAddress; - ticker = template.receiveCurrency; + ticker = template.receiveCurrency.toLowerCase(); exchangeViewModel.receiveAddress = - await applyUnstoppableDomainAddress(context, domain, ticker); + await parseAddressFromDomain(context, domain, ticker); } void _setReactions( @@ -689,9 +689,9 @@ class ExchangePage extends BasePage { if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) { final domain = depositAddressController.text; - final ticker = exchangeViewModel.depositCurrency.title; + final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await applyUnstoppableDomainAddress(context, domain, ticker); + await parseAddressFromDomain(context, domain, ticker); } }); @@ -699,9 +699,9 @@ class ExchangePage extends BasePage { if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) { final domain = receiveAddressController.text; - final ticker = exchangeViewModel.receiveCurrency.title; + final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await applyUnstoppableDomainAddress(context, domain, ticker); + await parseAddressFromDomain(context, domain, ticker); } }); @@ -775,27 +775,4 @@ class ExchangePage extends BasePage { key.currentState.addressController.text = null; } } - - Future<String> applyUnstoppableDomainAddress(BuildContext context, - String domain, String ticker) async { - const topLevelDomain = 'crypto'; - - if (domain.contains('.')) { - final name = domain.split('.').last; - if (name == topLevelDomain) { - try { - final address = - await exchangeViewModel.getUnstoppableDomainAddress(domain, ticker); - if ((address != null)&&address.isNotEmpty) { - unstoppableDomainAddressAlert(context, domain); - return address; - } - } catch (e) { - print(e.toString()); - } - } - } - - return domain; - } } diff --git a/lib/src/screens/send/parse_address_from_domain.dart b/lib/src/screens/send/parse_address_from_domain.dart new file mode 100644 index 000000000..b114ef88f --- /dev/null +++ b/lib/src/screens/send/parse_address_from_domain.dart @@ -0,0 +1,53 @@ +import 'package:cake_wallet/entities/openalias_record.dart'; +import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +const topLevelDomain = 'crypto'; + +Future<String> parseAddressFromDomain( + BuildContext context, String domain, String ticker) async { + try { + final name = domain.split('.').last; + + if (name.contains(topLevelDomain)) { + final address = await fetchUnstoppableDomainAddress(domain, ticker); + if (address.isNotEmpty) { + showAddressAlert( + context, + S.of(context).address_detected, + S.of(context).address_from_domain(domain)); + return address; + } + } else if (name.isNotEmpty) { + final record = await OpenaliasRecord.fetchAddressAndName( + OpenaliasRecord.formatDomainName(domain)); + if (record.name != null && record.name != domain) { + showAddressAlert( + context, + S.of(context).openalias_alert_title, + S.of(context).openalias_alert_content(domain)); + return record.address; + } + } + } catch (e) { + print(e.toString()); + } + + return domain; +} + +void showAddressAlert(BuildContext context, String title, String content) async { + await showPopUp<void>( + context: context, + builder: (BuildContext context) { + + return AlertWithOneAction( + alertTitle: title, + alertContent: content, + buttonText: S.of(context).ok, + buttonAction: () => Navigator.of(context).pop()); + }); +} \ No newline at end of file diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 5a755f26d..92b6c54d1 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,6 +1,6 @@ import 'dart:ui'; import 'package:cake_wallet/entities/transaction_priority.dart'; -import 'package:cake_wallet/src/screens/send/widgets/unstoppable_domain_address_alert.dart'; +import 'package:cake_wallet/src/screens/send/parse_address_from_domain.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; @@ -736,26 +736,6 @@ class SendPage extends BasePage { _effectsInstalled = true; } - Future<void> getOpenaliasRecord(BuildContext context) async { - final record = - await sendViewModel.decodeOpenaliasRecord(_addressController.text); - - if (record != null) { - _addressController.text = record.address; - - await showPopUp<void>( - context: context, - builder: (BuildContext context) { - return AlertWithOneAction( - alertTitle: S.of(context).openalias_alert_title, - alertContent: - S.of(context).openalias_alert_content(record.name), - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); - } - } - Future<void> _setTransactionPriority(BuildContext context) async { final items = priorityForWalletType(sendViewModel.walletType); final selectedItem = items.indexOf(sendViewModel.transactionPriority); @@ -774,35 +754,10 @@ class SendPage extends BasePage { context: context); } - Future<void> getUnstoppableDomainAddress(BuildContext context) async { - try { - final address = await sendViewModel - .getUnstoppableDomainAddress( - _addressController.text); - - if ((address != null)&&address.isNotEmpty) { - unstoppableDomainAddressAlert( - context, _addressController.text); - _addressController.text = address; - } - } catch (e) { - print(e.toString()); - } - } - void applyOpenaliasOrUnstoppableDomains(BuildContext context) async { - const topLevelDomain = 'crypto'; - final address = _addressController.text; - - if (address.contains('.')) { - final name = address.split('.').last; - if (name.isNotEmpty) { - if (name == topLevelDomain) { - await getUnstoppableDomainAddress(context); - } else { - await getOpenaliasRecord(context); - } - } - } + final domain = _addressController.text; + final ticker = sendViewModel.currency.title.toLowerCase(); + _addressController.text = + await parseAddressFromDomain(context, domain, ticker); } } diff --git a/lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart b/lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart deleted file mode 100644 index 011a36794..000000000 --- a/lib/src/screens/send/widgets/unstoppable_domain_address_alert.dart +++ /dev/null @@ -1,17 +0,0 @@ -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -void unstoppableDomainAddressAlert(BuildContext context, String domain) async { - await showPopUp<void>( - context: context, - builder: (BuildContext context) { - - return AlertWithOneAction( - alertTitle: S.of(context).address_detected, - alertContent: S.of(context).address_from_domain(domain), - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); -} \ No newline at end of file diff --git a/lib/view_model/exchange/exchange_view_model.dart b/lib/view_model/exchange/exchange_view_model.dart index 7f0f601ab..f3f00cd77 100644 --- a/lib/view_model/exchange/exchange_view_model.dart +++ b/lib/view_model/exchange/exchange_view_model.dart @@ -4,7 +4,6 @@ import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/entities/crypto_currency.dart'; import 'package:cake_wallet/entities/sync_status.dart'; -import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/exchange/exchange_provider.dart'; import 'package:cake_wallet/exchange/limits.dart'; @@ -423,8 +422,4 @@ abstract class ExchangeViewModelBase with Store { }*/ isReceiveAmountEditable = false; } - - Future<String> getUnstoppableDomainAddress(String domain, String ticker) async { - return await fetchUnstoppableDomainAddress(domain, ticker.toLowerCase()); - } } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 850ec0b3b..3fdcbc526 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -1,17 +1,14 @@ import 'package:cake_wallet/bitcoin/bitcoin_amount_format.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_priority.dart'; import 'package:cake_wallet/bitcoin/electrum_wallet.dart'; -import 'package:cake_wallet/entities/balance_display_mode.dart'; import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart'; import 'package:cake_wallet/entities/transaction_description.dart'; import 'package:cake_wallet/entities/transaction_priority.dart'; -import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/monero/monero_amount_format.dart'; import 'package:cake_wallet/view_model/settings/settings_view_model.dart'; import 'package:hive/hive.dart'; import 'package:intl/intl.dart'; import 'package:mobx/mobx.dart'; -import 'package:cake_wallet/entities/openalias_record.dart'; import 'package:cake_wallet/entities/template.dart'; import 'package:cake_wallet/store/templates/send_template_store.dart'; import 'package:cake_wallet/core/template_validator.dart'; @@ -21,7 +18,6 @@ import 'package:cake_wallet/core/pending_transaction.dart'; import 'package:cake_wallet/core/validator.dart'; import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/core/execution_state.dart'; -import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_credentials.dart'; import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/monero/monero_transaction_creation_credentials.dart'; @@ -265,17 +261,6 @@ abstract class SendViewModelBase with Store { void setTransactionPriority(TransactionPriority priority) => _settingsStore.priority[_wallet.type] = priority; - Future<OpenaliasRecord> decodeOpenaliasRecord(String name) async { - final record = await OpenaliasRecord.fetchAddressAndName( - OpenaliasRecord.formatDomainName(name)); - - return record.name != name ? record : null; - } - - Future<String> getUnstoppableDomainAddress(String domain) async { - return await fetchUnstoppableDomainAddress(domain, currency.title.toLowerCase()); - } - @action void _updateFiatAmount() { try { diff --git a/res/values/strings_zh.arb b/res/values/strings_zh.arb index b5a76f9a4..d7867ca4f 100644 --- a/res/values/strings_zh.arb +++ b/res/values/strings_zh.arb @@ -482,9 +482,9 @@ "buy_with" : "一起购买", "moonpay_alert_text" : "金额的价值必须大于或等于 ${minAmount} ${fiatCurrency}", - "address_detected" : "檢測到地址", - "address_from_domain" : "您有以下地址 unstoppable domain ${domain}", - "outdated_electrum_wallet_receive_warning": "如果这个钱包有一个 12 字的种子并且是在 Cake 中创建的,不要将比特币存入这个钱包。 任何转移到此钱包的 BTC 都可能丢失。 创建一个新的 24 字钱包(点击右上角的菜单,选择钱包,选择创建新钱包,然后选择比特币)并立即将您的 BTC 移到那里。 Cake 的新(24 字)BTC 钱包是安全的", - "do_not_show_me": "不再提示" + "do_not_show_me": "不再提示", + + "address_detected" : "檢測到地址", + "address_from_domain" : "您有以下地址 unstoppable domain ${domain}" } \ No newline at end of file From f995342491d1517a06390038a7acc63090fa5a57 Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Wed, 7 Jul 2021 16:50:55 +0300 Subject: [PATCH 09/12] CAKE-192 | parse_address_from_domain.dart fixed and split on 2 files (current and parse_address_from_domain_alert.dart), then moved to the entities directory; used one channel for native calls; removed unneeded spaces; fixed handle of unstoppable domain error in the MainActivity.java --- .../cakewallet/cake_wallet/MainActivity.java | 10 +--- ios/Runner/AppDelegate.swift | 57 +++++++------------ lib/entities/parse_address_from_domain.dart | 52 +++++++++++++++++ lib/entities/unstoppable_domain_address.dart | 4 +- lib/src/screens/exchange/exchange_page.dart | 2 +- .../send/parse_address_from_domain.dart | 53 ----------------- lib/src/screens/send/send_page.dart | 2 +- .../parse_address_from_domain_alert.dart | 17 ++++++ 8 files changed, 97 insertions(+), 100 deletions(-) create mode 100644 lib/entities/parse_address_from_domain.dart delete mode 100644 lib/src/screens/send/parse_address_from_domain.dart create mode 100644 lib/src/screens/send/widgets/parse_address_from_domain_alert.dart diff --git a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java index fa6930a05..3afdc111e 100644 --- a/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java +++ b/android/app/src/main/java/com/cakewallet/cake_wallet/MainActivity.java @@ -21,7 +21,6 @@ import java.security.SecureRandom; public class MainActivity extends FlutterFragmentActivity { final String UTILS_CHANNEL = "com.cake_wallet/native_utils"; - final String UNSTOPPABLE_DOMAIN_CHANNEL = "com.cakewallet.cake_wallet/unstoppable-domain"; final int UNSTOPPABLE_DOMAIN_MIN_VERSION_SDK = 24; @Override @@ -33,12 +32,6 @@ public class MainActivity extends FlutterFragmentActivity { UTILS_CHANNEL); utilsChannel.setMethodCallHandler(this::handle); - - MethodChannel unstoppableDomainChannel = - new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), - UNSTOPPABLE_DOMAIN_CHANNEL); - - unstoppableDomainChannel.setMethodCallHandler(this::handle); } private void handle(@NonNull MethodCall call, @NonNull MethodChannel.Result result) { @@ -80,7 +73,8 @@ public class MainActivity extends FlutterFragmentActivity { String address = resolution.getAddress(domain, ticker); handler.post(() -> result.success(address)); } catch (Exception e) { - handler.post(() -> result.error("INVALID DOMAIN", e.getMessage(), null)); + System.out.println("Expected Address, but got " + e.getMessage()); + handler.post(() -> result.success("")); } }); } diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 859a6e628..50b6e39dd 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -5,7 +5,7 @@ import UnstoppableDomainsResolution @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { lazy var resolution : Resolution? = { - return try? Resolution() + return try? Resolution() }() override func application( @@ -75,45 +75,32 @@ import UnstoppableDomainsResolution } result(secRandom(count: count)) + case "getUnstoppableDomainAddress": + guard let args = call.arguments as? Dictionary<String, String>, + let domain = args["domain"], + let ticker = args["ticker"], + let resolution = self?.resolution else { + result(nil) + return + } + + resolution.addr(domain: domain, ticker: ticker) { addrResult in + var address : String = "" + + switch addrResult { + case .success(let returnValue): + address = returnValue + case .failure(let error): + print("Expected Address, but got \(error)") + } + + result(address) + } default: result(FlutterMethodNotImplemented) } }) - let unstoppableDomainChannel = FlutterMethodChannel(name: "com.cakewallet.cake_wallet/unstoppable-domain", binaryMessenger: controller.binaryMessenger) - unstoppableDomainChannel.setMethodCallHandler({ [weak self] - (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in - switch call.method { - case "getUnstoppableDomainAddress": - guard let args = call.arguments as? Dictionary<String, String>, - let domain = args["domain"], - let ticker = args["ticker"] else { - result(nil) - return - } - - guard let resolution = self?.resolution else { - result(nil) - return - } - - resolution.addr(domain: domain, ticker: ticker) { addrResult in - var address : String = "" - - switch addrResult { - case .success(let returnValue): - address = returnValue - case .failure(let error): - print("Expected Address, but got \(error)") - } - - result(address) - } - default: - result(FlutterMethodNotImplemented) - } - }) - GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart new file mode 100644 index 000000000..b81120361 --- /dev/null +++ b/lib/entities/parse_address_from_domain.dart @@ -0,0 +1,52 @@ +import 'package:cake_wallet/entities/openalias_record.dart'; +import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; +import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +const topLevelDomain = 'crypto'; + +Future<String> parseAddressFromDomain( + BuildContext context, String domain, String ticker) async { + try { + final domainParts = domain.split('.'); + final name = domainParts.last; + + if (domainParts.length <= 1 || domainParts.first.isEmpty || name.isEmpty) { + return domain; + } + + if (name.contains(topLevelDomain)) { + final address = await fetchUnstoppableDomainAddress(domain, ticker); + + if (address?.isEmpty ?? true) { + return domain; + } + + showAddressAlert( + context, + S.of(context).address_detected, + S.of(context).address_from_domain(domain)); + + return address; + } + + final record = await OpenaliasRecord.fetchAddressAndName( + OpenaliasRecord.formatDomainName(domain)); + + if (record == null || record.address.contains(domain)) { + return domain; + } + + showAddressAlert( + context, + S.of(context).openalias_alert_title, + S.of(context).openalias_alert_content(domain)); + + return record.address; + } catch (e) { + print(e.toString()); + } + + return domain; +} \ No newline at end of file diff --git a/lib/entities/unstoppable_domain_address.dart b/lib/entities/unstoppable_domain_address.dart index 494782d54..792f9a348 100644 --- a/lib/entities/unstoppable_domain_address.dart +++ b/lib/entities/unstoppable_domain_address.dart @@ -1,9 +1,9 @@ import 'package:flutter/services.dart'; -const channel = MethodChannel('com.cakewallet.cake_wallet/unstoppable-domain'); +const channel = MethodChannel('com.cake_wallet/native_utils'); Future<String> fetchUnstoppableDomainAddress(String domain, String ticker) async { - String address; + var address = ''; try { address = await channel.invokeMethod( diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index fa69d5da2..2209fe01b 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -1,7 +1,7 @@ import 'dart:ui'; import 'package:cake_wallet/entities/sync_status.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; -import 'package:cake_wallet/src/screens/send/parse_address_from_domain.dart'; +import 'package:cake_wallet/entities/parse_address_from_domain.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; diff --git a/lib/src/screens/send/parse_address_from_domain.dart b/lib/src/screens/send/parse_address_from_domain.dart deleted file mode 100644 index b114ef88f..000000000 --- a/lib/src/screens/send/parse_address_from_domain.dart +++ /dev/null @@ -1,53 +0,0 @@ -import 'package:cake_wallet/entities/openalias_record.dart'; -import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; -import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; -import 'package:cake_wallet/utils/show_pop_up.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; - -const topLevelDomain = 'crypto'; - -Future<String> parseAddressFromDomain( - BuildContext context, String domain, String ticker) async { - try { - final name = domain.split('.').last; - - if (name.contains(topLevelDomain)) { - final address = await fetchUnstoppableDomainAddress(domain, ticker); - if (address.isNotEmpty) { - showAddressAlert( - context, - S.of(context).address_detected, - S.of(context).address_from_domain(domain)); - return address; - } - } else if (name.isNotEmpty) { - final record = await OpenaliasRecord.fetchAddressAndName( - OpenaliasRecord.formatDomainName(domain)); - if (record.name != null && record.name != domain) { - showAddressAlert( - context, - S.of(context).openalias_alert_title, - S.of(context).openalias_alert_content(domain)); - return record.address; - } - } - } catch (e) { - print(e.toString()); - } - - return domain; -} - -void showAddressAlert(BuildContext context, String title, String content) async { - await showPopUp<void>( - context: context, - builder: (BuildContext context) { - - return AlertWithOneAction( - alertTitle: title, - alertContent: content, - buttonText: S.of(context).ok, - buttonAction: () => Navigator.of(context).pop()); - }); -} \ No newline at end of file diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 92b6c54d1..3d7e011e1 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,6 +1,6 @@ import 'dart:ui'; import 'package:cake_wallet/entities/transaction_priority.dart'; -import 'package:cake_wallet/src/screens/send/parse_address_from_domain.dart'; +import 'package:cake_wallet/entities/parse_address_from_domain.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; diff --git a/lib/src/screens/send/widgets/parse_address_from_domain_alert.dart b/lib/src/screens/send/widgets/parse_address_from_domain_alert.dart new file mode 100644 index 000000000..760091611 --- /dev/null +++ b/lib/src/screens/send/widgets/parse_address_from_domain_alert.dart @@ -0,0 +1,17 @@ +import 'package:cake_wallet/src/widgets/alert_with_one_action.dart'; +import 'package:cake_wallet/utils/show_pop_up.dart'; +import 'package:flutter/material.dart'; +import 'package:cake_wallet/generated/i18n.dart'; + +void showAddressAlert(BuildContext context, String title, String content) async { + await showPopUp<void>( + context: context, + builder: (BuildContext context) { + + return AlertWithOneAction( + alertTitle: title, + alertContent: content, + buttonText: S.of(context).ok, + buttonAction: () => Navigator.of(context).pop()); + }); +} \ No newline at end of file From bac491c44f33e6ba0b69fd74dc2fd7bb378b3c5e Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Wed, 7 Jul 2021 17:31:16 +0300 Subject: [PATCH 10/12] CAKE-192 | created ParsedAddress class; applied this class to parse_address_from_domain.dart, send_page.dart and exchange_page.dart --- lib/entities/parse_address_from_domain.dart | 30 +++++----------- lib/entities/parsed_address.dart | 8 +++++ lib/src/screens/exchange/exchange_page.dart | 38 +++++++++++++++++---- lib/src/screens/send/send_page.dart | 23 +++++++++++-- 4 files changed, 70 insertions(+), 29 deletions(-) create mode 100644 lib/entities/parsed_address.dart diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index b81120361..0c2b864dd 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -1,52 +1,40 @@ 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/src/screens/send/widgets/parse_address_from_domain_alert.dart'; -import 'package:flutter/material.dart'; -import 'package:cake_wallet/generated/i18n.dart'; const topLevelDomain = 'crypto'; -Future<String> parseAddressFromDomain( - BuildContext context, String domain, String ticker) async { +Future<ParsedAddress> parseAddressFromDomain( + String domain, String ticker) async { try { final domainParts = domain.split('.'); final name = domainParts.last; if (domainParts.length <= 1 || domainParts.first.isEmpty || name.isEmpty) { - return domain; + return ParsedAddress(domain, ParseFrom.notParsed); } if (name.contains(topLevelDomain)) { final address = await fetchUnstoppableDomainAddress(domain, ticker); if (address?.isEmpty ?? true) { - return domain; + return ParsedAddress(domain, ParseFrom.notParsed); } - showAddressAlert( - context, - S.of(context).address_detected, - S.of(context).address_from_domain(domain)); - - return address; + return ParsedAddress(address, ParseFrom.unstoppableDomains); } final record = await OpenaliasRecord.fetchAddressAndName( OpenaliasRecord.formatDomainName(domain)); if (record == null || record.address.contains(domain)) { - return domain; + return ParsedAddress(domain, ParseFrom.notParsed); } - showAddressAlert( - context, - S.of(context).openalias_alert_title, - S.of(context).openalias_alert_content(domain)); - - return record.address; + return ParsedAddress(record.address, ParseFrom.openAlias); } catch (e) { print(e.toString()); } - return domain; + return ParsedAddress(domain, ParseFrom.notParsed); } \ No newline at end of file diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart new file mode 100644 index 000000000..f293d99c2 --- /dev/null +++ b/lib/entities/parsed_address.dart @@ -0,0 +1,8 @@ +enum ParseFrom {unstoppableDomains, openAlias, notParsed} + +class ParsedAddress { + ParsedAddress(this.address, this.parseFrom); + + final String address; + final ParseFrom parseFrom; +} \ No newline at end of file diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 2209fe01b..693eade72 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -1,7 +1,9 @@ import 'dart:ui'; +import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/sync_status.dart'; import 'package:cake_wallet/entities/wallet_type.dart'; import 'package:cake_wallet/entities/parse_address_from_domain.dart'; +import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart'; import 'package:cake_wallet/src/widgets/standard_checkbox.dart'; import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/cupertino.dart'; @@ -229,7 +231,7 @@ class ExchangePage extends BasePage { final ticker = exchangeViewModel .depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await parseAddressFromDomain( + await applyOpenaliasOrUnstoppableDomains( context, domain, ticker); }, ), @@ -284,7 +286,7 @@ class ExchangePage extends BasePage { final ticker = exchangeViewModel .receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await parseAddressFromDomain( + await applyOpenaliasOrUnstoppableDomains( context, domain, ticker); }, )), @@ -514,12 +516,12 @@ class ExchangePage extends BasePage { var domain = template.depositAddress; var ticker = template.depositCurrency.toLowerCase(); exchangeViewModel.depositAddress = - await parseAddressFromDomain(context, domain, ticker); + await applyOpenaliasOrUnstoppableDomains(context, domain, ticker); domain = template.receiveAddress; ticker = template.receiveCurrency.toLowerCase(); exchangeViewModel.receiveAddress = - await parseAddressFromDomain(context, domain, ticker); + await applyOpenaliasOrUnstoppableDomains(context, domain, ticker); } void _setReactions( @@ -691,7 +693,7 @@ class ExchangePage extends BasePage { final domain = depositAddressController.text; final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await parseAddressFromDomain(context, domain, ticker); + await applyOpenaliasOrUnstoppableDomains(context, domain, ticker); } }); @@ -701,7 +703,7 @@ class ExchangePage extends BasePage { final domain = receiveAddressController.text; final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await parseAddressFromDomain(context, domain, ticker); + await applyOpenaliasOrUnstoppableDomains(context, domain, ticker); } }); @@ -775,4 +777,28 @@ class ExchangePage extends BasePage { key.currentState.addressController.text = null; } } + + Future<String> applyOpenaliasOrUnstoppableDomains( + BuildContext context, String domain, String ticker) async { + final parsedAddress = await parseAddressFromDomain(domain, ticker); + + switch (parsedAddress.parseFrom) { + case ParseFrom.unstoppableDomains: + showAddressAlert( + context, + S.of(context).address_detected, + S.of(context).address_from_domain(domain)); + break; + case ParseFrom.openAlias: + showAddressAlert( + context, + S.of(context).openalias_alert_title, + S.of(context).openalias_alert_content(domain)); + break; + case ParseFrom.notParsed: + break; + } + + return parsedAddress.address; + } } diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 3d7e011e1..2aa4ebb82 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -1,6 +1,8 @@ import 'dart:ui'; +import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/transaction_priority.dart'; import 'package:cake_wallet/entities/parse_address_from_domain.dart'; +import 'package:cake_wallet/src/screens/send/widgets/parse_address_from_domain_alert.dart'; import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart'; import 'package:cake_wallet/src/widgets/keyboard_done_button.dart'; import 'package:cake_wallet/src/widgets/picker.dart'; @@ -757,7 +759,24 @@ class SendPage extends BasePage { void applyOpenaliasOrUnstoppableDomains(BuildContext context) async { final domain = _addressController.text; final ticker = sendViewModel.currency.title.toLowerCase(); - _addressController.text = - await parseAddressFromDomain(context, domain, ticker); + final parsedAddress = await parseAddressFromDomain(domain, ticker); + _addressController.text = parsedAddress.address; + + switch (parsedAddress.parseFrom) { + case ParseFrom.unstoppableDomains: + showAddressAlert( + context, + S.of(context).address_detected, + S.of(context).address_from_domain(domain)); + break; + case ParseFrom.openAlias: + showAddressAlert( + context, + S.of(context).openalias_alert_title, + S.of(context).openalias_alert_content(domain)); + break; + case ParseFrom.notParsed: + break; + } } } From 008936435b287adbf06bba5114e988eead1707fb Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Fri, 16 Jul 2021 13:28:46 +0300 Subject: [PATCH 11/12] CAKE-192 | added name property to parsed_address.dart; fixed parse_address_from_domain.dart --- lib/entities/parse_address_from_domain.dart | 29 +++++++++++++-------- lib/entities/parsed_address.dart | 6 ++++- lib/src/screens/exchange/exchange_page.dart | 4 +-- lib/src/screens/send/send_page.dart | 4 +-- 4 files changed, 27 insertions(+), 16 deletions(-) diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 0c2b864dd..3dc12e6c4 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -7,34 +7,41 @@ const topLevelDomain = 'crypto'; Future<ParsedAddress> parseAddressFromDomain( String domain, String ticker) async { try { - final domainParts = domain.split('.'); + final formattedName = OpenaliasRecord.formatDomainName(domain); + final domainParts = formattedName.split('.'); final name = domainParts.last; if (domainParts.length <= 1 || domainParts.first.isEmpty || name.isEmpty) { - return ParsedAddress(domain, ParseFrom.notParsed); + return ParsedAddress(address: domain); } if (name.contains(topLevelDomain)) { - final address = await fetchUnstoppableDomainAddress(domain, ticker); + final address = + await fetchUnstoppableDomainAddress(formattedName, ticker); if (address?.isEmpty ?? true) { - return ParsedAddress(domain, ParseFrom.notParsed); + return ParsedAddress(address: domain); } - return ParsedAddress(address, ParseFrom.unstoppableDomains); + return ParsedAddress( + address: address, + name: formattedName, + parseFrom: ParseFrom.unstoppableDomains); } - final record = await OpenaliasRecord.fetchAddressAndName( - OpenaliasRecord.formatDomainName(domain)); + final record = await OpenaliasRecord.fetchAddressAndName(formattedName); - if (record == null || record.address.contains(domain)) { - return ParsedAddress(domain, ParseFrom.notParsed); + if (record == null || record.address.contains(formattedName)) { + return ParsedAddress(address: domain); } - return ParsedAddress(record.address, ParseFrom.openAlias); + return ParsedAddress( + address: record.address, + name: record.name, + parseFrom: ParseFrom.openAlias); } catch (e) { print(e.toString()); } - return ParsedAddress(domain, ParseFrom.notParsed); + return ParsedAddress(address: domain); } \ No newline at end of file diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart index f293d99c2..91fec6750 100644 --- a/lib/entities/parsed_address.dart +++ b/lib/entities/parsed_address.dart @@ -1,8 +1,12 @@ enum ParseFrom {unstoppableDomains, openAlias, notParsed} class ParsedAddress { - ParsedAddress(this.address, this.parseFrom); + ParsedAddress({ + this.address = '', + this.name = '', + this.parseFrom = ParseFrom.notParsed}); final String address; + final String name; final ParseFrom parseFrom; } \ No newline at end of file diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 693eade72..286134f16 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -787,13 +787,13 @@ class ExchangePage extends BasePage { showAddressAlert( context, S.of(context).address_detected, - S.of(context).address_from_domain(domain)); + S.of(context).address_from_domain(parsedAddress.name)); break; case ParseFrom.openAlias: showAddressAlert( context, S.of(context).openalias_alert_title, - S.of(context).openalias_alert_content(domain)); + S.of(context).openalias_alert_content(parsedAddress.name)); break; case ParseFrom.notParsed: break; diff --git a/lib/src/screens/send/send_page.dart b/lib/src/screens/send/send_page.dart index 2aa4ebb82..aae86483c 100644 --- a/lib/src/screens/send/send_page.dart +++ b/lib/src/screens/send/send_page.dart @@ -767,13 +767,13 @@ class SendPage extends BasePage { showAddressAlert( context, S.of(context).address_detected, - S.of(context).address_from_domain(domain)); + S.of(context).address_from_domain(parsedAddress.name)); break; case ParseFrom.openAlias: showAddressAlert( context, S.of(context).openalias_alert_title, - S.of(context).openalias_alert_content(domain)); + S.of(context).openalias_alert_content(parsedAddress.name)); break; case ParseFrom.notParsed: break; From 6855a6d68bf91a030fe10fafd16bd2eb7f56dcb4 Mon Sep 17 00:00:00 2001 From: OleksandrSobol <dr.alexander.sobol@gmail.com> Date: Fri, 16 Jul 2021 13:44:12 +0300 Subject: [PATCH 12/12] CAKE-192 | fixed parse_address_from_domain.dart --- lib/entities/parse_address_from_domain.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index 3dc12e6c4..45571e358 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -17,7 +17,7 @@ Future<ParsedAddress> parseAddressFromDomain( if (name.contains(topLevelDomain)) { final address = - await fetchUnstoppableDomainAddress(formattedName, ticker); + await fetchUnstoppableDomainAddress(domain, ticker); if (address?.isEmpty ?? true) { return ParsedAddress(address: domain); @@ -25,7 +25,7 @@ Future<ParsedAddress> parseAddressFromDomain( return ParsedAddress( address: address, - name: formattedName, + name: domain, parseFrom: ParseFrom.unstoppableDomains); }