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, + 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 fetchUnstoppableDomainAddress(String domain, String ticker) async { + String address; + + try { + address = await channel.invokeMethod( + 'getUnstoppableDomainAddress', + { + '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(); final _formKey = GlobalKey(); 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( @@ -726,4 +775,20 @@ class ExchangePage extends BasePage { key.currentState.addressController.text = null; } } + + Future 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 currencies; @@ -49,8 +51,10 @@ class ExchangeCard extends StatefulWidget { final FormFieldValidator currencyValueValidator; final FormFieldValidator 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 { ? 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 { .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( @@ -770,4 +776,20 @@ class SendPage extends BasePage { ), context: context); } + + Future 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( + 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 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 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