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