mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-02-02 03:06:35 +00:00
[skip ci] Merge branch 'main' of https://github.com/cake-tech/cake_wallet into breez
This commit is contained in:
commit
4c73dec92f
22 changed files with 205 additions and 75 deletions
|
@ -1,4 +1,8 @@
|
|||
-
|
||||
uri: api.trongrid.io
|
||||
is_default: true
|
||||
useSSL: true
|
||||
-
|
||||
uri: tron-rpc.publicnode.com:443
|
||||
is_default: false
|
||||
useSSL: true
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
22
cw_core/lib/window_size.dart
Normal file
22
cw_core/lib/window_size.dart
Normal file
|
@ -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}'.");
|
||||
}
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
|
|
|
@ -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);
|
||||
},
|
||||
));
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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))!
|
||||
];
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
@ -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>()!
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue