Reformat the whole codebase with 100 line width (#3403)

This commit is contained in:
Omar Hatem
2026-07-15 01:20:33 +03:00
committed by GitHub
parent 1241b28bec
commit 16ddc0837a
801 changed files with 17517 additions and 17091 deletions
+2 -3
View File
@@ -3,8 +3,7 @@ import 'package:cw_core/wallet_base.dart';
import 'package:mobx/mobx.dart';
class AnimatedURModel with Store {
AnimatedURModel(this.appStore)
: wallet = appStore.wallet!;
AnimatedURModel(this.appStore) : wallet = appStore.wallet!;
final AppStore appStore;
final WalletBase wallet;
}
}
-1
View File
@@ -5,4 +5,3 @@ class AuthenticationBanned extends ExecutionState {
final String error;
}
+1 -1
View File
@@ -121,4 +121,4 @@ abstract class AuthViewModelBase with Store {
_authService.saveLastAuthTime();
}
}
}
}
+3 -3
View File
@@ -30,13 +30,13 @@ abstract class BackupViewModelBase with Store {
init();
reaction((_) => editBackupPasswordViewModel.backupPassword, (value) {
if(value != backupPassword) {
if (value != backupPassword) {
backupPassword = value;
}
});
reaction((_)=>backupPassword, (value){
if(value != editBackupPasswordViewModel.backupPassword) {
reaction((_) => backupPassword, (value) {
if (value != editBackupPasswordViewModel.backupPassword) {
editBackupPasswordViewModel.backupPassword = value;
}
});
@@ -98,8 +98,8 @@ abstract class BridgeDetailsViewModelBase with Store {
final sourceName =
evm?.getChainInfoByChainId(transfer.sourceChainId)?.name ?? '${transfer.sourceChainId}';
final destName =
evm?.getChainInfoByChainId(transfer.destinationChainId)?.name ?? '${transfer.destinationChainId}';
final destName = evm?.getChainInfoByChainId(transfer.destinationChainId)?.name ??
'${transfer.destinationChainId}';
items.add(
StandartListItem(
+8 -12
View File
@@ -142,13 +142,13 @@ abstract class BridgeViewModelBase extends WalletChangeListenerViewModel with St
@computed
String get amountDisplayFormatted {
if (selectedToken == null) return "0.00";
if (selectedToken == null) return "0.00";
return amountParsingProxy.getDisplayCryptoAmount(
amount.replaceAll(',', '.'),
selectedToken!,
);
}
return amountParsingProxy.getDisplayCryptoAmount(
amount.replaceAll(',', '.'),
selectedToken!,
);
}
DecimalAmountValidator get decimalAmountValidator => DecimalAmountValidator(
currency: selectedToken!,
@@ -176,8 +176,7 @@ abstract class BridgeViewModelBase extends WalletChangeListenerViewModel with St
String get quoteNativeFee {
if (quote == null) return '—';
return amountParsingProxy.asDisplayString(
Money(quote!.nativeFee, wallet.currency));
return amountParsingProxy.asDisplayString(Money(quote!.nativeFee, wallet.currency));
}
@computed
@@ -281,10 +280,7 @@ abstract class BridgeViewModelBase extends WalletChangeListenerViewModel with St
return;
}
setAmount(
amountParsingProxy.asDisplayString(Money(
selectedTokenBalance,
token)
),
amountParsingProxy.asDisplayString(Money(selectedTokenBalance, token)),
);
}
@@ -11,8 +11,8 @@ abstract class BuyAmountViewModelBase with Store {
BuyAmountViewModelBase()
: amount = '',
fiatCurrency = FiatCurrency.usd {
int selectedIndex = FiatCurrency.currenciesAvailableToBuyWith
.indexOf(getIt.get<SettingsStore>().fiatCurrency);
int selectedIndex =
FiatCurrency.currenciesAvailableToBuyWith.indexOf(getIt.get<SettingsStore>().fiatCurrency);
if (selectedIndex != -1) {
fiatCurrency = FiatCurrency.currenciesAvailableToBuyWith[selectedIndex];
+2 -3
View File
@@ -18,8 +18,7 @@ class BuyItem {
BuyAmount _buyAmount;
try {
_buyAmount = await provider
.calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
_buyAmount = await provider.calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
} catch (e) {
_buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
printV(e.toString());
@@ -27,4 +26,4 @@ class BuyItem {
return _buyAmount;
}
}
}
+10 -8
View File
@@ -476,8 +476,7 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
validQuotes.where((element) => !uniqueProviderQuotes.contains(element)).toList());
if (sortedRecommendedQuotes.isNotEmpty) {
sortedRecommendedQuotes.first
..setIsBestRate = true;
sortedRecommendedQuotes.first..setIsBestRate = true;
bestRateQuote = sortedRecommendedQuotes.first;
sortedRecommendedQuotes.sort((a, b) {
@@ -486,14 +485,17 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
return 0;
});
final Quote effectiveBestRateQuote =
sortedRecommendedQuotes.reduce((a, b) {
return isBuyAction ? a.rate < b.rate ? a : b : a.rate > b.rate ? a : b;
final Quote effectiveBestRateQuote = sortedRecommendedQuotes.reduce((a, b) {
return isBuyAction
? a.rate < b.rate
? a
: b
: a.rate > b.rate
? a
: b;
});
effectiveBestRateQuote.recommendations
.add(ProviderRecommendation.bestRate);
effectiveBestRateQuote.recommendations.add(ProviderRecommendation.bestRate);
selectedQuote = sortedRecommendedQuotes.first;
sortedRecommendedQuotes.first.setIsSelected = true;
@@ -162,8 +162,9 @@ abstract class CakePayBuyCardViewModelBase with Store {
confirmsVoidedRefund: confirmsVoidedRefund,
confirmsTermsAgreed: confirmsTermsAgreed,
);
final paymentData =
CakePayOrder.getPaymentDataFor(method: selectedPaymentMethod, order: order); // TODO should hande other currencies if added
final paymentData = CakePayOrder.getPaymentDataFor(
method: selectedPaymentMethod,
order: order); // TODO should hande other currencies if added
if (paymentData == null || order == null)
throw Exception('Payment data or order is not available.');
@@ -240,7 +241,7 @@ abstract class CakePayBuyCardViewModelBase with Store {
formattedRemainingTime = formatDuration(remainingTime!);
}
}
Future<void> logout() async => await _cakePayService.logout();
void _startExpirationTimer() {
@@ -153,7 +153,6 @@ abstract class CakePayCardsListViewModelBase with Store {
.toList(growable: false);
}
bool get hasFiltersChanged {
return selectedCountry != _initialSelectedCountry ||
displayPrepaidCards != _initialDisplayPrepaidCards ||
@@ -19,8 +19,7 @@ part 'contact_view_model.g.dart';
class ContactViewModel = ContactViewModelBase with _$ContactViewModel;
abstract class ContactViewModelBase with Store {
ContactViewModelBase(this._contacts, this.appStore,this.adrResService,
{ContactRecord? contact})
ContactViewModelBase(this._contacts, this.appStore, this.adrResService, {ContactRecord? contact})
: state = InitialExecutionState(),
currencies = CryptoCurrency.all,
_contact = contact,
@@ -33,7 +32,6 @@ abstract class ContactViewModelBase with Store {
final AppStore appStore;
final AddressResolverService adrResService;
@observable
ExecutionState state;
@@ -53,9 +51,7 @@ abstract class ContactViewModelBase with Store {
@computed
bool get isReady =>
name.isNotEmpty &&
(currency?.toString().isNotEmpty ?? false) &&
address.isNotEmpty;
name.isNotEmpty && (currency?.toString().isNotEmpty ?? false) && address.isNotEmpty;
final List<CryptoCurrency> currencies;
final Box<Contact> _contacts;
@@ -78,7 +74,6 @@ abstract class ContactViewModelBase with Store {
if (currentCurrency == null) return null;
if (query.isEmpty) return null;
// Check if the address is valid for the current currency (except for Zano, which can use handles as addresses)
if (currentCurrency != CryptoCurrency.zano) {
final isValidAddress = AddressValidator(type: currentCurrency).isValid(query);
@@ -108,9 +103,8 @@ abstract class ContactViewModelBase with Store {
if (resolvedAddress == null || resolvedAddress.isEmpty) return;
address = resolvedAddress;
displayName = parsedAddress.profileName.isNotEmpty
? parsedAddress.profileName
: parsedAddress.handle;
displayName =
parsedAddress.profileName.isNotEmpty ? parsedAddress.profileName : parsedAddress.handle;
}
Future<void> save() async {
@@ -135,11 +129,15 @@ abstract class ContactViewModelBase with Store {
_contact.lastChange = now;
await _contact.save();
} else {
await _contacts
.add(Contact(name: name, address: address, type: currency!, lastChange: now, displayName: displayName));
await _contacts.add(Contact(
name: name,
address: address,
type: currency!,
lastChange: now,
displayName: displayName));
}
lastChange = now;
lastChange = now;
state = ExecutedSuccessfullyState();
} catch (e) {
state = FailureState(e.toString());
@@ -149,4 +147,4 @@ abstract class ContactViewModelBase with Store {
bool doesContactNameExist(String name) {
return _contacts.values.any((contact) => contact.name == name);
}
}
}
@@ -5,4 +5,4 @@ abstract class ActionListItem {
DateTime get date;
Key key;
}
}
@@ -252,7 +252,6 @@ abstract class DashboardViewModelBase with Store {
tradeMonitor.monitorActiveTrades(wallet.id);
}
void loadFilterItems() {
filterItems = [
// FilterItem(
@@ -276,14 +275,12 @@ abstract class DashboardViewModelBase with Store {
SwapFilterItem(
enabledProviders: () => tradeFilterStore.enabledProvidersCount,
allEnabled: () => tradeFilterStore.displayAllTrades,
value: () => tradeFilterStore.enabledProvidersCount>0,
onChanged: () =>
tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.all)),
value: () => tradeFilterStore.enabledProvidersCount > 0,
onChanged: () => tradeFilterStore.toggleDisplayExchange(ExchangeProviderDescription.all)),
FilterItem(
value: () => orderFilterStore.displayCakePay,
caption: 'Cake Pay',
onChanged: () =>
orderFilterStore.toggleDisplayOrder(OrderProviderDescription.cakePay)),
onChanged: () => orderFilterStore.toggleDisplayOrder(OrderProviderDescription.cakePay)),
];
exchangeFilterItems = [
SwapProviderFilterItem(
@@ -354,8 +351,6 @@ abstract class DashboardViewModelBase with Store {
];
}
bool _isTransactionDisposerCallbackRunning = false;
@action
@@ -402,9 +397,9 @@ abstract class DashboardViewModelBase with Store {
}
bool showBridge(CryptoCurrency currency) {
if(!isEVMCompatibleChain(wallet.type)) return false;
if (!isEVMCompatibleChain(wallet.type)) return false;
if(evm!.isUSDT0Token(wallet, currency)) return true;
if (evm!.isUSDT0Token(wallet, currency)) return true;
return false;
}
@@ -513,7 +508,8 @@ abstract class DashboardViewModelBase with Store {
// printV("Transaction disposer callback (relevantTxs: ${relevantTxs.length} current: ${transactions.length})");
// TODO(malik) update this in a saner way during the vm refactor
String _txIdentityString(String txHash, TransactionDirection direction) => "${txHash}_$direction";
String _txIdentityString(String txHash, TransactionDirection direction) =>
"${txHash}_$direction";
String _txIdentityStringConfirmations(
String txHash, TransactionDirection direction, int confirmations, bool isPending) =>
"${txHash}_${direction}_${confirmations}_$isPending";
@@ -542,7 +538,8 @@ abstract class DashboardViewModelBase with Store {
.toSet();
transactions.removeWhere(
(item) => newKeys.contains(_txIdentityString(item.transaction.txHash, item.transaction.direction)),
(item) => newKeys
.contains(_txIdentityString(item.transaction.txHash, item.transaction.direction)),
);
transactions.addAll(newTransactions);
@@ -684,7 +681,9 @@ abstract class DashboardViewModelBase with Store {
}).toList();
@computed
bool get shouldShowBalanceHiddenMessage => balanceDisplayMode == BalanceDisplayMode.hiddenBalance && appStore.settingsStore.balanceHideCounter < 10;
bool get shouldShowBalanceHiddenMessage =>
balanceDisplayMode == BalanceDisplayMode.hiddenBalance &&
appStore.settingsStore.balanceHideCounter < 10;
@computed
List<OrderListItem> get orders =>
@@ -736,10 +735,8 @@ abstract class DashboardViewModelBase with Store {
static const shortHistoryLength = 3;
@computed
List<ActionListItem> get itemsShort => items
.where((item) => item is! DateSectionItem)
.take(shortHistoryLength)
.toList();
List<ActionListItem> get itemsShort =>
items.where((item) => item is! DateSectionItem).take(shortHistoryLength).toList();
@observable
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet;
@@ -809,7 +806,7 @@ abstract class DashboardViewModelBase with Store {
// if (wallet.seed == "") "wallet seed is empty",
// if (monero!.getSubaddressList(wallet).getAll(wallet)[0].address ==
// "41d7FXjswpK1111111111111111111111111111111111111111111111111111111111111111111111111111112KhNi4")
// "primary address is invalid, you won't be able to receive / spend funds",
// "primary address is invalid, you won't be able to receive / spend funds",
];
return errors;
}
+7 -12
View File
@@ -1,10 +1,7 @@
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
class FilterItem {
FilterItem({
required this.value,
required this.caption,
required this.onChanged});
FilterItem({required this.value, required this.caption, required this.onChanged});
bool Function() value;
String caption;
@@ -24,17 +21,15 @@ class SwapFilterItem extends FilterItem {
bool Function() allEnabled;
}
class SwapProviderFilterItem extends FilterItem {
SwapProviderFilterItem({
required super.value,
required super.onChanged,
required this.providerDescription,
super.caption = ""
});
SwapProviderFilterItem(
{required super.value,
required super.onChanged,
required this.providerDescription,
super.caption = ""});
@override
String get caption => providerDescription.title;
final ExchangeProviderDescription providerDescription;
}
}
@@ -34,10 +34,9 @@ abstract class HomeSettingsViewModelBase with Store {
showCombinedBalance = _balanceViewModel.wallet.walletInfo.showCombinedBalance,
favoriteToken = _balanceViewModel.wallet.currency {
_updateTokensList();
_updateLocalFavoriteToken();
_updateLocalFavoriteToken();
// React to wallet changes
// React to wallet changes
reaction((_) => _balanceViewModel.wallet, (_) {
_updateTokensList();
});
@@ -61,7 +60,8 @@ abstract class HomeSettingsViewModelBase with Store {
final ObservableSet<CryptoCurrency> tokens;
@computed
List<CryptoCurrency> get enabledTokens => [_balanceViewModel.wallet.currency, ...tokens.where((item)=>item.enabled).toList()];
List<CryptoCurrency> get enabledTokens =>
[_balanceViewModel.wallet.currency, ...tokens.where((item) => item.enabled).toList()];
WalletType get walletType => _balanceViewModel.wallet.type;
@@ -413,11 +413,10 @@ abstract class HomeSettingsViewModelBase with Store {
void _updateFiatPrices(CryptoCurrency token) async {
if (token.isPotentialScam) return; // don't fetch price data for potential scam tokens
try {
_balanceViewModel.fiatConversionStore.prices[token] =
await FiatConversionService.fetchPrice(
crypto: token,
fiat: _settingsStore.fiatCurrency,
torOnly: _settingsStore.fiatApiMode == FiatApiMode.torOnly);
_balanceViewModel.fiatConversionStore.prices[token] = await FiatConversionService.fetchPrice(
crypto: token,
fiat: _settingsStore.fiatCurrency,
torOnly: _settingsStore.fiatApiMode == FiatApiMode.torOnly);
} catch (_) {}
}
@@ -499,7 +498,6 @@ abstract class HomeSettingsViewModelBase with Store {
}
}
// FIXME these two observables cause duplicated state and are needed because mobx. remove them as part of the refactor and replace with proper getters
@observable
bool showCombinedBalance;
@@ -519,7 +517,7 @@ abstract class HomeSettingsViewModelBase with Store {
Future<void> setFavoriteToken(CryptoCurrency token) async {
final String? address;
if(token == _balanceViewModel.wallet.currency) {
if (token == _balanceViewModel.wallet.currency) {
address = null;
} else {
address = getTokenAddressBasedOnWallet(token);
@@ -533,11 +531,11 @@ abstract class HomeSettingsViewModelBase with Store {
@action
Future<void> _updateLocalFavoriteToken() async {
favoriteToken = await TokenUtilities.findTokenByAddress(
walletType: _balanceViewModel.wallet.type, address: _balanceViewModel.wallet.walletInfo.favoriteTokenAddress ?? "") ??
walletType: _balanceViewModel.wallet.type,
address: _balanceViewModel.wallet.walletInfo.favoriteTokenAddress ?? "") ??
_balanceViewModel.wallet.currency;
}
@action
void _refreshTokensList() {
final _tokens = Set.of(tokens);
@@ -23,4 +23,4 @@ class OrderListItem extends ActionListItem {
@override
DateTime get date => order.createdAt;
}
}
@@ -31,7 +31,6 @@ abstract class ReceiveOptionViewModelBase with Store {
String get walletTypeString => walletTypeToString(_wallet.type);
@action
void selectReceiveOption(ReceivePageOption option) => selectedReceiveOption = option;
}
@@ -55,7 +55,6 @@ class TransactionListItem extends ActionListItem with Keyable {
}
String get formattedTitle {
if (balanceViewModel.wallet.type == WalletType.bitcoin &&
transaction.additionalInfo['hasMissingInputTx'] == true) {
return 'Transaction has missing data';
@@ -90,8 +89,7 @@ class TransactionListItem extends ActionListItem with Keyable {
case WalletType.litecoin:
bool isPegOut = (transaction.additionalInfo["isPegOut"] as bool?) ?? false;
bool fromPegOut = (transaction.additionalInfo["fromPegOut"] as bool?) ?? false;
if(isPegOut || fromPegOut)
return 6;
if (isPegOut || fromPegOut) return 6;
default:
return 0;
}
+1 -1
View File
@@ -3,4 +3,4 @@ class WalletBalance {
String unlockedBalance;
String totalBalance;
}
}
@@ -2,7 +2,9 @@ import 'package:flutter_daemon/flutter_daemon.dart';
import 'package:mobx/mobx.dart';
part 'background_sync_logs_view_model.g.dart';
class BackgroundSyncLogsViewModel = BackgroundSyncLogsViewModelBase with _$BackgroundSyncLogsViewModel;
class BackgroundSyncLogsViewModel = BackgroundSyncLogsViewModelBase
with _$BackgroundSyncLogsViewModel;
abstract class BackgroundSyncLogsViewModelBase with Store {
final FlutterDaemon _daemon = FlutterDaemon();
@@ -26,7 +28,7 @@ abstract class BackgroundSyncLogsViewModelBase with Store {
Future<void> loadLogs() async {
isLoading = true;
error = null;
try {
logData = await _daemon.getLogs();
} catch (e) {
@@ -41,4 +43,4 @@ abstract class BackgroundSyncLogsViewModelBase with Store {
await _daemon.clearLogs();
await loadLogs();
}
}
}
@@ -6,7 +6,8 @@ part 'exchange_provider_logs_view_model.g.dart';
enum LogFilter { all, success, error }
class ExchangeProviderLogsViewModel = ExchangeProviderLogsViewModelBase with _$ExchangeProviderLogsViewModel;
class ExchangeProviderLogsViewModel = ExchangeProviderLogsViewModelBase
with _$ExchangeProviderLogsViewModel;
abstract class ExchangeProviderLogsViewModelBase with Store {
@observable
@@ -60,7 +61,7 @@ abstract class ExchangeProviderLogsViewModelBase with Store {
void loadLogs() {
isLoading = true;
error = null;
try {
logs.clear();
logs.addAll(ExchangeProviderLogger.logs);
@@ -13,4 +13,4 @@ abstract class NetworkRequestsViewModelBase with Store {
Future<void> loadLogs() async {
logs = MemoryProxyLogger.logs;
}
}
}
+12 -14
View File
@@ -22,8 +22,6 @@ abstract class QRToolsViewModelBase with Store {
@observable
String input = '';
@computed
Map<String, dynamic> get data => _getResult(input);
@@ -33,7 +31,6 @@ abstract class QRToolsViewModelBase with Store {
return out.$1;
}
Map<String, dynamic> _getResult(String input) {
try {
final decoder = URDecoder();
@@ -49,15 +46,17 @@ abstract class QRToolsViewModelBase with Store {
decoder.receivePart(part);
}
return {
"result": (decoder.result != null) ? switch (decoder.result.runtimeType) {
UR => {
"cbor": (decoder.result as UR).cbor,
"_cbor.decode.base64": base64.encode(_decodeCBOR((decoder.result as UR).cbor)),
"type": (decoder.result as UR).type,
"toString": (decoder.result as UR).toString(),
},
_ => "unknown type: ${decoder.result.runtimeType}"
} : null,
"result": (decoder.result != null)
? switch (decoder.result.runtimeType) {
UR => {
"cbor": (decoder.result as UR).cbor,
"_cbor.decode.base64": base64.encode(_decodeCBOR((decoder.result as UR).cbor)),
"type": (decoder.result as UR).type,
"toString": (decoder.result as UR).toString(),
},
_ => "unknown type: ${decoder.result.runtimeType}"
}
: null,
"expectedType": decoder.expectedType,
"estimatedPercentComplete": decoder.estimatedPercentComplete(),
"processedPartsCount": decoder.processedPartsCount(),
@@ -70,7 +69,6 @@ abstract class QRToolsViewModelBase with Store {
"resultError": decoder.resultError(),
"resultMessage": decoder.resultMessage(),
"toString": decoder.toString(),
};
} catch (e) {
return {
@@ -78,4 +76,4 @@ abstract class QRToolsViewModelBase with Store {
};
}
}
}
}
+4 -15
View File
@@ -6,14 +6,7 @@ part 'secure_preferences.g.dart';
class DevSecurePreferences = DevSecurePreferencesBase with _$DevSecurePreferences;
enum PreferenceType {
unknown,
string,
int,
double,
bool,
listString
}
enum PreferenceType { unknown, string, int, double, bool, listString }
abstract class DevSecurePreferencesBase with Store {
DevSecurePreferencesBase() {
@@ -29,9 +22,7 @@ abstract class DevSecurePreferencesBase with Store {
List<String> get keys => values.keys.toList()..sort();
@action
Future<void> delete(String key) async {
}
Future<void> delete(String key) async {}
dynamic get(String key) {
if (!values.containsKey(key)) {
@@ -42,13 +33,11 @@ abstract class DevSecurePreferencesBase with Store {
final decodedPassword = decodeWalletPassword(password: values[key]!);
return values[key]! + "\n\nDecoded: $decodedPassword";
} catch (e) {
return values[key]! +"\n$e";
return values[key]! + "\n$e";
}
}
Future<void> set(String key, PreferenceType type, dynamic value) async {
}
Future<void> set(String key, PreferenceType type, dynamic value) async {}
PreferenceType getPreferenceType(String key) {
if (!values.containsKey(key)) {
@@ -3,7 +3,8 @@ import 'package:mobx/mobx.dart';
part 'send_network_requests_view_model.g.dart';
class SendNetworkRequestsViewModel = SendNetworkRequestsViewModelBase with _$SendNetworkRequestsViewModel;
class SendNetworkRequestsViewModel = SendNetworkRequestsViewModelBase
with _$SendNetworkRequestsViewModel;
abstract class SendNetworkRequestsViewModelBase with Store {
@observable
@@ -13,4 +14,4 @@ abstract class SendNetworkRequestsViewModelBase with Store {
Future<void> loadLogs() async {
logs = MemoryProxyLogger.logs;
}
}
}
+1 -8
View File
@@ -5,14 +5,7 @@ part 'shared_preferences.g.dart';
class DevSharedPreferences = DevSharedPreferencesBase with _$DevSharedPreferences;
enum PreferenceType {
unknown,
string,
int,
double,
bool,
listString
}
enum PreferenceType { unknown, string, int, double, bool, listString }
abstract class DevSharedPreferencesBase with Store {
DevSharedPreferencesBase() {
@@ -6,7 +6,6 @@ part 'socket_health_logs_view_model.g.dart';
class SocketHealthLogsViewModel = SocketHealthLogsViewModelBase with _$SocketHealthLogsViewModel;
abstract class SocketHealthLogsViewModelBase with Store {
@observable
bool isLoading = false;
@@ -9,9 +9,12 @@ class EditBackupPasswordViewModel = EditBackupPasswordViewModelBase
with _$EditBackupPasswordViewModel;
abstract class EditBackupPasswordViewModelBase with Store {
EditBackupPasswordViewModelBase(this.secureStorage,)
: backupPassword = "",
_originalPassword = ''{init();}
EditBackupPasswordViewModelBase(
this.secureStorage,
) : backupPassword = "",
_originalPassword = '' {
init();
}
final SecureStorage secureStorage;
@@ -50,7 +50,8 @@ abstract class ExchangeTradeViewModelBase with Store {
required this.feesViewModel,
required this.fiatConversionStore,
}) : trade = tradesStore.trade!,
isSwapsXYZCanSendFromExternal = _checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet),
isSwapsXYZCanSendFromExternal =
_checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet),
items = ObservableList<ExchangeTradeItem>() {
setUpOutput();
switch (trade.provider) {
@@ -307,18 +308,17 @@ abstract class ExchangeTradeViewModelBase with Store {
items.add(
isSwapsXYZCanSendFromExternal
? ExchangeTradeItem(
title: S.current.send_to_this_address('${tradeFrom}', tagFrom) +
':',
data: trade.inputAddress ?? '',
isCopied: false,
isReceiveDetail: false,
isExternalSendDetail: true)
title: S.current.send_to_this_address('${tradeFrom}', tagFrom) + ':',
data: trade.inputAddress ?? '',
isCopied: false,
isReceiveDetail: false,
isExternalSendDetail: true)
: ExchangeTradeItem(
title: 'Smart contract call (no address required)',
data: 'Wallet will execute a contract call. On-chain transaction',
isCopied: false,
isReceiveDetail: false,
isExternalSendDetail: true),
title: 'Smart contract call (no address required)',
data: 'Wallet will execute a contract call. On-chain transaction',
isCopied: false,
isReceiveDetail: false,
isExternalSendDetail: true),
);
}
@@ -369,8 +369,7 @@ abstract class ExchangeTradeViewModelBase with Store {
}
final canSend = _sameCurrency(tradeFrom, wallet.currency) ||
(_sameCurrency(tradeFrom, CryptoCurrency.btcln) &&
wallet.currency == CryptoCurrency.btc) ||
(_sameCurrency(tradeFrom, CryptoCurrency.btcln) && wallet.currency == CryptoCurrency.btc) ||
trade.provider == ExchangeProviderDescription.xmrto ||
_isTokenBelongingToWallet(CryptoCurrency.eth) ||
_isTokenBelongingToWallet(CryptoCurrency.maticpoly) ||
@@ -408,13 +407,10 @@ abstract class ExchangeTradeViewModelBase with Store {
static bool _checkIfSwapsXYZCanSendFromExternal(Trade trade, WalletBase wallet) {
final provider = trade.provider;
if (provider == ExchangeProviderDescription.swapsXyz &&
isEVMCompatibleChain(wallet.type)) {
if(trade.routerData != null && trade.routerData != '0x') {
if (provider == ExchangeProviderDescription.swapsXyz && isEVMCompatibleChain(wallet.type)) {
if (trade.routerData != null && trade.routerData != '0x') {
return false;
}
}
return true;
}
@@ -463,9 +459,7 @@ abstract class ExchangeTradeViewModelBase with Store {
case WalletType.monero:
return MoneroURI(address: inputAddress, amount: amount);
case WalletType.wownero:
return MoneroURI(
address: inputAddress,
amount: amount);
return MoneroURI(address: inputAddress, amount: amount);
case WalletType.litecoin:
return LitecoinURI(amount: amount, address: inputAddress);
case WalletType.nano:
@@ -175,7 +175,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
useSameWalletAddress(depositCurrency) ? wallet.walletAddresses.addressForExchange : '';
_disposers.add(reaction((_) => receiveAddress, (_) {
if(!(tradeState is TradeIsCreatedSuccessfully)) {
if (!(tradeState is TradeIsCreatedSuccessfully)) {
receiveAddressDisplayName = null;
}
}));
@@ -254,8 +254,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
c.title == depositCurrency.title &&
(c.tag == depositCurrency.tag || c.tag == depositCurrency.title),
);
final balanceForCurrency =
balanceCurrency != null ? wallet.balance[balanceCurrency] : null;
final balanceForCurrency = balanceCurrency != null ? wallet.balance[balanceCurrency] : null;
if (depositCurrency == currency && balanceForCurrency != null) {
depositAvailableAmount =
_appStore.amountParsingProxy.asDisplayStringWithSymbol(balanceForCurrency.available);
@@ -281,7 +280,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
bool useSameWalletAddress(CryptoCurrency currency) =>
currency == wallet.currency ||
(currency == CryptoCurrency.btcln && wallet.currency == CryptoCurrency.btc && wallet.isSoftwareWallet) ||
(currency == CryptoCurrency.btcln &&
wallet.currency == CryptoCurrency.btc &&
wallet.isSoftwareWallet) ||
(currency.tag != null && currency.tag == wallet.currency.tag) ||
currency.tag == wallet.currency.title;
@@ -294,7 +295,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
bool get hideAddressAfterExchange =>
[WalletType.monero, WalletType.wownero, WalletType.zcash].contains(wallet.type) ||
isElectrumWallet;
isElectrumWallet;
bool _useTorOnly;
final ExchangeTemplateStore _exchangeTemplateStore;
@@ -465,7 +466,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
type = cryptoCurrencyOrTokenToWalletType(depositCurrency);
if (type == null) {
try {
type = cryptoCurrencyOrTokenToWalletType(CryptoCurrency.fromString(depositCurrency.tag ?? ""));
type =
cryptoCurrencyOrTokenToWalletType(CryptoCurrency.fromString(depositCurrency.tag ?? ""));
} catch (_) {}
}
@@ -495,7 +497,9 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
@computed
String? get balanceDisplay {
CryptoCurrency? balanceCurrency;
if (isEVMCompatibleChain(wallet.type) || wallet.type == WalletType.solana || wallet.type == WalletType.tron) {
if (isEVMCompatibleChain(wallet.type) ||
wallet.type == WalletType.solana ||
wallet.type == WalletType.tron) {
balanceCurrency = wallet.balance.keys.firstWhereOrNull(
(c) =>
c.title == depositCurrency.title &&
@@ -523,7 +527,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
@computed
bool get decentralizedExchangesPromptDismissed => _settingsStore.decentralizedExchangesPromptDismissed;
bool get decentralizedExchangesPromptDismissed =>
_settingsStore.decentralizedExchangesPromptDismissed;
@action
void dismissDecentralizedExchangesPrompt() {
@@ -707,7 +712,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
try {
return double.parse(depositAmount).toStringAsPrecision(digits);
} catch(e) {
} catch (e) {
return "0";
}
}
@@ -718,7 +723,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
try {
return double.parse(receiveAmount).toStringAsPrecision(digits);
} catch(e) {
} catch (e) {
return "0";
}
}
@@ -850,6 +855,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
_receiveAmount = null;
return;
}
/// For fixed-rate transactions, we don't want to recalculate receive amount
/// as it should remain exactly what the user set
if (isFixedRateMode) return;
@@ -1014,9 +1020,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
final entries = await Future.wait(futures);
_providerLimits = Map.fromEntries(entries);
_providerLimits.values
.whereType<Limits>()
.forEach((tempLimits) {
_providerLimits.values.whereType<Limits>().forEach((tempLimits) {
if (lowestMin != null && (tempLimits.min ?? -1) < lowestMin!) {
lowestMin = tempLimits.min;
}
@@ -1072,10 +1076,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
? '$depositAmountValue is not a valid amount for depositAmount'
: '$receiveAmountValue is not a valid amount for receiveAmount';
tradeState = TradeIsCreatedFailure(
title: S.current.trade_not_created,
error: invalidAmountError
);
tradeState =
TradeIsCreatedFailure(title: S.current.trade_not_created, error: invalidAmountError);
return;
}
@@ -1085,8 +1087,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
if (limits.min != null && amount != null && amount < limits.min!) {
tradeState = TradeIsCreatedFailure(
title: S.current.trade_not_created,
error: S.current.amount_is_below_minimum_limit(limits.min!.toString()),
title: S.current.trade_not_created,
error: S.current.amount_is_below_minimum_limit(limits.min!.toString()),
);
return;
}
@@ -1212,8 +1214,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
// Skip Swaps.xyz when sending from external
if (isSendFromExternal &&
provider.description == ExchangeProviderDescription.swapsXyz) {
if (isSendFromExternal && provider.description == ExchangeProviderDescription.swapsXyz) {
printV('Skipping Swaps.xyz for external send');
continue;
}
@@ -1264,10 +1265,10 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
trade.walletId = wallet.id;
trade.chainId = wallet.chainId;
trade.fromWalletAddress = wallet.walletAddresses.address;
if(trade.from == null) {
if (trade.from == null) {
trade.from = depositCurrency;
}
if(trade.to == null) {
if (trade.to == null) {
trade.to = receiveCurrency;
}
@@ -1385,7 +1386,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
} else if (wallet.type == WalletType.monero) {
final amount = await unspentCoinsListViewModel.getSendingBalance(UnspentCoinType.any);
changeDepositAmount(amount: wallet.currency.formatAmount(BigInt.from(amount)), isCanonical: true);
changeDepositAmount(
amount: wallet.currency.formatAmount(BigInt.from(amount)), isCanonical: true);
} else if (isEVMCompatibleChain(wallet.type)) {
final balanceCurrency = wallet.balance.keys.firstWhereOrNull(
(currency) =>
@@ -1399,7 +1401,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
return;
}
final balanceAmount = _appStore.amountParsingProxy.asDisplayString(balanceForCurrency.available);
final balanceAmount =
_appStore.amountParsingProxy.asDisplayString(balanceForCurrency.available);
final balanceDouble = double.tryParse(balanceAmount.replaceAll(',', '.')) ?? 0.0;
if (balanceDouble <= 0) {
changeDepositAmount(amount: wallet.currency.formatAmount(BigInt.zero), isCanonical: true);
@@ -1431,7 +1434,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
final feeWei = BigInt.parse(feeString);
final amountAfterFeeWei = balanceWei > feeWei ? balanceWei - feeWei : BigInt.zero;
changeDepositAmount(
amount: wallet.currency.formatAmount(amountAfterFeeWei), isCanonical: true);
amount: wallet.currency.formatAmount(amountAfterFeeWei), isCanonical: true);
} catch (e) {
printV('Error calculating send all for EVM: $e');
changeDepositAmount(amount: balanceAmount, isCanonical: true);
@@ -1588,16 +1591,19 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
String? _addressTypeValidation(String refundAddress, String receiveAddress) {
final isRefundAddressSP = RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(refundAddress);
final isRefundAddressSP =
RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(refundAddress);
if (isRefundAddressSP) return 'Silent Payment ${S.current.address_not_allowed_as_refund}';
final isReceiveAddressSP = RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(receiveAddress);
final isReceiveAddressSP =
RegExp(AddressValidator.silentPaymentAddressPatternMainnet).hasMatch(receiveAddress);
if (isReceiveAddressSP) return 'Silent Payment ${S.current.address_not_allowed_as_receive}';
final isRefundAddressMWEB = RegExp(AddressValidator.mWebAddressPattern).hasMatch(refundAddress);
if (isRefundAddressMWEB) return 'MWEB ${S.current.address_not_allowed_as_refund}';
final isReceiveAddressMWEB = RegExp(AddressValidator.mWebAddressPattern).hasMatch(receiveAddress);
final isReceiveAddressMWEB =
RegExp(AddressValidator.mWebAddressPattern).hasMatch(receiveAddress);
if (isReceiveAddressMWEB) return 'MWEB ${S.current.address_not_allowed_as_receive}';
return null;
}
@@ -1678,7 +1684,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
@action
void toggleForceDecentralizedExchanges() {
_settingsStore.forceDecentralizedExchanges = !_settingsStore.forceDecentralizedExchanges;
if(forceDecentralizedExchanges) {
if (forceDecentralizedExchanges) {
final providers = selectedProviders.toList();
for (final provider in providers) {
if (forceDecentralizedExchanges && provider.description.isCentralized) {
@@ -1686,13 +1692,12 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
}
}
} else {
for(final provider in providerList) {
if(!selectedProviders.contains(provider) && provider.description.isCentralized) {
for (final provider in providerList) {
if (!selectedProviders.contains(provider) && provider.description.isCentralized) {
addExchangeProvider(provider);
}
}
}
}
void _setAvailableProviders() {
@@ -1714,9 +1719,7 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
int get receiveMaxDigits => receiveCurrency.decimals;
Future<CreateTradeResult> isCanCreateTrade(Trade trade) async {
if (trade.provider == ExchangeProviderDescription.swapsXyz) {
final tradeFrom = trade.from;
if (tradeFrom == null) {
@@ -1726,7 +1729,8 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
);
}
final isNativeSupportedToken = walletTypes.contains(cryptoCurrencyOrTokenToWalletType(tradeFrom));
final isNativeSupportedToken =
walletTypes.contains(cryptoCurrencyOrTokenToWalletType(tradeFrom));
if (!isNativeSupportedToken) {
bool _isEthToken() =>
@@ -1734,10 +1738,11 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
bool _isPolygonToken() =>
wallet.currency == CryptoCurrency.maticpoly &&
tradeFrom.tag == CryptoCurrency.maticpoly.tag;
tradeFrom.tag == CryptoCurrency.maticpoly.tag;
bool _isBaseToken() =>
wallet.currency == CryptoCurrency.baseEth && tradeFrom.tag == CryptoCurrency.baseEth.tag;
wallet.currency == CryptoCurrency.baseEth &&
tradeFrom.tag == CryptoCurrency.baseEth.tag;
bool _isTronToken() =>
wallet.currency == CryptoCurrency.trx && tradeFrom.tag == CryptoCurrency.trx.title;
@@ -1751,14 +1756,20 @@ abstract class ExchangeViewModelBase extends WalletChangeListenerViewModel with
bool isBscToken() =>
wallet.currency == CryptoCurrency.bnb && tradeFrom.tag == CryptoCurrency.bnb.tag;
if(!(_isEthToken() || _isPolygonToken() || _isBaseToken() || _isTronToken() || _isSplToken() || isArbitrumToken() || isBscToken())) {
if (!(_isEthToken() ||
_isPolygonToken() ||
_isBaseToken() ||
_isTronToken() ||
_isSplToken() ||
isArbitrumToken() ||
isBscToken())) {
return CreateTradeResult(
result: false,
errorMessage: 'This token isn’t supported on the current wallet/network for Swaps.xyz. Switch to a supported wallet or asset',
errorMessage:
'This token isn’t supported on the current wallet/network for Swaps.xyz. Switch to a supported wallet or asset',
);
}
}
}
if (trade.provider == ExchangeProviderDescription.thorChain) {
@@ -25,7 +25,7 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
BitboxViewModelBase() {
if (!Platform.isIOS && !isMoneroOnly) {
bitboxManager = sdk.BitboxManager();
}
}
}
@override
@@ -100,7 +100,8 @@ abstract class BitboxViewModelBase extends HardwareWalletViewModel with Store {
switch (wallet.type) {
case WalletType.bitcoin:
case WalletType.litecoin:
return bitcoin!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
return bitcoin!
.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
case WalletType.ethereum:
case WalletType.polygon:
return evm!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
@@ -27,4 +27,3 @@ abstract class HardwareWalletViewModel {
String? interpretErrorCode(String error) => null;
}
@@ -120,14 +120,12 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
} catch (_) {}
}
final ledger = device.connectionType == HardwareWalletConnectionType.ble
? ledgerPlusBLE
: ledgerPlusUSB;
final ledger =
device.connectionType == HardwareWalletConnectionType.ble ? ledgerPlusBLE : ledgerPlusUSB;
if (_connectionChangeSubscription == null) {
_connectionChangeSubscription = ledger
.deviceStateChanges(device.device.id)
.listen(_connectionChangeListener);
_connectionChangeSubscription =
ledger.deviceStateChanges(device.device.id).listen(_connectionChangeListener);
}
try {
@@ -182,9 +180,11 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
case WalletType.monero:
return monero!.setLedgerConnection(wallet, connection);
case WalletType.bitcoin:
return bitcoin!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
return bitcoin!
.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
case WalletType.litecoin:
return bitcoin!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
return bitcoin!
.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
case WalletType.ethereum:
case WalletType.polygon:
return evm!.setHardwareWalletService(wallet, await getHardwareWalletService(wallet.type));
@@ -210,7 +210,6 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
}
}
@override
String? interpretErrorCode(String error) {
if (error.contains("Make sure no other program is communicating with the Ledger")) {
@@ -224,8 +223,7 @@ abstract class LedgerViewModelBase extends HardwareWalletViewModel with Store {
return S.current.ledger_error_tx_rejected_by_user;
} else if (errorCode.contains("5515")) {
return S.current.ledger_error_device_locked;
} else
if (["6e01", "6a87", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
} else if (["6e01", "6a87", "6d02", "6511", "6e00"].any((e) => errorCode.contains(e))) {
return S.current.ledger_error_wrong_app;
}
return null;
@@ -142,12 +142,10 @@ abstract class TrezorConnectViewModelBase extends HardwareWalletViewModel with S
isDismissible: false,
enableDrag: false,
useSafeArea: true,
builder: (context) =>
HardwareWalletProceedOnDeviceSheet(
hardwareWalletType: hardwareWalletType,
trezorConnectVM: this,
onRetry: () => connectDevice(device, type, true)
),
builder: (context) => HardwareWalletProceedOnDeviceSheet(
hardwareWalletType: hardwareWalletType,
trezorConnectVM: this,
onRetry: () => connectDevice(device, type, true)),
);
}
@@ -234,7 +232,6 @@ abstract class TrezorConnectViewModelBase extends HardwareWalletViewModel with S
}
}
abstract class TrezorParingState {
static TrezorParingState initial = InitialTrezorParingState();
static TrezorParingState enterPin = EnterPinTrezorParingState();
@@ -243,11 +240,11 @@ abstract class TrezorParingState {
static TrezorParingState fail(String message) => FailTrezorParingState(message);
}
class InitialTrezorParingState extends TrezorParingState {}
class InitialTrezorParingState extends TrezorParingState {}
class EnterPinTrezorParingState extends TrezorParingState {}
class EnterPinTrezorParingState extends TrezorParingState {}
class VerifyingPinTrezorParingState extends TrezorParingState {}
class VerifyingPinTrezorParingState extends TrezorParingState {}
class SuccessTrezorParingState extends TrezorParingState {}
@@ -23,7 +23,8 @@ class DEuroViewModel = DEuroViewModelBase with _$DEuroViewModel;
abstract class DEuroViewModelBase with Store {
final AppStore _appStore;
static Money get MIN_ACCRUED_INTEREST => Money(BigInt.parse("1000000000000"), CryptoCurrency.deuro);
static Money get MIN_ACCRUED_INTEREST =>
Money(BigInt.parse("1000000000000"), CryptoCurrency.deuro);
static Money get ZERO => Money.zero(CryptoCurrency.deuro);
@@ -178,7 +179,7 @@ abstract class DEuroViewModelBase with Store {
}
final amount = tryParseFixed(amountRaw, 18);
if (amount == BigInt.zero || amount == null) {
throw Exception("Invalid amount: amount cannot be zero");
}
@@ -1,6 +1,5 @@
class AccountListItem {
AccountListItem(
{required this.label, required this.id, this.balance, this.isSelected = false});
AccountListItem({required this.label, required this.id, this.balance, this.isSelected = false});
final String label;
final int id;
@@ -21,7 +21,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
{required WalletBase wallet, AccountListItem? accountListItem})
: state = InitialExecutionState(),
isEdit = accountListItem != null,
label = accountListItem?.label??'',
label = accountListItem?.label ?? '',
_accountListItem = accountListItem,
_wallet = wallet;
@@ -76,14 +76,10 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
state = IsExecutingState();
if (_accountListItem != null) {
await _moneroAccountList.setLabelAccount(
_wallet,
accountIndex: _accountListItem.id,
label: label);
await _moneroAccountList.setLabelAccount(_wallet,
accountIndex: _accountListItem.id, label: label);
} else {
await _moneroAccountList.addAccount(
_wallet,
label: label);
await _moneroAccountList.addAccount(_wallet, label: label);
}
await _wallet.save();
@@ -98,14 +94,10 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
state = IsExecutingState();
if (_accountListItem != null) {
await _wowneroAccountList?.setLabelAccount(
_wallet,
accountIndex: _accountListItem.id,
label: label);
await _wowneroAccountList?.setLabelAccount(_wallet,
accountIndex: _accountListItem.id, label: label);
} else {
await _wowneroAccountList?.addAccount(
_wallet,
label: label);
await _wowneroAccountList?.addAccount(_wallet, label: label);
}
await _wallet.save();
@@ -114,5 +106,4 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
state = FailureState(e.toString());
}
}
}
@@ -10,11 +10,10 @@ import 'package:cake_wallet/monero/monero.dart';
part 'monero_account_list_view_model.g.dart';
class MoneroAccountListViewModel = MoneroAccountListViewModelBase
with _$MoneroAccountListViewModel;
class MoneroAccountListViewModel = MoneroAccountListViewModelBase with _$MoneroAccountListViewModel;
abstract class MoneroAccountListViewModelBase with Store {
MoneroAccountListViewModelBase(this._wallet,this.settingsStore) : scrollOffsetFromTop = 0;
MoneroAccountListViewModelBase(this._wallet, this.settingsStore) : scrollOffsetFromTop = 0;
final SettingsStore settingsStore;
@@ -32,25 +31,27 @@ abstract class MoneroAccountListViewModelBase with Store {
List<AccountListItem> get accounts {
final hideBalance = settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance;
if (_wallet.type == WalletType.monero) {
return monero
!.getAccountList(_wallet)
.accounts.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
balance: hideBalance ? '●●●●●●' : acc.balance,
isSelected: acc.id == monero!.getCurrentAccount(_wallet).id))
.toList();
return monero!
.getAccountList(_wallet)
.accounts
.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
balance: hideBalance ? '●●●●●●' : acc.balance,
isSelected: acc.id == monero!.getCurrentAccount(_wallet).id))
.toList();
}
if (_wallet.type == WalletType.wownero) {
return wownero
!.getAccountList(_wallet)
.accounts.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
balance: hideBalance ? '●●●●●●' : acc.balance,
isSelected: acc.id == wownero!.getCurrentAccount(_wallet).id))
.toList();
return wownero!
.getAccountList(_wallet)
.accounts
.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
balance: hideBalance ? '●●●●●●' : acc.balance,
isSelected: acc.id == wownero!.getCurrentAccount(_wallet).id))
.toList();
}
throw Exception('Unexpected wallet type: ${_wallet.type} for monero');
@@ -71,7 +72,7 @@ abstract class MoneroAccountListViewModelBase with Store {
item.id,
item.label,
item.balance,
);
);
}
if (_wallet.type == WalletType.wownero) {
@@ -80,7 +81,7 @@ abstract class MoneroAccountListViewModelBase with Store {
item.id,
item.label,
item.balance,
);
);
}
}
}
@@ -12,28 +12,25 @@ import 'package:permission_handler/permission_handler.dart';
part 'node_create_or_edit_view_model.g.dart';
class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase
with _$NodeCreateOrEditViewModel;
class NodeCreateOrEditViewModel = NodeCreateOrEditViewModelBase with _$NodeCreateOrEditViewModel;
abstract class NodeCreateOrEditViewModelBase with Store {
NodeCreateOrEditViewModelBase(
this.isPow, this.walletType, this._settingsStore, {this.editingNode})
NodeCreateOrEditViewModelBase(this.isPow, this.walletType, this._settingsStore,
{this.editingNode})
: state = InitialExecutionState(),
connectionState = InitialExecutionState(),
label = editingNode?.label ?? '',
address = editingNode?.uri.host.toString() ?? '',
path = editingNode?.path.toString() ?? '',
port = (editingNode != null && editingNode.uri.hasPort)
? editingNode.uri.port.toString()
: '',
port =
(editingNode != null && editingNode.uri.hasPort) ? editingNode.uri.port.toString() : '',
login = editingNode?.login ?? '',
password = editingNode?.password ?? '',
socksProxyAddress = editingNode?.socksProxyAddress ?? '',
trusted = editingNode?.trusted ?? false,
isEnabledForAutoSwitching =
editingNode?.isEnabledForAutoSwitching ?? false,
useSocksProxy = editingNode?.socksProxyAddress != null &&
editingNode!.socksProxyAddress!.isNotEmpty,
isEnabledForAutoSwitching = editingNode?.isEnabledForAutoSwitching ?? false,
useSocksProxy =
editingNode?.socksProxyAddress != null && editingNode!.socksProxyAddress!.isNotEmpty,
useSSL = editingNode?.useSSL ?? false {}
final nodeLabelUIKey = 'node_label_row_key';
@@ -113,11 +110,9 @@ abstract class NodeCreateOrEditViewModelBase with Store {
@observable
bool isPow;
@computed
bool get isReady =>
(address.isNotEmpty) ||
walletType == WalletType.decred; // Allow an empty address.
(address.isNotEmpty) || walletType == WalletType.decred; // Allow an empty address.
bool get hasAuthCredentials =>
walletType == WalletType.monero ||
@@ -240,8 +235,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
void setTrusted(bool val) => trusted = val;
@action
void setIsEnabledForAutoSwitching(bool val) =>
isEnabledForAutoSwitching = val;
void setIsEnabledForAutoSwitching(bool val) => isEnabledForAutoSwitching = val;
@action
void setSocksProxy(bool val) => useSocksProxy = val;
@@ -276,7 +270,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
}
state = ExecutedSuccessfullyState();
} catch (e) {
state = FailureState(e.toString());
}
@@ -303,7 +296,6 @@ abstract class NodeCreateOrEditViewModelBase with Store {
}
}
@action
void setAsCurrent(Node node) => _settingsStore.nodes[walletType] = node;
@@ -320,8 +312,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
throw Exception('Unexpected scan QR code value: value is empty');
}
if (code.startsWith("monero_node:"))
code = code.replaceFirst("monero_node:", "tcp://");
if (code.startsWith("monero_node:")) code = code.replaceFirst("monero_node:", "tcp://");
if (!code.contains('://')) code = 'tcp://$code';
final uri = Uri.tryParse(code);
@@ -16,7 +16,6 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
part 'node_list_view_model.g.dart';
class NodeSpeed {
final String iconPath;
final String darkIconPath;
@@ -24,21 +23,20 @@ class NodeSpeed {
// fraction of best node ping needed to be classified as this speed.
final double treshold;
const NodeSpeed._(this.iconPath, this.darkIconPath, this.treshold);
const NodeSpeed._(this.iconPath, this.darkIconPath, this.treshold);
static const disconnected = NodeSpeed._(
"assets/new-ui/node_speed_badges/disconnected.svg", "assets/new-ui/node_speed_badges/disconnected-dark.svg", 0);
static const slow = NodeSpeed._(
"assets/new-ui/node_speed_badges/slow.svg", "assets/new-ui/node_speed_badges/slow-dark.svg", 0);
static const medium = NodeSpeed._(
"assets/new-ui/node_speed_badges/medium.svg", "assets/new-ui/node_speed_badges/medium.svg", 0.5);
static const disconnected = NodeSpeed._("assets/new-ui/node_speed_badges/disconnected.svg",
"assets/new-ui/node_speed_badges/disconnected-dark.svg", 0);
static const slow = NodeSpeed._("assets/new-ui/node_speed_badges/slow.svg",
"assets/new-ui/node_speed_badges/slow-dark.svg", 0);
static const medium = NodeSpeed._("assets/new-ui/node_speed_badges/medium.svg",
"assets/new-ui/node_speed_badges/medium.svg", 0.5);
static const fast = NodeSpeed._(
"assets/new-ui/node_speed_badges/fast.svg", "assets/new-ui/node_speed_badges/fast.svg", 0.8);
static const all = [fast, medium, slow, disconnected];
}
class NodeListViewModel = NodeListViewModelBase with _$NodeListViewModel;
abstract class NodeListViewModelBase with Store {
@@ -63,7 +61,6 @@ abstract class NodeListViewModelBase with Store {
bindNodes();
});
}
@computed
Node get currentNode {
@@ -103,9 +100,8 @@ abstract class NodeListViewModelBase with Store {
final bool isPow;
final ObservableMap<String, int> _nodeSpeeds;
@computed
List<Node> get nonCurrentNodes => nodes.where((item)=>item != currentNode).toList();
List<Node> get nonCurrentNodes => nodes.where((item) => item != currentNode).toList();
@observable
bool isTestingNodeSpeed = false;
@@ -117,9 +113,8 @@ abstract class NodeListViewModelBase with Store {
final nodes = this.nodes.toList();
await Future.wait(nodes.map((node) async {
final sw = Stopwatch()..start();
final res = await node
.requestNode()
.timeout(const Duration(seconds: 10), onTimeout: () => false);
final res =
await node.requestNode().timeout(const Duration(seconds: 10), onTimeout: () => false);
sw.stop();
if (res) {
_nodeSpeeds[node.uriRaw] = sw.elapsedMilliseconds;
@@ -163,7 +158,6 @@ abstract class NodeListViewModelBase with Store {
Node node;
if (walletType == WalletType.bitcoin && wallet.isTestnet) {
node = (await getBitcoinTestnetDefaultElectrumServer())!;
} else if (isEVMCompatibleChain(walletType)) {
final chainId = evm!.getSelectedChainId(wallet);
if (chainId != null) {
@@ -205,12 +199,11 @@ abstract class NodeListViewModelBase with Store {
}
// For non-EVM wallets, use the wallet type directly
if(isPow) {
if (isPow) {
settingsStore.powNodes[walletType] = node;
} else {
settingsStore.nodes[walletType] = node;
}
}
@action
@@ -235,7 +228,8 @@ abstract class NodeListViewModelBase with Store {
}
// For non-EVM wallets, use the wallet type directly
nodes.addAll(isPow ? await Node.getAllForWalletTypePow(walletType) : await Node.getAllForWalletType(walletType));
nodes.addAll(isPow
? await Node.getAllForWalletTypePow(walletType)
: await Node.getAllForWalletType(walletType));
}
}
@@ -0,0 +1 @@
@@ -18,8 +18,7 @@ import 'package:url_launcher/url_launcher.dart';
part 'payjoin_details_view_model.g.dart';
class PayjoinDetailsViewModel = PayjoinDetailsViewModelBase
with _$PayjoinDetailsViewModel;
class PayjoinDetailsViewModel = PayjoinDetailsViewModelBase with _$PayjoinDetailsViewModel;
abstract class PayjoinDetailsViewModelBase with Store {
PayjoinDetailsViewModelBase(
@@ -61,8 +60,7 @@ abstract class PayjoinDetailsViewModelBase with Store {
),
TradeDetailsListCardItem(
id: "${payjoinSession.isSenderSession ? S.current.outgoing : S.current.incoming} Payjoin",
createdAt:
dateFormat.format(payjoinSession.inProgressSince!).toString(),
createdAt: dateFormat.format(payjoinSession.inProgressSince!).toString(),
pair:
'${bitcoin!.formatterBitcoinAmountToString(amount: payjoinSession.amount.toInt())} BTC',
onTap: (_) {},
+1 -1
View File
@@ -31,7 +31,7 @@ abstract class RescanViewModelBase with Store {
@computed
bool get isMwebScan => wallet.type == WalletType.litecoin;
Future<bool> get isBitcoinMempoolAPIEnabled async =>
wallet.type == WalletType.bitcoin && await bitcoin!.checkIfMempoolAPIIsEnabled(wallet);
+1 -1
View File
@@ -1 +1 @@
enum WalletRestoreMode { seed, keys, txids }
enum WalletRestoreMode { seed, keys, txids }
@@ -32,7 +32,7 @@ abstract class RestoreFromBackupViewModelBase with Store {
void reset() => filePath = '';
@action
Future<void> import(String password,{bool checkBackupApp = true}) async {
Future<void> import(String password, {bool checkBackupApp = true}) async {
try {
state = IsExecutingState();
@@ -49,7 +49,8 @@ abstract class RestoreFromBackupViewModelBase with Store {
rethrow;
} catch (e, s) {
if (e.toString().contains("unknown_backup_version")) {
state = FailureState('This is not a valid backup file, please make sure you have selected the correct one');
state = FailureState(
'This is not a valid backup file, please make sure you have selected the correct one');
} else {
state = FailureState(e.toString() + "\n" + s.toString());
}
+2 -1
View File
@@ -14,7 +14,8 @@ abstract class SeedSettingsViewModelBase with Store {
MoneroSeedType get moneroSeedType => _appStore.settingsStore.moneroSeedType;
@action
void setMoneroSeedType(MoneroSeedType seedType) => _appStore.settingsStore.moneroSeedType = seedType;
void setMoneroSeedType(MoneroSeedType seedType) =>
_appStore.settingsStore.moneroSeedType = seedType;
@computed
BitcoinSeedType get bitcoinSeedType => _appStore.settingsStore.bitcoinSeedType;
+8 -7
View File
@@ -37,8 +37,7 @@ class Output = OutputBase with _$Output;
abstract class OutputBase with Store {
OutputBase(this._wallet, this._appStore, this._fiatConversationStore, this.cryptoCurrencyHandler)
:
key = UniqueKey(),
: key = UniqueKey(),
sendAll = false,
cryptoAmount = '',
cryptoFullBalance = '',
@@ -57,7 +56,6 @@ abstract class OutputBase with Store {
});
}
Key key;
bool get useSatoshi => _appStore.amountParsingProxy.useSatoshi(cryptoCurrencyHandler());
@@ -98,7 +96,6 @@ abstract class OutputBase with Store {
@observable
String extractedAddress;
@computed
bool get isParsedAddress =>
parsedAddress.addressSource != AddressSource.notParsed && parsedAddress.handle.isNotEmpty;
@@ -172,9 +169,11 @@ abstract class OutputBase with Store {
break;
case WalletType.tron:
if (cryptoCurrencyHandler() == CryptoCurrency.trx) {
estimatedFee = tron!.getTronNativeEstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
estimatedFee =
tron!.getTronNativeEstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
} else {
estimatedFee = tron!.getTronTRC20EstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
estimatedFee =
tron!.getTronTRC20EstimatedFee(_wallet) ?? Money.zero(CryptoCurrency.trx);
}
break;
@@ -200,7 +199,8 @@ abstract class OutputBase with Store {
? evm!.getEVMNativeEstimatedFee(_wallet)
: evm!.getEVMERC20EstimatedFee(_wallet);
estimatedFee = Money(BigInt.parse(fee ?? '0.0'), walletTypeToCryptoCurrency(_wallet.type));
estimatedFee =
Money(BigInt.parse(fee ?? '0.0'), walletTypeToCryptoCurrency(_wallet.type));
break;
/// end EVMs
@@ -293,6 +293,7 @@ abstract class OutputBase with Store {
}
@action
/// [setCryptoAmount] always takes in the canonical representation eg. Bitcoin and not Sats
void setCryptoAmount(String amount) {
if (amount.toUpperCase() != S.current.all) sendAll = false;
@@ -35,9 +35,7 @@ abstract class SendTemplateViewModelBase with Store {
@action
void addRecipient() {
recipients.add(TemplateViewModel(
wallet: _wallet,
appStore: _appStore,
fiatConversationStore: _fiatConversationStore));
wallet: _wallet, appStore: _appStore, fiatConversationStore: _fiatConversationStore));
}
@action
+59 -83
View File
@@ -85,8 +85,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
currencies = wallet.balance.keys.toList();
selectedCryptoCurrency =
coinTypeToSpendFrom == UnspentCoinType.lightning ? CryptoCurrency.btcln : wallet.currency;
hasMultipleTokens = isEVMWallet ||
[WalletType.solana, WalletType.tron, WalletType.zano].contains(wallet.type);
hasMultipleTokens =
isEVMWallet || [WalletType.solana, WalletType.tron, WalletType.zano].contains(wallet.type);
for (final output in outputs) {
output.updateWallet(wallet);
@@ -195,7 +195,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
if (isValidAddress) return null;
}
final results = await _adrResService.resolve(
query: query,
wallet: wallet,
@@ -411,9 +410,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
final sp = RegExp(AddressValidator.silentPaymentAddressPatternMainnet);
final address = output.extractedAddress.isNotEmpty
? output.extractedAddress
: output.address;
final address = output.extractedAddress.isNotEmpty ? output.extractedAddress : output.address;
return sp.hasMatch(address);
}
@@ -467,7 +464,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
FiatCurrency get fiatCurrency => _settingsStore.fiatCurrency;
set fiatCurrency(FiatCurrency value) {
_settingsStore.fiatCurrency = value;
_settingsStore.fiatCurrency = value;
}
List<FiatCurrency> fiatCurrencies;
@@ -530,7 +527,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
@computed
TransactionInfo? get transactionInfo {
if(isEVMCompatibleChain(walletType)) {
if (isEVMCompatibleChain(walletType)) {
return wallet.transactionHistory.transactions[pendingTransaction?.evmTxHashFromRawHex];
}
if (walletType == WalletType.monero) {
@@ -633,7 +630,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
clearOutputs();
outputs.first.address = paymentRequest.address;
outputs.first.parsedAddress = ParsedAddress(parsedAddressByCurrencyMap: {currency:paymentRequest.address}, handle: ocpRequest!.receiverName);
outputs.first.parsedAddress = ParsedAddress(
parsedAddressByCurrencyMap: {currency: paymentRequest.address},
handle: ocpRequest!.receiverName);
outputs.first.setCryptoAmount(paymentRequest.amount);
outputs.first.note = ocpRequest!.receiverName;
@@ -694,13 +693,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
final routerTo = trade.inputAddress;
final routerData = trade.routerData;
if (routerData != null && routerData != '0x') {
final tokenContract = (trade.sourceTokenAddress ?? '').toLowerCase();
final priority = _settingsStore.getPriority(
walletType, chainId: selectedChainId);
final routerValueWei = BigInt.tryParse(trade.routerValue ?? '0') ??
BigInt.zero;
final priority = _settingsStore.getPriority(walletType, chainId: selectedChainId);
final routerValueWei = BigInt.tryParse(trade.routerValue ?? '0') ?? BigInt.zero;
if (routerTo == null || routerTo.isEmpty) {
state = FailureState('Invalid router address');
@@ -730,33 +726,26 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
// Smart Swap (Requires Approval)
if (selector == swapAndExecuteSig) {
final requiredAmount = BigInt.tryParse(
(trade.sourceTokenAmountRaw ?? '0').replaceAll('n', '')) ??
BigInt.zero;
final requiredAmount =
BigInt.tryParse((trade.sourceTokenAmountRaw ?? '0').replaceAll('n', '')) ??
BigInt.zero;
final needsApproval = tokenContract.isNotEmpty &&
requiredAmount > BigInt.zero
? await evm!.isApprovalRequired(
wallet, tokenContract, routerTo, requiredAmount)
final needsApproval = tokenContract.isNotEmpty && requiredAmount > BigInt.zero
? await evm!.isApprovalRequired(wallet, tokenContract, routerTo, requiredAmount)
: false;
printV(
'[Swaps.xyz sending flow] Approval required: $needsApproval for token ${trade
.from?.title} ${trade.from?.tag ??
''} with amount $requiredAmount');
'[Swaps.xyz sending flow] Approval required: $needsApproval for token ${trade.from?.title} ${trade.from?.tag ?? ''} with amount $requiredAmount');
if (needsApproval) {
// USDT Approval Flow (Special Case). We must reset allowance to 0 first.
final isUSDTMainnet = selectedChainId == 1 &&
tokenContract.toLowerCase() ==
'0xdac17f958d2ee523a2206206994597c13d831ec7';
tokenContract.toLowerCase() == '0xdac17f958d2ee523a2206206994597c13d831ec7';
if (isUSDTMainnet) {
final currentAllowance = await evm!.getAllowance(
wallet, tokenContract, routerTo);
final currentAllowance = await evm!.getAllowance(wallet, tokenContract, routerTo);
if (currentAllowance != null &&
currentAllowance > BigInt.zero) {
if (currentAllowance != null && currentAllowance > BigInt.zero) {
printV(
'[Swaps.xyz sending flow] currentAllowance USDT: $currentAllowance. Resetting to 0 before setting new allowance.');
@@ -766,8 +755,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
requiredAmount: BigInt.zero,
// Approve 0
sourceTokenDecimals: trade.sourceTokenDecimals,
priority: priority
);
priority: priority);
if (resetTx != null) {
await resetTx.commit();
@@ -780,8 +768,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
);
if (!resetConfirmed) {
state = FailureState(
'Failed to reset USDT allowance. Please try again.');
state = FailureState('Failed to reset USDT allowance. Please try again.');
return null;
}
printV(
@@ -796,8 +783,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
tokenContract: tokenContract,
requiredAmount: requiredAmount,
sourceTokenDecimals: trade.sourceTokenDecimals,
priority: priority
);
priority: priority);
if (approvalTx == null) {
state = FailureState('Failed to build approval transaction');
@@ -808,8 +794,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
try {
printV(
'[Swaps.xyz sending flow] Submitting approval transaction for token ${trade
.from?.title} ${trade.from?.tag ?? ''} ');
'[Swaps.xyz sending flow] Submitting approval transaction for token ${trade.from?.title} ${trade.from?.tag ?? ''} ');
await approvalTx.commit();
// Wait for the approval to be mined on-chain
@@ -827,10 +812,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
printV(
'[Swaps.xyz sending flow] Approval transaction confirmed on-chain. Proceeding with swap execution.');
} catch (e, s) {
printV(
'[Swaps.xyz sending flow] Approval transaction error: $e\n$s');
state = FailureState(
translateErrorMessage(e, wallet.type, wallet.currency));
printV('[Swaps.xyz sending flow] Approval transaction error: $e\n$s');
state = FailureState(translateErrorMessage(e, wallet.type, wallet.currency));
return null;
}
}
@@ -859,8 +842,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
} catch (e, s) {
printV('Swaps.xyz transaction error: $e\n$s');
state = FailureState(
'Failed to create Swaps.xyz transaction - ${translateErrorMessage(
e, wallet.type, wallet.currency)}');
'Failed to create Swaps.xyz transaction - ${translateErrorMessage(e, wallet.type, wallet.currency)}');
return null;
}
}
@@ -902,14 +884,12 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
// Regular flow
final isSendAll = outputs.any((output) => output.sendAll);
if (!isSendAll) {
final estimateTxAmountDouble = outputs.fold<double>(0, (acc, output) =>
acc + (double.tryParse(output.cryptoAmount) ?? 0));
if (estimateTxAmountDouble <= 0) throw Exception(
'Amount must be greater than 0');
final estimateTxAmountDouble = outputs.fold<double>(
0, (acc, output) => acc + (double.tryParse(output.cryptoAmount) ?? 0));
if (estimateTxAmountDouble <= 0) throw Exception('Amount must be greater than 0');
}
pendingTransaction = await wallet.createTransaction(_credentials(provider));
@@ -942,7 +922,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
}
if (wallet.type == WalletType.bitcoin) {
final updatedOutputs = bitcoin!.updateOutputs(pendingTransaction!, outputs);
@@ -1030,7 +1009,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
throw Exception("Pending transaction doesn't exist. It should not be happened.");
}
try {
state = wallet.isHardwareWallet && walletType == WalletType.monero
? IsAwaitingDeviceResponseState()
@@ -1124,7 +1102,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
}
// Immediate transaction update for EVM chains, Tron, and Nano
if (isEVMWallet || [WalletType.bitcoin, WalletType.solana, WalletType.tron, WalletType.nano].contains(walletType)) {
if (isEVMWallet ||
[WalletType.bitcoin, WalletType.solana, WalletType.tron, WalletType.nano]
.contains(walletType)) {
Future.delayed(Duration(seconds: 4), () async {
try {
await Future.wait([
@@ -1140,7 +1120,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
// FIXME(malik) ideally, this should be done wallet-side.
// it is required because evm, solana and tron don't actually save the transaction info when you send something.
// instead, they rely on the tx to eventually get fetched at sync time, which can take a while
if(isEVMWallet) {
if (isEVMWallet) {
wallet.transactionHistory.addOne(evm!.getTransactionInfo(
id: pendingTransaction!.evmTxHashFromRawHex!,
height: 0,
@@ -1154,8 +1134,8 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
chainId: wallet.chainId ?? 0,
));
}
if(walletType == WalletType.solana) {
if (walletType == WalletType.solana) {
wallet.transactionHistory.addOne(solana!.getTransactionInfo(
id: pendingTransaction!.id,
blockTime: DateTime.now(),
@@ -1211,7 +1191,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
Future<void> updateWalletBalance() async => await wallet.updateBalance();
Future<void> _addTransactionDescription() async {
String address = outputs.fold('', (acc, value) {
String address = outputs.fold('', (acc, value) {
final canonical = value.extractedAddress.trim().isNotEmpty
? value.extractedAddress.trim()
: value.address.trim();
@@ -1360,15 +1340,15 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
@computed
int get maxMemoLength => _maxMemoLengths[wallet.type] ?? 9999999;
ContactRecord? newContactAddress() {
final Set<String> contactAddresses =
Set.from(contactListViewModel.contacts.map((contact) => contact.address))
..addAll(contactListViewModel.walletContacts.map((contact) => contact.address));
for (final output in outputs) {
final address =
output.isParsedAddress ? output.parsedAddress.parsedAddressByCurrencyMap[selectedCryptoCurrency] ?? '' : output.address;
final address = output.isParsedAddress
? output.parsedAddress.parsedAddressByCurrencyMap[selectedCryptoCurrency] ?? ''
: output.address;
if (address.isNotEmpty &&
!contactAddresses.contains(address) &&
@@ -1400,14 +1380,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
int attempts = 0;
const int maxAttempts = 30; // ~60 seconds
printV('[Swaps.xyz sending flow] Starting allowance check. Target: $requiredAmount (Exact match: $waitForExactMatch)');
printV(
'[Swaps.xyz sending flow] Starting allowance check. Target: $requiredAmount (Exact match: $waitForExactMatch)');
while (attempts < maxAttempts) {
try {
final currentAllowance = await evm!.getAllowance(wallet, tokenContract, spender);
if (currentAllowance != null) {
printV('[Swaps.xyz sending flow] Current Allowance: $currentAllowance / Target: $requiredAmount');
printV(
'[Swaps.xyz sending flow] Current Allowance: $currentAllowance / Target: $requiredAmount');
if (waitForExactMatch) {
// For Reset (Target 0): We need it to be exactly 0 (or less, though it can't be negative)
@@ -1443,17 +1425,16 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
required TransactionPriority? priority,
int? sourceTokenDecimals,
}) async {
final erc20Token = wallet.balance.keys.whereType<Erc20Token>().firstWhere(
(t) => t.contractAddress.toLowerCase() == tokenContract.toLowerCase(),
orElse: () => Erc20Token(
name: '',
symbol: '',
contractAddress: tokenContract,
decimal: sourceTokenDecimals ?? 18,
enabled: true,
),
);
orElse: () => Erc20Token(
name: '',
symbol: '',
contractAddress: tokenContract,
decimal: sourceTokenDecimals ?? 18,
enabled: true,
),
);
return await evm!.createTokenApproval(
wallet,
@@ -1461,7 +1442,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
spender,
priority,
useBlinkProtection:
canSupportBlinkProtection(selectedChainId) ? _settingsStore.useBlinkProtection : false,
canSupportBlinkProtection(selectedChainId) ? _settingsStore.useBlinkProtection : false,
);
}
@@ -1646,9 +1627,9 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return S.current.tx_invalid_input;
}
if(wallet.type == WalletType.bitcoin) {
if (wallet.type == WalletType.bitcoin) {
final lnError = getLightningErrorMessage(error);
if(lnError != null) return lnError;
if (lnError != null) return lnError;
}
return errorMessage;
@@ -1656,12 +1637,10 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
String? getLightningErrorMessage(Object error) {
// TODO add more patterns
Map<String, String> errorPatterns = {
"insufficient funds": S.current.insufficient_funds_for_tx
};
Map<String, String> errorPatterns = {"insufficient funds": S.current.insufficient_funds_for_tx};
for(final pattern in errorPatterns.keys) {
if(error.toString().contains(pattern)) return errorPatterns[pattern]!;
for (final pattern in errorPatterns.keys) {
if (error.toString().contains(pattern)) return errorPatterns[pattern]!;
}
return null;
@@ -1677,7 +1656,6 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
Future<void> registerSwapsXyzTransaction(Trade trade) async {
try {
// register only for vmId is alt-vm or bridgeId is alt-vm (trade.needToRegisterInSwapXyz)
final needToRegister = trade.needToRegisterInSwapXyz ?? false;
if (!needToRegister) return;
@@ -1688,9 +1666,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
return;
}
final txHash = pendingTransaction?.evmTxHashFromRawHex
?? pendingTransaction?.id
?? '';
final txHash = pendingTransaction?.evmTxHashFromRawHex ?? pendingTransaction?.id ?? '';
if (txHash.isEmpty) {
printV('SwapsXyz: transaction register: skipped (txHash empty)');
@@ -1,6 +1,9 @@
import 'package:cake_wallet/core/execution_state.dart';
class IsDeviceSigningResponseState extends IsExecutingState {}
class IsAwaitingDeviceResponseState extends IsExecutingState {}
class TransactionCommitting extends ExecutionState {}
class TransactionCommitted extends ExecutionState {}
@@ -232,7 +232,6 @@ abstract class ConnectionSyncViewModelBase with Store {
@computed
bool get canUseTronGrid => _wallet.type == WalletType.tron;
@action
void setUseMempoolFeeAPI(bool value) => _settingsStore.useMempoolFeeAPI = value;
@@ -249,7 +248,10 @@ abstract class ConnectionSyncViewModelBase with Store {
@action
void setUseBlinkProtection(bool value) => _settingsStore.useBlinkProtection = value;
bool get hasRescan => _wallet.hasRescan && _wallet.type != WalletType.bitcoin && _wallet.type != WalletType.litecoin;
bool get hasRescan =>
_wallet.hasRescan &&
_wallet.type != WalletType.bitcoin &&
_wallet.type != WalletType.litecoin;
@action
void setUseEtherscan(bool value) {
@@ -59,7 +59,7 @@ abstract class DisplaySettingsViewModelBase with Store {
@computed
bool get showAddressBookPopup => _settingsStore.showAddressBookPopupEnabled;
@computed
bool get showZcashCard => _settingsStore.showZcashMissingFundsCard;
@@ -126,7 +126,8 @@ abstract class DisplaySettingsViewModelBase with Store {
bool get showZcashCardSetting => _appStore.wallet?.type == WalletType.zcash;
@action
void setDisplayAmountsInSatoshi(BitcoinAmountDisplayMode value) => _settingsStore.displayAmountsInSatoshi = value;
void setDisplayAmountsInSatoshi(BitcoinAmountDisplayMode value) =>
_settingsStore.displayAmountsInSatoshi = value;
@action
void setShowZcashCard(bool value) => _settingsStore.showZcashMissingFundsCard = value;
+6 -6
View File
@@ -5,11 +5,11 @@ import 'package:flutter/material.dart';
class LinkListItem extends SettingsListItem {
LinkListItem(
{required String title,
required this.link,
required this.linkTitle,
this.icon,
this.lightIcon,
this.hasIconColor = false})
required this.link,
required this.linkTitle,
this.icon,
this.lightIcon,
this.hasIconColor = false})
: super(title);
final String? icon;
@@ -17,4 +17,4 @@ class LinkListItem extends SettingsListItem {
final String link;
final String linkTitle;
final bool hasIconColor;
}
}
@@ -66,18 +66,18 @@ abstract class OtherSettingsViewModelBase with Store {
void setAutoGenerateSubaddresses(bool value) {
_wallet.isEnabledAutoGenerateSubaddress = value;
_settingsStore.autoGenerateSubaddressStatus =
value ? AutoGenerateSubaddressStatus.enabled : AutoGenerateSubaddressStatus.disabled;
value ? AutoGenerateSubaddressStatus.enabled : AutoGenerateSubaddressStatus.disabled;
}
bool get isAutoGenerateSubaddressesVisible => [
WalletType.monero,
WalletType.wownero,
WalletType.bitcoin,
WalletType.litecoin,
WalletType.bitcoinCash,
WalletType.dogecoin,
WalletType.decred
].contains(_wallet.type);
WalletType.monero,
WalletType.wownero,
WalletType.bitcoin,
WalletType.litecoin,
WalletType.bitcoinCash,
WalletType.dogecoin,
WalletType.decred
].contains(_wallet.type);
@computed
bool get isMoneroWallet => _wallet.type == WalletType.monero;
@@ -49,8 +49,7 @@ abstract class PrivacySettingsViewModelBase with Store {
].contains(_wallet.type);
@computed
bool get hasCoinControl =>
[
bool get hasCoinControl => [
WalletType.bitcoin,
WalletType.litecoin,
WalletType.monero,
@@ -112,7 +111,8 @@ abstract class PrivacySettingsViewModelBase with Store {
bool get canUsePayjoin => _wallet.type == WalletType.bitcoin && DeviceInfo.instance.isMobile;
@computed
bool get canUseLightning => _wallet.type == WalletType.bitcoin && !Platform.isWindows && !Platform.isLinux;
bool get canUseLightning =>
_wallet.type == WalletType.bitcoin && !Platform.isWindows && !Platform.isLinux;
@computed
bool get useLightning => _wallet.type == WalletType.bitcoin && bitcoin!.useLightning(_wallet);
@@ -5,4 +5,4 @@ class RegularListItem extends SettingsListItem {
RegularListItem({required String title, this.handler}) : super(title);
final void Function(BuildContext context)? handler;
}
}
@@ -9,7 +9,8 @@ part 'security_settings_view_model.g.dart';
class SecuritySettingsViewModel = SecuritySettingsViewModelBase with _$SecuritySettingsViewModel;
abstract class SecuritySettingsViewModelBase with Store {
SecuritySettingsViewModelBase(this._settingsStore, this._authService) : _biometricAuth = BiometricAuth();
SecuritySettingsViewModelBase(this._settingsStore, this._authService)
: _biometricAuth = BiometricAuth();
final BiometricAuth _biometricAuth;
final SettingsStore _settingsStore;
@@ -51,9 +52,7 @@ abstract class SecuritySettingsViewModelBase with Store {
_settingsStore.pinTimeOutDuration = duration;
@action
void setEnableDuressPin(bool value) =>
_settingsStore.enableDuressPin = value;
void setEnableDuressPin(bool value) => _settingsStore.enableDuressPin = value;
Future<void> clearDuressPin() async => await _authService.clearDuressPin();
}
@@ -3,10 +3,7 @@ import 'package:flutter/foundation.dart';
import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
class SwitcherListItem extends SettingsListItem {
SwitcherListItem(
{required String title,
required this.value,
required this.onValueChange})
SwitcherListItem({required String title, required this.value, required this.onValueChange})
: super(title);
final bool Function() value;
@@ -28,10 +28,7 @@ abstract class TrocadorProvidersViewModelBase with Store {
ObservableFuture(trocadorExchangeProvider.fetchProviders().then((providers) {
var providerNames = providers.map((e) => e.name).toList();
providerRatings = {
for (var provider in providers)
provider.name: provider.rating
};
providerRatings = {for (var provider in providers) provider.name: provider.rating};
return _settingsStore
.updateAllTrocadorProviderStates(providerNames)
@@ -3,4 +3,4 @@ import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
class VersionListItem extends SettingsListItem {
VersionListItem({required String title}) : super(title);
}
}
@@ -4,8 +4,7 @@ import 'package:cake_wallet/entities/secret_store_key.dart';
import 'package:cake_wallet/store/settings_store.dart';
class SetupPinCodeViewModel {
SetupPinCodeViewModel(this._authService, this._settingsStore,
{this.isDuressPin = false})
SetupPinCodeViewModel(this._authService, this._settingsStore, {this.isDuressPin = false})
: _pinCodeLength = _settingsStore.pinCodeLength;
String originalPinCode = '';
@@ -46,7 +45,6 @@ class SetupPinCodeViewModel {
originalPinCode = pin;
if (isDuressPin && pin.length == pinCodeLength) {
final regularKey = generateStoreKeyFor(key: SecretStoreKey.pinCodePassword);
final encodedRegularPin = await _authService.secureStorage.read(key: regularKey);
@@ -84,7 +82,6 @@ class SetupPinCodeViewModel {
return;
}
await _authService.setPassword(repeatedPinCode);
_settingsStore.pinCodeLength = pinCodeLength;
}
+8 -5
View File
@@ -40,7 +40,7 @@ abstract class StartTorViewModelBase with Store {
remainingSeconds = waitTimeInSeconds;
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
remainingSeconds -= 1;
if (remainingSeconds <= 0) {
timer.cancel();
timeoutReached = true;
@@ -66,7 +66,8 @@ abstract class StartTorViewModelBase with Store {
didStartTor = true;
final appStore = getIt.get<AppStore>();
bootstrapOnline(navigatorKey, loadWallet: true);
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
appStore.wallet
?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
Navigator.pushReplacementNamed(context, Routes.login);
}
@@ -76,7 +77,8 @@ abstract class StartTorViewModelBase with Store {
settingsStore.currentBuiltinTor = false;
bootstrapOnline(navigatorKey, loadWallet: true);
final appStore = getIt.get<AppStore>();
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
appStore.wallet
?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
Navigator.pushReplacementNamed(context, Routes.login);
}
@@ -84,7 +86,8 @@ abstract class StartTorViewModelBase with Store {
void ignoreAndLaunchApp(BuildContext context) {
bootstrapOnline(navigatorKey, loadWallet: true);
final appStore = getIt.get<AppStore>();
appStore.wallet?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
appStore.wallet
?.connectToNode(node: appStore.settingsStore.getCurrentNode(appStore.wallet!.type));
Navigator.pushReplacementNamed(context, Routes.login);
}
@@ -92,4 +95,4 @@ abstract class StartTorViewModelBase with Store {
_timer?.cancel();
_timer = null;
}
}
}
+10 -14
View File
@@ -117,13 +117,13 @@ abstract class TradeDetailsViewModelBase with Store {
case ExchangeProviderDescription.chainflip:
return 'https://scan.chainflip.io/channels/${trade.id}';
case ExchangeProviderDescription.xoSwap:
return 'https://orders.xoswap.com/${trade.id}';
return 'https://orders.xoswap.com/${trade.id}';
case ExchangeProviderDescription.swapsXyz:
return 'https://scan.swaps.xyz/transactions/${trade.id}';
return 'https://scan.swaps.xyz/transactions/${trade.id}';
case ExchangeProviderDescription.jupiter:
return 'https://solscan.io/tx/${trade.txId}';
case ExchangeProviderDescription.nearIntents:
return 'https://explorer.near-intents.org/transactions/${trade.id}';
return 'https://explorer.near-intents.org/transactions/${trade.id}';
}
return null;
}
@@ -167,7 +167,7 @@ abstract class TradeDetailsViewModelBase with Store {
DetailsListStatusItem(title: S.current.trade_details_state, value: trade.state.toString()));
final tradeFrom = trade.from;
final tradeTo = trade.to;
final tradeTo = trade.to;
if (tradeFrom != null && tradeTo != null) {
items.add(TradeDetailsListCardItem.tradeDetails(
@@ -185,9 +185,7 @@ abstract class TradeDetailsViewModelBase with Store {
final destinationMemo = trade.toAddressExtraId;
final destinationCurrency = trade.to;
if (destinationMemo != null &&
destinationMemo.isNotEmpty &&
destinationCurrency != null) {
if (destinationMemo != null && destinationMemo.isNotEmpty && destinationCurrency != null) {
final isDestinationTag =
memoLabelTypeFor(destinationCurrency) == MemoLabelType.destinationTag;
items.add(StandartListItem(
@@ -205,8 +203,7 @@ abstract class TradeDetailsViewModelBase with Store {
}
if (trade.isRefund == true) {
items.add(StandartListItem(
title: 'Refund', value: trade.refundAddress ?? ''));
items.add(StandartListItem(title: 'Refund', value: trade.refundAddress ?? ''));
}
if (trade.provider == ExchangeProviderDescription.trocador) {
@@ -220,9 +217,10 @@ abstract class TradeDetailsViewModelBase with Store {
}
}
if (trade.provider == ExchangeProviderDescription.swapsXyz && trade.txId != null && trade.txId!.isNotEmpty) {
items.add(StandartListItem(
title: 'Transaction ID', value: trade.txId!));
if (trade.provider == ExchangeProviderDescription.swapsXyz &&
trade.txId != null &&
trade.txId!.isNotEmpty) {
items.add(StandartListItem(title: 'Transaction ID', value: trade.txId!));
}
}
@@ -232,6 +230,4 @@ abstract class TradeDetailsViewModelBase with Store {
launchUrl(uri, mode: LaunchMode.externalApplication);
} catch (e) {}
}
}
@@ -76,7 +76,9 @@ class TxDetailRowDefinition {
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_date_key",
title: S.current.transaction_details_date,
valueGetter: (vm) => DateFormat("d MMMM yyyy, HH:mm", vm._appStore.settingsStore.languageCode).format(vm.transactionInfo.date)),
valueGetter: (vm) =>
DateFormat("d MMMM yyyy, HH:mm", vm._appStore.settingsStore.languageCode)
.format(vm.transactionInfo.date)),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_height_key",
title: S.current.transaction_details_height,
@@ -85,7 +87,6 @@ class TxDetailRowDefinition {
![WalletType.solana, WalletType.tron].contains(vm.wallet.type) ||
!isLightning(vm.transactionInfo),
),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_fee_key",
title: S.current.transaction_details_fee,
@@ -93,8 +94,6 @@ class TxDetailRowDefinition {
applicable: (vm) =>
vm.wallet.type != WalletType.nano &&
(vm.transactionInfo.fee?.toStringWithSymbol() ?? "").isNotEmpty),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_confirmations_key",
title: S.current.confirmations,
@@ -104,8 +103,6 @@ class TxDetailRowDefinition {
.contains(vm.wallet.type) &&
!isLightning(vm.transactionInfo),
listItemBuilder: ConfirmationsListItem.new),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_recipient_address_key",
title: S.current.transaction_details_recipient_address,
@@ -125,12 +122,12 @@ class TxDetailRowDefinition {
.firstOrNull ??
"";
case WalletType.tron:
if(vm.transactionInfo.to != null)
ret = tron!.getTronBase58Address(vm.transactionInfo.to!, vm.wallet);
if (vm.transactionInfo.to != null)
ret = tron!.getTronBase58Address(vm.transactionInfo.to!, vm.wallet);
default:
break;
}
if(ret == null) {
if (ret == null) {
ret = vm.transactionInfo.to ?? "";
}
final resolvedAddress = _moneroRecipientAddressForDisplay(ret, vm.wallet.type);
@@ -144,8 +141,6 @@ class TxDetailRowDefinition {
vm.wallet.type == WalletType.bitcoin &&
vm.transactionInfo.direction == TransactionDirection.incoming),
listItemBuilder: AddressListItem.new),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_source_address_key",
title: S.current.transaction_details_source_address,
@@ -159,7 +154,6 @@ class TxDetailRowDefinition {
},
applicable: (vm) => vm.transactionInfo.from != null,
listItemBuilder: AddressListItem.new),
TxDetailRowDefinition(
keyString: "standard_list_item_address_label_key",
title: S.current.address_label,
@@ -168,8 +162,6 @@ class TxDetailRowDefinition {
vm.transactionInfo.additionalInfo['accountIndex'] as int,
vm.transactionInfo.additionalInfo['addressIndex'] as int),
applicable: (vm) => vm.wallet.type == WalletType.monero),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_key",
title: S.current.transaction_key,
@@ -185,7 +177,6 @@ class TxDetailRowDefinition {
"";
},
applicable: (vm) => vm.wallet.type == WalletType.monero),
TxDetailRowDefinition(
keyString: "standard_list_item_lightning_preimage",
title: S.current.transaction_preimage,
@@ -193,14 +184,11 @@ class TxDetailRowDefinition {
applicable: (vm) =>
hasLightningPreimage(vm.transactionInfo) && isLightning(vm.transactionInfo),
),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_confirmed_key",
title: S.current.confirmed_tx,
valueGetter: (vm) => (vm.transactionInfo.confirmations > 0).toString(),
applicable: (vm) => vm.wallet.type == WalletType.nano),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_memo_key",
title: S.current.memo,
@@ -208,23 +196,17 @@ class TxDetailRowDefinition {
applicable: (vm) =>
vm.wallet.type == WalletType.zcash &&
vm.transactionInfo.additionalInfo["memo"] != null),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_asset_id_key",
title: "Asset ID",
valueGetter: (vm) =>
vm.transactionInfo.additionalInfo["assetId"] as String? ?? "Unknown asset id",
applicable: (vm) => vm.wallet.type == WalletType.zano),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_comment_key",
title: S.current.transaction_details_title,
valueGetter: (vm) => vm.transactionInfo.additionalInfo['comment'] as String? ?? "",
applicable: (vm) => vm.wallet.type == WalletType.zano),
TxDetailRowDefinition(
keyString: "standard_list_item_transaction_details_id_key",
title: S.current.transaction_details_transaction_id,
@@ -272,7 +254,8 @@ abstract class TransactionDetailsViewModelBase with Store {
final recipientAddress = description.recipientAddress;
if (recipientAddress?.isNotEmpty ?? false) {
final recipientAddressForDisplay = _moneroRecipientAddressForDisplay(recipientAddress!, wallet.type);
final recipientAddressForDisplay =
_moneroRecipientAddressForDisplay(recipientAddress!, wallet.type);
items.add(
AddressListItem(
title: S.current.transaction_details_recipient_address,
@@ -287,7 +270,7 @@ abstract class TransactionDetailsViewModelBase with Store {
void updateNote(String note) {
final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
final description = transactionDescriptionBox.values.firstWhere(
(val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
(val) => val.id == descriptionKey || val.id == transactionInfo.txHash,
orElse: () => TransactionDescription(id: descriptionKey));
description.transactionNote = note;
@@ -301,9 +284,9 @@ abstract class TransactionDetailsViewModelBase with Store {
String get note {
final descriptionKey = '${transactionInfo.txHash}_${wallet.walletAddresses.primaryAddress}';
final description = transactionDescriptionBox.values.firstWhereOrNull(
(val) => val.id == descriptionKey || val.id == transactionInfo.txHash);
return description?.transactionNote??"";
final description = transactionDescriptionBox.values
.firstWhereOrNull((val) => val.id == descriptionKey || val.id == transactionInfo.txHash);
return description?.transactionNote ?? "";
}
final TransactionInfo transactionInfo;
@@ -400,16 +383,13 @@ abstract class TransactionDetailsViewModelBase with Store {
case WalletType.litecoin:
bool isPegOut = (transactionInfo.additionalInfo["isPegOut"] as bool?) ?? false;
bool fromPegOut = (transactionInfo.additionalInfo["fromPegOut"] as bool?) ?? false;
if(isPegOut || fromPegOut)
return 6;
if (isPegOut || fromPegOut) return 6;
default:
return 0;
}
return 0;
}
String get formattedTitle {
if (transactionInfo.additionalInfo['autoShield'] == true) {
return "Autoshield";
@@ -425,7 +405,6 @@ abstract class TransactionDetailsViewModelBase with Store {
bool canReplaceByFee;
String get _explorerUrl {
final txId = transactionInfo.txHash;
if (wallet.chainId != null) {
final explorerUrl = evm!.getExplorerUrlForChainId(wallet.chainId!);
@@ -569,9 +548,6 @@ abstract class TransactionDetailsViewModelBase with Store {
}
}
@action
Future<void> _checkForRBF(TransactionInfo tx) async {
if (wallet.type == WalletType.bitcoin &&
@@ -634,6 +610,4 @@ abstract class TransactionDetailsViewModelBase with Store {
String get pendingTransactionFeeFiatAmountFormatted => sendViewModel.isFiatDisabled
? ''
: sendViewModel.pendingTransactionFeeFiatAmount + ' ' + sendViewModel.fiat.title;
}
@@ -46,7 +46,8 @@ abstract class UnspentCoinsDetailsViewModelBase with Store {
})
];
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(_type)) {
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin]
.contains(_type)) {
items.add(BlockExplorerListItem(
title: S.current.view_in_block_explorer,
value: _explorerDescription(_type),
@@ -6,20 +6,19 @@ part 'unspent_coins_item.g.dart';
class UnspentCoinsItem = UnspentCoinsItemBase with _$UnspentCoinsItem;
abstract class UnspentCoinsItemBase with Store, UnspentComparable {
UnspentCoinsItemBase({
required this.address,
required this.amount,
required this.hash,
required this.isFrozen,
required this.note,
required this.isSending,
required this.isChange,
required this.value,
required this.vout,
required this.keyImage,
required this.isSilentPayment,
this.isBeingSaved = false
});
UnspentCoinsItemBase(
{required this.address,
required this.amount,
required this.hash,
required this.isFrozen,
required this.note,
required this.isSending,
required this.isChange,
required this.value,
required this.vout,
required this.keyImage,
required this.isSilentPayment,
this.isBeingSaved = false});
@observable
String address;
@@ -54,7 +53,6 @@ abstract class UnspentCoinsItemBase with Store, UnspentComparable {
@observable
bool isSilentPayment;
@observable
bool isBeingSaved;
}
@@ -50,10 +50,10 @@ abstract class UnspentCoinsListViewModelBase with Store {
ObservableList<UnspentCoinsItem> items;
@computed
List<UnspentCoinsItem> get nonFrozenItems => items.where((e)=>!e.isFrozen).toList();
List<UnspentCoinsItem> get nonFrozenItems => items.where((e) => !e.isFrozen).toList();
@computed
List<UnspentCoinsItem> get frozenItems => items.where((e)=>e.isFrozen).toList();
List<UnspentCoinsItem> get frozenItems => items.where((e) => e.isFrozen).toList();
final Map<String, Map<String, dynamic>> _originalState;
@@ -74,7 +74,6 @@ abstract class UnspentCoinsListViewModelBase with Store {
@computed
Map<String, String> get fiatAmounts {
final currency = wallet.currency;
final price = _fiatConversationStore.prices[currency];
if (price == null || price == 0.0 || isFiatDisabled) return {};
@@ -149,7 +148,8 @@ abstract class UnspentCoinsListViewModelBase with Store {
if (wallet.type == WalletType.wownero) {
await wownero!.updateUnspents(wallet);
}
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin].contains(wallet.type)) {
if ([WalletType.bitcoin, WalletType.litecoin, WalletType.bitcoinCash, WalletType.dogecoin]
.contains(wallet.type)) {
await bitcoin!.updateUnspents(wallet);
}
if (wallet.type == WalletType.decred) {
@@ -176,7 +176,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
}
}
List<Unspent> _getSpecificUnspents(UnspentCoinType overrideCoinTypeToSpendFrom) {
List<Unspent> _getSpecificUnspents(UnspentCoinType overrideCoinTypeToSpendFrom) {
switch (wallet.type) {
case WalletType.monero:
return monero!.getUnspents(wallet);
@@ -1,12 +1,13 @@
import 'package:cake_wallet/src/screens/transaction_details/transaction_details_list_item.dart';
class UnspentCoinsSwitchItem extends TransactionDetailsListItem {
UnspentCoinsSwitchItem({
required String title,
required String value,
required this.switchValue,
required this.onSwitchValueChange}) : super(title: title, value: value);
UnspentCoinsSwitchItem(
{required String title,
required String value,
required this.switchValue,
required this.onSwitchValueChange})
: super(title: title, value: value);
final bool Function() switchValue;
final void Function(bool value) onSwitchValueChange;
}
}
@@ -1,3 +1,3 @@
import 'package:cake_wallet/utils/list_item.dart';
class WalletAccountListHeader extends ListItem {}
class WalletAccountListHeader extends ListItem {}
@@ -1,3 +1,3 @@
import 'package:cake_wallet/utils/list_item.dart';
class WalletAddressHiddenListHeader extends ListItem {}
class WalletAddressHiddenListHeader extends ListItem {}
@@ -1,21 +1,21 @@
import 'package:cake_wallet/utils/list_item.dart';
class WalletAddressListItem extends ListItem {
WalletAddressListItem({
required this.address,
required this.isPrimary,
this.id,
this.name,
this.txCount,
this.balance,
this.isChange = false,
// Address that is only ever used once, shouldn't be used to receive funds, copy and paste, share etc
this.isOneTimeReceiveAddress = false,
this.isHidden = false,
this.isManual = false,
this.isLegacyDerivation = false,
this.derivationPath
}) : super();
WalletAddressListItem(
{required this.address,
required this.isPrimary,
this.id,
this.name,
this.txCount,
this.balance,
this.isChange = false,
// Address that is only ever used once, shouldn't be used to receive funds, copy and paste, share etc
this.isOneTimeReceiveAddress = false,
this.isHidden = false,
this.isManual = false,
this.isLegacyDerivation = false,
this.derivationPath})
: super();
final int? id;
final bool isPrimary;
@@ -73,8 +73,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
double? _fiatRate;
List<Currency> get currencies =>
[tokenCurrency ?? wallet.currency, ...FiatCurrency.all];
List<Currency> get currencies => [tokenCurrency ?? wallet.currency, ...FiatCurrency.all];
List<Currency> get tokenCurrencies => wallet.balance.keys.toList();
@@ -86,7 +85,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
_appStore.amountParsingProxy.getCryptoSymbol(tokenCurrency ?? wallet.currency);
void setTokenCurrency(Currency curr) {
if(curr == wallet.currency || curr == CryptoCurrency.btcln) {
if (curr == wallet.currency || curr == CryptoCurrency.btcln) {
tokenCurrency = null;
selectedCurrency = wallet.currency;
return;
@@ -144,7 +143,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
if (_amount.isEmpty) return "";
var cryptoCurrency = tokenCurrency ?? wallet.currency;
if (cryptoCurrency == CryptoCurrency.btcln) cryptoCurrency = CryptoCurrency.btc;
if(selectedCurrency is FiatCurrency && _fiatRate != null) {
if (selectedCurrency is FiatCurrency && _fiatRate != null) {
return selectedCurrencyFiatAmount;
}
@@ -168,7 +167,10 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
// payjoinEndpoint getter is broken, but uri works
bool get hasPayjoin =>
wallet.type == WalletType.bitcoin && !isLightning && !isSilentPayments && uri.toString().contains("payjo.in");
wallet.type == WalletType.bitcoin &&
!isLightning &&
!isSilentPayments &&
uri.toString().contains("payjo.in");
AmountParsingProxy get amountParsingProxy => _appStore.amountParsingProxy;
@@ -461,7 +463,8 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
String get walletTypeName => walletTypeToString(type);
@computed
bool get hasAddressList => [
bool get hasAddressList =>
[
WalletType.monero,
WalletType.wownero,
WalletType.haven,
@@ -471,7 +474,9 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
WalletType.decred,
WalletType.dogecoin,
WalletType.zcash
].contains(wallet.type) && !isLightning && isZCashTransparent;
].contains(wallet.type) &&
!isLightning &&
isZCashTransparent;
@computed
bool get hasAddressRotation => hasAddressList && wallet.type != WalletType.zcash;
@@ -576,11 +581,13 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
wallet.type == WalletType.bitcoin && bitcoin!.hasSelectedSilentPayments(wallet);
@computed
bool get isLightning => wallet.type == WalletType.bitcoin && (wallet.walletAddresses.getPaymentUri(_amount) is LightningPaymentRequest);
bool get isLightning =>
wallet.type == WalletType.bitcoin &&
(wallet.walletAddresses.getPaymentUri(_amount) is LightningPaymentRequest);
@computed
bool get isZCashTransparent {
if(wallet.type != WalletType.zcash) {
if (wallet.type != WalletType.zcash) {
return true;
}
receivePageOption;
@@ -619,7 +626,7 @@ abstract class WalletAddressListViewModelBase extends WalletChangeListenerViewMo
@action
Future<void> rotateAddress() async {
if(isRotatingAddress) {
if (isRotatingAddress) {
return;
}
try {
@@ -25,18 +25,14 @@ Future<void> createNewAddress(WalletBase wallet, String label) async {
await monero!
.getSubaddressList(wallet)
.addSubaddress(wallet, accountIndex: monero!.getCurrentAccount(wallet).id, label: label);
final subaddressList = await monero!
.getSubaddressList(wallet)
.subaddresses;
if(subaddressList.isEmpty) {
final subaddressList = await monero!.getSubaddressList(wallet).subaddresses;
if (subaddressList.isEmpty) {
// this shouldn't happen, we just added an addr.
// somehow, it happened once in prod regardless.
// we just return instead of crashing, user can press the button again ig
return;
}
final addr = subaddressList
.first
.address; // first because the order is reversed
final addr = subaddressList.first.address; // first because the order is reversed
wallet.walletAddresses.manualAddresses.add(addr);
await wallet.save();
}
+6 -7
View File
@@ -25,8 +25,7 @@ part 'wallet_creation_vm.g.dart';
class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
abstract class WalletCreationVMBase with Store {
WalletCreationVMBase(this._appStore, this.walletCreationService,
this.seedSettingsViewModel,
WalletCreationVMBase(this._appStore, this.walletCreationService, this.seedSettingsViewModel,
{required this.type, required this.isRecovery})
: state = InitialExecutionState(),
name = '';
@@ -81,7 +80,6 @@ abstract class WalletCreationVMBase with Store {
Future<void> _create({dynamic options}) async {
final type = this.type;
try {
state = IsExecutingState();
if (name.isEmpty) {
name = await generateName();
@@ -101,9 +99,9 @@ abstract class WalletCreationVMBase with Store {
final credentials = getCredentials(options);
final di = ((credentials.derivationInfo?.derivationPath??"") == "")
? getDefaultCreateDerivation()
: credentials.derivationInfo;
final di = ((credentials.derivationInfo?.derivationPath ?? "") == "")
? getDefaultCreateDerivation()
: credentials.derivationInfo;
final diId = await di!.save();
credentials.derivationInfo = di;
@@ -118,7 +116,8 @@ abstract class WalletCreationVMBase with Store {
path: path,
dirPath: dirPath,
address: '',
showIntroCakePayCard: (!await walletCreationService.typeExists(type)) && type != WalletType.haven,
showIntroCakePayCard:
(!await walletCreationService.typeExists(type)) && type != WalletType.haven,
derivationInfoId: diId,
hardwareWalletType: credentials.hardwareWalletType,
);
@@ -24,7 +24,7 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
this._walletManager,
this.walletListViewModel, {
required this.type,
}) : isFetchingMnemonic = false {
}) : isFetchingMnemonic = false {
reaction((_) => _appStore.wallet, (_) => unawaited(updateWalletInfoSourceList()));
unawaited(updateWalletInfoSourceList());
}
@@ -47,7 +47,6 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
@observable
WalletInfo? selectedSingleWallet;
@observable
bool isFetchingMnemonic;
@@ -116,8 +115,8 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
// Check for nano derivation type
final di = await wallet.getDerivationInfo();
bool isNanoDerivationType = wallet.type == WalletType.nano &&
di.derivationType == DerivationType.nano;
bool isNanoDerivationType =
wallet.type == WalletType.nano && di.derivationType == DerivationType.nano;
// Check for electrum derivation type
bool isElectrumDerivationType =
@@ -129,17 +128,17 @@ abstract class WalletGroupsDisplayViewModelBase with Store {
bool isNonSeedWallet = wallet.isNonSeedWallet;
bool isNotMoneroBip39Wallet = wallet.type == WalletType.monero &&
di.derivationType != DerivationType.bip39;
bool isNotMoneroBip39Wallet =
wallet.type == WalletType.monero && di.derivationType != DerivationType.bip39;
// Exclude if any of these conditions are true
shouldExcludeGroup = shouldExcludeGroup ||
isNonBIP39Wallet ||
isNanoDerivationType ||
isElectrumDerivationType ||
isSameTypeAsSelectedWallet ||
isNonSeedWallet ||
isNotMoneroBip39Wallet;
isNonBIP39Wallet ||
isNanoDerivationType ||
isElectrumDerivationType ||
isSameTypeAsSelectedWallet ||
isNonSeedWallet ||
isNotMoneroBip39Wallet;
}
if (shouldExcludeGroup) continue;
@@ -26,14 +26,10 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
int _nextIndex = 0;
WalletHardwareRestoreViewModelBase(
this.hardwareWalletVM,
AppStore appStore,
WalletCreationService walletCreationService,
SeedSettingsViewModel seedSettingsViewModel,
WalletHardwareRestoreViewModelBase(this.hardwareWalletVM, AppStore appStore,
WalletCreationService walletCreationService, SeedSettingsViewModel seedSettingsViewModel,
{required WalletType type})
: super(appStore, walletCreationService, seedSettingsViewModel,
type: type, isRecovery: true);
: super(appStore, walletCreationService, seedSettingsViewModel, type: type, isRecovery: true);
@observable
String name = "";
@@ -54,8 +50,7 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
Future<void> getNextAvailableAccounts(int limit) async {
try {
final service = await hardwareWalletVM.getHardwareWalletService(type);
final accounts = await service
.getAvailableAccounts(index: _nextIndex, limit: limit);
final accounts = await service.getAvailableAccounts(index: _nextIndex, limit: limit);
availableAccounts.addAll(accounts);
_nextIndex += limit;
@@ -74,8 +69,8 @@ abstract class WalletHardwareRestoreViewModelBase extends WalletCreationVM with
switch (type) {
case WalletType.bitcoin:
case WalletType.litecoin:
credentials =
bitcoin!.createBitcoinHardwareWalletCredentials(name: name, accountData: selectedAccount!);
credentials = bitcoin!
.createBitcoinHardwareWalletCredentials(name: name, accountData: selectedAccount!);
break;
case WalletType.ethereum:
case WalletType.polygon:
@@ -70,8 +70,7 @@ abstract class WalletListViewModelBase with Store {
WalletType get currentWalletType => _appStore.wallet!.type;
Future<bool> requireHardwareWalletConnection(WalletListItem walletItem) async =>
_walletLoadingService.requireHardwareWalletConnection(
walletItem.type, walletItem.name);
_walletLoadingService.requireHardwareWalletConnection(walletItem.type, walletItem.name);
@action
Future<void> loadWallet(WalletListItem walletItem) async {
@@ -89,8 +88,8 @@ abstract class WalletListViewModelBase with Store {
bool get ascending => _appStore.settingsStore.walletListAscending;
/// Serializes updateList() calls: each caller waits for the previous one to finish, then runs.
///
/// Serializes updateList() calls: each caller waits for the previous one to finish, then runs.
///
/// This basically ensures that all calls to updateList() are executed.
Future<void> _lastUpdate = Future.value();
+12 -14
View File
@@ -255,15 +255,14 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
case WalletType.monero:
return monero!.createMoneroRestoreWalletFromKeysCredentials(
name: name,
height: height,
spendKey: spendKey!,
viewKey: viewKey!,
address: address!,
password: password,
language: 'English',
hardwareWalletType: hardwareWalletType
);
name: name,
height: height,
spendKey: spendKey!,
viewKey: viewKey!,
address: address!,
password: password,
language: 'English',
hardwareWalletType: hardwareWalletType);
case WalletType.nano:
return nano!.createNanoRestoreWalletFromKeysCredentials(
@@ -312,11 +311,10 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
);
case WalletType.zcash:
return zcash!.createZcashRestoreWalletFromPrivateKey(
name: name,
privateKey: options['private_key'] as String,
password: password,
height: height
);
name: name,
privateKey: options['private_key'] as String,
password: password,
height: height);
default:
break;
}
@@ -21,7 +21,6 @@ abstract class WalletSeedViewModelBase with Store {
setupSeedVerification();
}
@observable
String name;