diff --git a/assets/tron_node_list.yml b/assets/tron_node_list.yml index e30f79d53..4c67b920e 100644 --- a/assets/tron_node_list.yml +++ b/assets/tron_node_list.yml @@ -1,4 +1,8 @@ - uri: api.trongrid.io is_default: true + useSSL: true +- + uri: tron-rpc.publicnode.com:443 + is_default: false useSSL: true \ No newline at end of file diff --git a/cw_bitcoin/pubspec.yaml b/cw_bitcoin/pubspec.yaml index 620d0fc18..4db7e8e8d 100644 --- a/cw_bitcoin/pubspec.yaml +++ b/cw_bitcoin/pubspec.yaml @@ -54,6 +54,9 @@ dependency_overrides: dependency_overrides: watcher: ^1.1.0 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_bitcoin_cash/pubspec.yaml b/cw_bitcoin_cash/pubspec.yaml index 797f7fb80..38ba8ed6c 100644 --- a/cw_bitcoin_cash/pubspec.yaml +++ b/cw_bitcoin_cash/pubspec.yaml @@ -49,6 +49,9 @@ dependency_overrides: dependency_overrides: watcher: ^1.1.0 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_core/lib/window_size.dart b/cw_core/lib/window_size.dart new file mode 100644 index 000000000..a0f192f66 --- /dev/null +++ b/cw_core/lib/window_size.dart @@ -0,0 +1,22 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; + +const MethodChannel _channel = MethodChannel('com.cake_wallet/native_utils'); + +Future<void> setDefaultMinimumWindowSize() async { + if (!Platform.isMacOS) return; + + try { + final result = await _channel.invokeMethod( + 'setMinWindowSize', + {'width': 500, 'height': 700}, + ) as bool; + + if (!result) { + print("Failed to set minimum window size."); + } + } on PlatformException catch (e) { + print("Failed to set minimum window size: '${e.message}'."); + } +} diff --git a/cw_haven/pubspec.yaml b/cw_haven/pubspec.yaml index ddd07af4f..ba7304d2b 100644 --- a/cw_haven/pubspec.yaml +++ b/cw_haven/pubspec.yaml @@ -35,6 +35,9 @@ dependency_overrides: dependency_overrides: watcher: ^1.1.0 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_monero/pubspec.yaml b/cw_monero/pubspec.yaml index ad02aca4c..5fe7a9935 100644 --- a/cw_monero/pubspec.yaml +++ b/cw_monero/pubspec.yaml @@ -37,6 +37,9 @@ dependency_overrides: dependency_overrides: watcher: ^1.1.0 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_nano/pubspec.yaml b/cw_nano/pubspec.yaml index c10f95dca..7ca39d69e 100644 --- a/cw_nano/pubspec.yaml +++ b/cw_nano/pubspec.yaml @@ -42,6 +42,9 @@ dependency_overrides: dependency_overrides: watcher: ^1.1.0 +dependency_overrides: + watcher: ^1.1.0 + # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/cw_tron/lib/tron_client.dart b/cw_tron/lib/tron_client.dart index f03a8abce..73812f14c 100644 --- a/cw_tron/lib/tron_client.dart +++ b/cw_tron/lib/tron_client.dart @@ -367,7 +367,7 @@ class TronClient { ) async { // This is introduce to server as a limit in cases where feeLimit is 0 // The transaction signing will fail if the feeLimit is explicitly 0. - int defaultFeeLimit = 100000; + int defaultFeeLimit = 269000; final block = await _provider!.request(TronRequestGetNowBlock()); // Create the transfer contract @@ -401,8 +401,9 @@ class TronClient { final tronBalanceInt = tronBalance.toInt(); if (feeLimit > tronBalanceInt) { + final feeInTrx = TronHelper.fromSun(BigInt.parse(feeLimit.toString())); throw Exception( - 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up.', + 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up.\nTransaction fee: $feeInTrx TRX', ); } @@ -442,6 +443,9 @@ class TronClient { if (!request.isSuccess) { log("Tron TRC20 error: ${request.error} \n ${request.respose}"); + throw Exception( + 'An error occured while creating the transfer request. Please try again.', + ); } final feeLimit = await getFeeLimit( @@ -454,8 +458,9 @@ class TronClient { final tronBalanceInt = tronBalance.toInt(); if (feeLimit > tronBalanceInt) { + final feeInTrx = TronHelper.fromSun(BigInt.parse(feeLimit.toString())); throw Exception( - 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up.', + 'You don\'t have enough TRX to cover the transaction fee for this transaction. Kindly top up. Transaction fee: $feeInTrx TRX', ); } diff --git a/lib/entities/parse_address_from_domain.dart b/lib/entities/parse_address_from_domain.dart index f729e6392..409724c6e 100644 --- a/lib/entities/parse_address_from_domain.dart +++ b/lib/entities/parse_address_from_domain.dart @@ -5,6 +5,7 @@ import 'package:cake_wallet/entities/openalias_record.dart'; import 'package:cake_wallet/entities/parsed_address.dart'; import 'package:cake_wallet/entities/unstoppable_domain_address.dart'; import 'package:cake_wallet/entities/emoji_string_extension.dart'; +import 'package:cake_wallet/exchange/provider/thorchain_exchange.provider.dart'; import 'package:cake_wallet/mastodon/mastodon_api.dart'; import 'package:cake_wallet/nostr/nostr_api.dart'; import 'package:cake_wallet/store/settings_store.dart'; @@ -71,8 +72,8 @@ class AddressResolver { return emailRegex.hasMatch(address); } - // TODO: refactor this to take Crypto currency instead of ticker, or at least pass in the tag as well - Future<ParsedAddress> resolve(BuildContext context, String text, String ticker) async { + Future<ParsedAddress> resolve(BuildContext context, String text, CryptoCurrency currency) async { + final ticker = currency.title; try { if (text.startsWith('@') && !text.substring(1).contains('@')) { if (settingsStore.lookupsTwitter) { @@ -116,8 +117,7 @@ class AddressResolver { await MastodonAPI.lookupUserByUserName(userName: userName, apiHost: hostName); if (mastodonUser != null) { - String? addressFromBio = extractAddressByType( - raw: mastodonUser.note, type: CryptoCurrency.fromString(ticker)); + String? addressFromBio = extractAddressByType(raw: mastodonUser.note, type: currency); if (addressFromBio != null) { return ParsedAddress.fetchMastodonAddress( @@ -131,8 +131,8 @@ class AddressResolver { if (pinnedPosts.isNotEmpty) { final userPinnedPostsText = pinnedPosts.map((item) => item.content).join('\n'); - String? addressFromPinnedPost = extractAddressByType( - raw: userPinnedPostsText, type: CryptoCurrency.fromString(ticker)); + String? addressFromPinnedPost = + extractAddressByType(raw: userPinnedPostsText, type: currency); if (addressFromPinnedPost != null) { return ParsedAddress.fetchMastodonAddress( @@ -162,6 +162,16 @@ class AddressResolver { } } } + + final thorChainAddress = await ThorChainExchangeProvider.lookupAddressByName(text); + if (thorChainAddress != null) { + String? address = + thorChainAddress[ticker] ?? (ticker == 'RUNE' ? thorChainAddress['THOR'] : null); + if (address != null) { + return ParsedAddress.thorChainAddress(address: address, name: text); + } + } + final formattedName = OpenaliasRecord.formatDomainName(text); final domainParts = formattedName.split('.'); final name = domainParts.last; @@ -204,7 +214,7 @@ class AddressResolver { if (nostrUserData != null) { String? addressFromBio = extractAddressByType( - raw: nostrUserData.about, type: CryptoCurrency.fromString(ticker)); + raw: nostrUserData.about, type: currency); if (addressFromBio != null) { return ParsedAddress.nostrAddress( address: addressFromBio, diff --git a/lib/entities/parsed_address.dart b/lib/entities/parsed_address.dart index fc8ab2440..cfd69acbe 100644 --- a/lib/entities/parsed_address.dart +++ b/lib/entities/parsed_address.dart @@ -11,7 +11,8 @@ enum ParseFrom { ens, contact, mastodon, - nostr + nostr, + thorChain } class ParsedAddress { @@ -133,6 +134,14 @@ class ParsedAddress { ); } + factory ParsedAddress.thorChainAddress({required String address, required String name}) { + return ParsedAddress( + addresses: [address], + name: name, + parseFrom: ParseFrom.thorChain, + ); + } + final List<String> addresses; final String name; final String description; diff --git a/lib/exchange/provider/thorchain_exchange.provider.dart b/lib/exchange/provider/thorchain_exchange.provider.dart index 32dce7db8..826e203f3 100644 --- a/lib/exchange/provider/thorchain_exchange.provider.dart +++ b/lib/exchange/provider/thorchain_exchange.provider.dart @@ -34,11 +34,13 @@ class ThorChainExchangeProvider extends ExchangeProvider { static final isRefundAddressSupported = [CryptoCurrency.eth]; - static const _baseURL = 'thornode.ninerealms.com'; + static const _baseNodeURL = 'thornode.ninerealms.com'; + static const _baseURL = 'midgard.ninerealms.com'; static const _quotePath = '/thorchain/quote/swap'; static const _txInfoPath = '/thorchain/tx/status/'; static const _affiliateName = 'cakewallet'; static const _affiliateBps = '175'; + static const _nameLookUpPath= 'v2/thorname/lookup/'; final Box<Trade> tradesStore; @@ -154,7 +156,7 @@ class ThorChainExchangeProvider extends ExchangeProvider { Future<Trade> findTradeById({required String id}) async { if (id.isEmpty) throw Exception('Trade id is empty'); final formattedId = id.startsWith('0x') ? id.substring(2) : id; - final uri = Uri.https(_baseURL, '$_txInfoPath$formattedId'); + final uri = Uri.https(_baseNodeURL, '$_txInfoPath$formattedId'); final response = await http.get(uri); if (response.statusCode == 404) { @@ -206,8 +208,35 @@ class ThorChainExchangeProvider extends ExchangeProvider { ); } + static Future<Map<String, String>?>? lookupAddressByName(String name) async { + final uri = Uri.https(_baseURL, '$_nameLookUpPath$name'); + final response = await http.get(uri); + + if (response.statusCode != 200) { + return null; + } + + final body = json.decode(response.body) as Map<String, dynamic>; + final entries = body['entries'] as List<dynamic>?; + + if (entries == null || entries.isEmpty) { + return null; + } + + Map<String, String> chainToAddressMap = {}; + + for (final entry in entries) { + final chain = entry['chain'] as String; + final address = entry['address'] as String; + chainToAddressMap[chain] = address; + } + + return chainToAddressMap; + } + + Future<Map<String, dynamic>> _getSwapQuote(Map<String, String> params) async { - Uri uri = Uri.https(_baseURL, _quotePath, params); + Uri uri = Uri.https(_baseNodeURL, _quotePath, params); final response = await http.get(uri); diff --git a/lib/main.dart b/lib/main.dart index b274c7a84..b2e32d7a9 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -41,6 +41,7 @@ import 'package:uni_links/uni_links.dart'; import 'package:cw_core/unspent_coins_info.dart'; import 'package:cake_wallet/monero/monero.dart'; import 'package:cw_core/cake_hive.dart'; +import 'package:cw_core/window_size.dart'; final navigatorKey = GlobalKey<NavigatorState>(); final rootKey = GlobalKey<RootState>(); @@ -60,6 +61,8 @@ Future<void> main() async { return true; }; + await setDefaultMinimumWindowSize(); + await CakeHive.close(); await initializeAppConfigs(); diff --git a/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart b/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart index aa7012ae5..f8f92dc08 100644 --- a/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart +++ b/lib/src/screens/dashboard/desktop_widgets/dropdown_item_widget.dart @@ -22,7 +22,7 @@ class DropDownItemWidget extends StatelessWidget { child: Text( title, style: TextStyle( - fontSize: 22, + fontSize: 18, fontWeight: FontWeight.w500, color: Theme.of(context).extension<CakeTextTheme>()!.titleColor, ), diff --git a/lib/src/screens/exchange/exchange_page.dart b/lib/src/screens/exchange/exchange_page.dart index 0cd4fc8a2..62d21fed9 100644 --- a/lib/src/screens/exchange/exchange_page.dart +++ b/lib/src/screens/exchange/exchange_page.dart @@ -330,10 +330,12 @@ class ExchangePage extends BasePage { void applyTemplate( BuildContext context, ExchangeViewModel exchangeViewModel, ExchangeTemplate template) async { - exchangeViewModel.changeDepositCurrency( - currency: CryptoCurrency.fromString(template.depositCurrency)); - exchangeViewModel.changeReceiveCurrency( - currency: CryptoCurrency.fromString(template.receiveCurrency)); + + final depositCryptoCurrency = CryptoCurrency.fromString(template.depositCurrency); + final receiveCryptoCurrency = CryptoCurrency.fromString(template.receiveCurrency); + + exchangeViewModel.changeDepositCurrency(currency: depositCryptoCurrency); + exchangeViewModel.changeReceiveCurrency(currency: receiveCryptoCurrency); exchangeViewModel.changeDepositAmount(amount: template.amount); exchangeViewModel.depositAddress = template.depositAddress; @@ -342,12 +344,10 @@ class ExchangePage extends BasePage { exchangeViewModel.isFixedRateMode = false; var domain = template.depositAddress; - var ticker = template.depositCurrency.toLowerCase(); - exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, depositCryptoCurrency); domain = template.receiveAddress; - ticker = template.receiveCurrency.toLowerCase(); - exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, receiveCryptoCurrency); } void _setReactions(BuildContext context, ExchangeViewModel exchangeViewModel) { @@ -519,16 +519,14 @@ class ExchangePage extends BasePage { _depositAddressFocus.addListener(() async { if (!_depositAddressFocus.hasFocus && depositAddressController.text.isNotEmpty) { final domain = depositAddressController.text; - final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); - exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.depositAddress = await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); } }); _receiveAddressFocus.addListener(() async { if (!_receiveAddressFocus.hasFocus && receiveAddressController.text.isNotEmpty) { final domain = receiveAddressController.text; - final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); - exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, ticker); + exchangeViewModel.receiveAddress = await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); } }); @@ -575,8 +573,8 @@ class ExchangePage extends BasePage { } } - Future<String> fetchParsedAddress(BuildContext context, String domain, String ticker) async { - final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, ticker); + Future<String> fetchParsedAddress(BuildContext context, String domain, CryptoCurrency currency) async { + final parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, currency); final address = await extractAddressFromParsed(context, parsedAddress); return address; } @@ -664,15 +662,13 @@ class ExchangePage extends BasePage { addressTextFieldValidator: AddressValidator(type: exchangeViewModel.depositCurrency), onPushPasteButton: (context) async { final domain = exchangeViewModel.depositAddress; - final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); }, onPushAddressBookButton: (context) async { final domain = exchangeViewModel.depositAddress; - final ticker = exchangeViewModel.depositCurrency.title.toLowerCase(); exchangeViewModel.depositAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.depositCurrency); }, )); @@ -713,15 +709,13 @@ class ExchangePage extends BasePage { addressTextFieldValidator: AddressValidator(type: exchangeViewModel.receiveCurrency), onPushPasteButton: (context) async { final domain = exchangeViewModel.receiveAddress; - final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); }, onPushAddressBookButton: (context) async { final domain = exchangeViewModel.receiveAddress; - final ticker = exchangeViewModel.receiveCurrency.title.toLowerCase(); exchangeViewModel.receiveAddress = - await fetchParsedAddress(context, domain, ticker); + await fetchParsedAddress(context, domain, exchangeViewModel.receiveCurrency); }, )); diff --git a/lib/src/screens/send/widgets/extract_address_from_parsed.dart b/lib/src/screens/send/widgets/extract_address_from_parsed.dart index eb997c11b..9ce3ca2b1 100644 --- a/lib/src/screens/send/widgets/extract_address_from_parsed.dart +++ b/lib/src/screens/send/widgets/extract_address_from_parsed.dart @@ -56,6 +56,11 @@ Future<String> extractAddressFromParsed( profileImageUrl = parsedAddress.profileImageUrl; profileName = parsedAddress.profileName; break; + case ParseFrom.thorChain: + title = S.of(context).address_detected; + content = S.of(context).extracted_address_content('${parsedAddress.name} (ThorChain)'); + address = parsedAddress.addresses.first; + break; case ParseFrom.yatRecord: if (parsedAddress.name.isEmpty) { title = S.of(context).yat_error; diff --git a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart index 1d6168e4a..5355b7bb8 100644 --- a/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart +++ b/lib/src/screens/settings/desktop_settings/desktop_settings_page.dart @@ -12,7 +12,6 @@ final _settingsNavigatorKey = GlobalKey<NavigatorState>(); class DesktopSettingsPage extends StatefulWidget { const DesktopSettingsPage({super.key}); - @override State<DesktopSettingsPage> createState() => _DesktopSettingsPageState(); } @@ -33,22 +32,21 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> { return Scaffold( body: Container( height: MediaQuery.of(context).size.height, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + child: Row( children: [ - Padding( - padding: const EdgeInsets.all(24), - child: Text( - S.current.settings, - style: textXLarge(), - ), - ), Expanded( - child: Row( + flex: 1, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ + Padding( + padding: const EdgeInsets.fromLTRB(24, 24, 24, 4), + child: Text( + S.current.settings, + style: textXLarge(), + ), + ), Expanded( - flex: 1, child: ListView.separated( padding: EdgeInsets.only(top: 0), itemBuilder: (_, index) { @@ -78,27 +76,27 @@ class _DesktopSettingsPageState extends State<DesktopSettingsPage> { itemCount: itemCount, ), ), - Flexible( - flex: 2, - child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 500), - child: Navigator( - key: _settingsNavigatorKey, - initialRoute: Routes.empty_no_route, - onGenerateRoute: (settings) => Router.createRoute(settings), - onGenerateInitialRoutes: - (NavigatorState navigator, String initialRouteName) { - return [ - navigator - .widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! - ]; - }, - ), - ), - ) ], ), ), + Flexible( + flex: 2, + child: ConstrainedBox( + constraints: BoxConstraints(maxWidth: 500), + child: Navigator( + key: _settingsNavigatorKey, + initialRoute: Routes.empty_no_route, + onGenerateRoute: (settings) => Router.createRoute(settings), + onGenerateInitialRoutes: + (NavigatorState navigator, String initialRouteName) { + return [ + navigator + .widget.onGenerateRoute!(RouteSettings(name: initialRouteName))! + ]; + }, + ), + ), + ) ], ), ), diff --git a/lib/src/screens/wallet_list/wallet_list_page.dart b/lib/src/screens/wallet_list/wallet_list_page.dart index 220afafbd..d8ed6aa2b 100644 --- a/lib/src/screens/wallet_list/wallet_list_page.dart +++ b/lib/src/screens/wallet_list/wallet_list_page.dart @@ -172,7 +172,7 @@ class WalletListBodyState extends State<WalletListBody> { maxLines: null, softWrap: true, style: TextStyle( - fontSize: 20, + fontSize: DeviceInfo.instance.isDesktop ? 18 : 20, fontWeight: FontWeight.w500, color: Theme.of(context) .extension<CakeTextTheme>()! diff --git a/lib/view_model/send/output.dart b/lib/view_model/send/output.dart index a79baea48..d6f2589c1 100644 --- a/lib/view_model/send/output.dart +++ b/lib/view_model/send/output.dart @@ -296,8 +296,8 @@ abstract class OutputBase with Store { Future<void> fetchParsedAddress(BuildContext context) async { final domain = address; - final ticker = cryptoCurrencyHandler().title.toLowerCase(); - parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, ticker); + final currency = cryptoCurrencyHandler(); + parsedAddress = await getIt.get<AddressResolver>().resolve(context, domain, currency); extractedAddress = await extractAddressFromParsed(context, parsedAddress); note = parsedAddress.description; } diff --git a/lib/view_model/send/send_view_model.dart b/lib/view_model/send/send_view_model.dart index 2a6bf553b..0d53c59cc 100644 --- a/lib/view_model/send/send_view_model.dart +++ b/lib/view_model/send/send_view_model.dart @@ -247,7 +247,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor wallet.type != WalletType.banano && wallet.type != WalletType.solana && wallet.type != WalletType.tron; - + @observable CryptoCurrency selectedCryptoCurrency; @@ -363,7 +363,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor } catch (e) { if (e is LedgerException) { final errorCode = e.errorCode.toRadixString(16); - final fallbackMsg = e.message.isNotEmpty ? e.message : "Unexpected Ledger Error Code: $errorCode"; + final fallbackMsg = + e.message.isNotEmpty ? e.message : "Unexpected Ledger Error Code: $errorCode"; final errorMsg = ledgerViewModel.interpretErrorCode(errorCode) ?? fallbackMsg; state = FailureState(errorMsg); @@ -444,7 +445,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor Object _credentials() { final priority = _settingsStore.priority[wallet.type]; - if (priority == null && wallet.type != WalletType.nano && wallet.type != WalletType.banano && wallet.type != WalletType.solana && + if (priority == null && + wallet.type != WalletType.nano && + wallet.type != WalletType.banano && + wallet.type != WalletType.solana && wallet.type != WalletType.tron) { throw Exception('Priority is null for wallet type: ${wallet.type}'); } @@ -570,6 +574,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor return errorMessage; } + if (walletType == WalletType.tron) { + if (errorMessage.contains('balance is not sufficient')) { + return S.current.do_not_have_enough_gas_asset(currency.toString()); + } + + if (errorMessage.contains('Transaction expired')) { + return 'An error occurred while processing the transaction. Kindly retry the transaction'; + } + } + if (walletType == WalletType.bitcoin || walletType == WalletType.litecoin || walletType == WalletType.bitcoinCash) { diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 75a78404f..51f61d9e3 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -10,6 +10,7 @@ import cw_monero import device_info_plus import devicelocale import flutter_inappwebview_macos +import flutter_local_authentication import flutter_secure_storage_macos import in_app_review import package_info @@ -26,6 +27,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) DevicelocalePlugin.register(with: registry.registrar(forPlugin: "DevicelocalePlugin")) InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin")) + FlutterLocalAuthenticationPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalAuthenticationPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) diff --git a/macos/Podfile.lock b/macos/Podfile.lock index b82513de2..f1f72a818 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -26,6 +26,8 @@ PODS: - flutter_inappwebview_macos (0.0.1): - FlutterMacOS - OrderedSet (~> 5.0) + - flutter_local_authentication (1.2.0): + - FlutterMacOS - flutter_secure_storage_macos (6.1.1): - FlutterMacOS - FlutterMacOS (1.0.0) @@ -56,6 +58,7 @@ DEPENDENCIES: - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`) - devicelocale (from `Flutter/ephemeral/.symlinks/plugins/devicelocale/macos`) - flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`) + - flutter_local_authentication (from `Flutter/ephemeral/.symlinks/plugins/flutter_local_authentication/macos`) - flutter_secure_storage_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos`) - FlutterMacOS (from `Flutter/ephemeral`) - in_app_review (from `Flutter/ephemeral/.symlinks/plugins/in_app_review/macos`) @@ -83,6 +86,8 @@ EXTERNAL SOURCES: :path: Flutter/ephemeral/.symlinks/plugins/devicelocale/macos flutter_inappwebview_macos: :path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos + flutter_local_authentication: + :path: Flutter/ephemeral/.symlinks/plugins/flutter_local_authentication/macos flutter_secure_storage_macos: :path: Flutter/ephemeral/.symlinks/plugins/flutter_secure_storage_macos/macos FlutterMacOS: @@ -110,6 +115,7 @@ SPEC CHECKSUMS: device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f devicelocale: 9f0f36ac651cabae2c33f32dcff4f32b61c38225 flutter_inappwebview_macos: 9600c9df9fdb346aaa8933812009f8d94304203d + flutter_local_authentication: 85674893931e1c9cfa7c9e4f5973cb8c56b018b0 flutter_secure_storage_macos: d56e2d218c1130b262bef8b4a7d64f88d7f9c9ea FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 in_app_review: a850789fad746e89bce03d4aeee8078b45a53fd0 diff --git a/macos/Runner/AppDelegate.swift b/macos/Runner/AppDelegate.swift index 0c8973175..cd7f006e6 100644 --- a/macos/Runner/AppDelegate.swift +++ b/macos/Runner/AppDelegate.swift @@ -24,7 +24,21 @@ class AppDelegate: FlutterAppDelegate { } result(secRandom(count: count)) - + case "setMinWindowSize": + guard let self = self else { + result(false) + return + } + if let arguments = call.arguments as? [String: Any], + let width = arguments["width"] as? Double, + let height = arguments["height"] as? Double { + DispatchQueue.main.async { + self.mainFlutterWindow?.minSize = CGSize(width: width, height: height) + } + result(true) + } else { + result(false) + } default: result(FlutterMethodNotImplemented) }