Flutter upgrade

This commit is contained in:
M
2022-10-12 13:09:57 -04:00
parent c921ad890a
commit 1beb18b045
505 changed files with 6657 additions and 5875 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
import 'package:cake_wallet/core/execution_state.dart';
class AuthenticationBanned extends ExecutionState {
AuthenticationBanned({this.error});
AuthenticationBanned({required this.error});
final String error;
}
+5 -6
View File
@@ -14,10 +14,9 @@ class AuthViewModel = AuthViewModelBase with _$AuthViewModel;
abstract class AuthViewModelBase with Store {
AuthViewModelBase(this._authService, this._sharedPreferences,
this._settingsStore, this._biometricAuth) {
state = InitialExecutionState();
_failureCounter = 0;
}
this._settingsStore, this._biometricAuth)
: _failureCounter = 0,
state = InitialExecutionState();
static const maxFailedLogins = 3;
static const banTimeout = 180; // 3 minutes
@@ -40,7 +39,7 @@ abstract class AuthViewModelBase with Store {
final SettingsStore _settingsStore;
@action
Future<void> auth({String password}) async {
Future<void> auth({required String password}) async {
state = InitialExecutionState();
final _banDuration = banDuration();
@@ -74,7 +73,7 @@ abstract class AuthViewModelBase with Store {
}
}
Duration banDuration() {
Duration? banDuration() {
final unbanTimestamp = _sharedPreferences.getInt(banTimeoutKey);
if (unbanTimestamp == null) {
+6 -5
View File
@@ -12,7 +12,7 @@ import 'package:cake_wallet/wallet_type_utils.dart';
part 'backup_view_model.g.dart';
class BackupExportFile {
BackupExportFile(this.content, {@required this.name});
BackupExportFile(this.content, {required this.name});
final String name;
final List<int> content;
@@ -22,8 +22,9 @@ class BackupViewModel = BackupViewModelBase with _$BackupViewModel;
abstract class BackupViewModelBase with Store {
BackupViewModelBase(this.secureStorage, this.secretStore, this.backupService)
: isBackupPasswordVisible = false {
state = InitialExecutionState();
: isBackupPasswordVisible = false,
backupPassword = '',
state = InitialExecutionState() {
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
secretStore.values.observe((change) {
if (change.key == key) {
@@ -48,11 +49,11 @@ abstract class BackupViewModelBase with Store {
@action
Future<void> init() async {
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
backupPassword = await secureStorage.read(key: key);
backupPassword = (await secureStorage.read(key: key))!;
}
@action
Future<BackupExportFile> exportBackup() async {
Future<BackupExportFile?> exportBackup() async {
try {
state = IsExecutingState();
final backupContent = await backupService.exportBackup(backupPassword);
@@ -8,9 +8,8 @@ part 'buy_amount_view_model.g.dart';
class BuyAmountViewModel = BuyAmountViewModelBase with _$BuyAmountViewModel;
abstract class BuyAmountViewModelBase with Store {
BuyAmountViewModelBase() {
amount = '';
BuyAmountViewModelBase()
: amount = '' {
int selectedIndex = FiatCurrency.currenciesAvailableToBuyWith
.indexOf(getIt.get<SettingsStore>().fiatCurrency);
@@ -25,15 +24,15 @@ abstract class BuyAmountViewModelBase with Store {
String amount;
@observable
FiatCurrency fiatCurrency;
late FiatCurrency fiatCurrency;
@computed
double get doubleAmount {
double _amount;
try {
_amount = double.parse(amount.replaceAll(',', '.')) ?? 0.0;
} catch (e) {
_amount = double.parse(amount.replaceAll(',', '.'));
} catch (_) {
_amount = 0.0;
}
+2 -2
View File
@@ -4,7 +4,7 @@ import 'package:cake_wallet/entities/fiat_currency.dart';
import 'package:cake_wallet/view_model/buy/buy_amount_view_model.dart';
class BuyItem {
BuyItem({this.provider, this.buyAmountViewModel});
BuyItem({required this.provider, required this.buyAmountViewModel});
final BuyProvider provider;
final BuyAmountViewModel buyAmountViewModel;
@@ -18,7 +18,7 @@ class BuyItem {
try {
_buyAmount = await provider
.calculateAmount(amount?.toString(), fiatCurrency.title);
.calculateAmount(amount?.toString() ?? '', fiatCurrency.title);
} catch (e) {
_buyAmount = BuyAmount(sourceAmount: 0.0, destAmount: 0.0);
print(e.toString());
+8 -9
View File
@@ -20,13 +20,12 @@ class BuyViewModel = BuyViewModelBase with _$BuyViewModel;
abstract class BuyViewModelBase with Store {
BuyViewModelBase(this.ordersSource, this.ordersStore, this.settingsStore,
this.buyAmountViewModel, {@required this.wallet}) {
this.buyAmountViewModel, {required this.wallet})
: isRunning = false,
isDisabled = true,
isShowProviderButtons = false,
items = <BuyItem>[] {
_fetchBuyItems();
isRunning = false;
isDisabled = true;
isShowProviderButtons = false;
}
final Box<Order> ordersSource;
@@ -36,7 +35,7 @@ abstract class BuyViewModelBase with Store {
final WalletBase wallet;
@observable
BuyProvider selectedProvider;
BuyProvider? selectedProvider;
@observable
List<BuyItem> items;
@@ -64,7 +63,7 @@ abstract class BuyViewModelBase with Store {
try {
_url = await selectedProvider
?.requestUrl(doubleAmount?.toString(), fiatCurrency.title);
!.requestUrl(doubleAmount.toString(), fiatCurrency.title);
} catch (e) {
print(e.toString());
}
@@ -74,7 +73,7 @@ abstract class BuyViewModelBase with Store {
Future<void> saveOrder(String orderId) async {
try {
final order = await selectedProvider?.findOrderById(orderId);
final order = await selectedProvider!.findOrderById(orderId);
order.from = fiatCurrency.title;
order.to = cryptoCurrency.title;
await ordersSource.add(order);
@@ -41,7 +41,7 @@ abstract class ContactListViewModelBase with Store {
final Box<WalletInfo> walletInfoSource;
final ObservableList<ContactRecord> contacts;
final List<WalletContact> walletContacts;
StreamSubscription<BoxEvent> _subscription;
StreamSubscription<BoxEvent>? _subscription;
Future<void> delete(ContactRecord contact) async => contact.original.delete();
}
@@ -11,14 +11,13 @@ part 'contact_view_model.g.dart';
class ContactViewModel = ContactViewModelBase with _$ContactViewModel;
abstract class ContactViewModelBase with Store {
ContactViewModelBase(this._contacts, {ContactRecord contact})
ContactViewModelBase(this._contacts, {ContactRecord? contact})
: state = InitialExecutionState(),
currencies = CryptoCurrency.all,
_contact = contact {
name = _contact?.name;
address = _contact?.address;
currency = _contact?.type;
}
_contact = contact,
name = contact?.name ?? '',
address = contact?.address ?? '',
currency = contact?.type;
@observable
ExecutionState state;
@@ -30,17 +29,17 @@ abstract class ContactViewModelBase with Store {
String address;
@observable
CryptoCurrency currency;
CryptoCurrency? currency;
@computed
bool get isReady =>
(name?.isNotEmpty ?? false) &&
(currency?.toString()?.isNotEmpty ?? false) &&
(address?.isNotEmpty ?? false);
name.isNotEmpty &&
(currency?.toString().isNotEmpty ?? false) &&
address.isNotEmpty;
final List<CryptoCurrency> currencies;
final Box<Contact> _contacts;
final ContactRecord _contact;
final ContactRecord? _contact;
@action
void reset() {
@@ -54,13 +53,13 @@ abstract class ContactViewModelBase with Store {
state = IsExecutingState();
if (_contact != null) {
_contact.name = name;
_contact.address = address;
_contact.type = currency;
await _contact.save();
_contact?.name = name;
_contact?.address = address;
_contact?.type = currency!;
await _contact?.save();
} else {
await _contacts
.add(Contact(name: name, address: address, type: currency));
.add(Contact(name: name, address: address, type: currency!));
}
state = ExecutedSuccessfullyState();
@@ -18,7 +18,7 @@ int serializeActionlistDisplayModes(List<ActionListDisplayMode> modes) {
}
List<ActionListDisplayMode> deserializeActionlistDisplayModes(int raw) {
final modes = List<ActionListDisplayMode>();
final modes = <ActionListDisplayMode>[];
if (raw == 1 || raw - 10 == 1) {
modes.add(ActionListDisplayMode.trades);
@@ -16,12 +16,13 @@ import 'package:mobx/mobx.dart';
part 'balance_view_model.g.dart';
class BalanceRecord {
const BalanceRecord({this.availableBalance,
this.additionalBalance,
this.fiatAvailableBalance,
this.fiatAdditionalBalance,
this.asset,
this.formattedAssetTitle});
const BalanceRecord({
required this.availableBalance,
required this.additionalBalance,
required this.fiatAvailableBalance,
required this.fiatAdditionalBalance,
required this.asset,
required this.formattedAssetTitle});
final String fiatAdditionalBalance;
final String fiatAvailableBalance;
final String additionalBalance;
@@ -34,12 +35,12 @@ class BalanceViewModel = BalanceViewModelBase with _$BalanceViewModel;
abstract class BalanceViewModelBase with Store {
BalanceViewModelBase(
{@required this.appStore,
@required this.settingsStore,
@required this.fiatConvertationStore}) {
isReversing = false;
wallet ??= appStore.wallet;
isShowCard = wallet.walletInfo.isShowIntroCakePayCard;
{required this.appStore,
required this.settingsStore,
required this.fiatConvertationStore})
: isReversing = false,
isShowCard = appStore.wallet!.walletInfo.isShowIntroCakePayCard,
wallet = appStore.wallet! {
reaction((_) => appStore.wallet, _onWalletChange);
}
@@ -57,14 +58,22 @@ abstract class BalanceViewModelBase with Store {
wallet;
@computed
double get price => fiatConvertationStore.prices[appStore.wallet.currency];
double get price {
final price = fiatConvertationStore.prices[appStore.wallet!.currency];
if (price == null) {
throw Exception('No price for ${appStore.wallet!.currency} (current wallet)');
}
return price;
}
@computed
BalanceDisplayMode get savedDisplayMode => settingsStore.balanceDisplayMode;
@computed
String get asset {
final typeFormatted = walletTypeToString(appStore.wallet.type);
final typeFormatted = walletTypeToString(appStore.wallet!.type);
switch(wallet.type) {
case WalletType.haven:
@@ -110,7 +119,7 @@ abstract class BalanceViewModelBase with Store {
}
@computed
bool get hasMultiBalance => appStore.wallet.type == WalletType.haven;
bool get hasMultiBalance => appStore.wallet!.type == WalletType.haven;
@computed
String get availableBalance {
@@ -177,16 +186,22 @@ abstract class BalanceViewModelBase with Store {
formattedAssetTitle: _formatterAsset(key)));
}
final fiatCurrency = settingsStore.fiatCurrency;
final price = fiatConvertationStore.prices[key] ?? 0;
// if (price == null) {
// throw Exception('Price is null for: $key');
// }
final additionalFiatBalance = fiatCurrency.toString()
+ ' '
+ _getFiatBalance(
price: fiatConvertationStore.prices[key],
price: price,
cryptoAmount: value.formattedAdditionalBalance);
final availableFiatBalance = fiatCurrency.toString()
+ ' '
+ _getFiatBalance(
price: fiatConvertationStore.prices[key],
price: price,
cryptoAmount: value.formattedAvailableBalance);
return MapEntry(key, BalanceRecord(
@@ -231,23 +246,35 @@ abstract class BalanceViewModelBase with Store {
}
@computed
Balance get _walletBalance => wallet.balance[wallet.currency];
Balance get _walletBalance {
final balance = wallet.balance[wallet.currency];
if (balance == null) {
throw Exception('No balance for ${wallet.currency}');
}
return balance;
}
@computed
CryptoCurrency get currency => appStore.wallet.currency;
CryptoCurrency get currency => appStore.wallet!.currency;
@observable
bool isShowCard;
ReactionDisposer _onCurrentWalletChangeReaction;
ReactionDisposer? _onCurrentWalletChangeReaction;
@action
void _onWalletChange(
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
TransactionInfo>
TransactionInfo>?
wallet) {
this.wallet = wallet;
_onCurrentWalletChangeReaction?.reaction?.dispose();
if (wallet == null) {
return;
}
this.wallet = wallet;
_onCurrentWalletChangeReaction?.reaction.dispose();
isShowCard = wallet.walletInfo.isShowIntroCakePayCard;
}
@@ -259,7 +286,7 @@ abstract class BalanceViewModelBase with Store {
isShowCard = cardDisplayStatus;
}
String _getFiatBalance({double price, String cryptoAmount}) {
String _getFiatBalance({required double price, String? cryptoAmount}) {
if (cryptoAmount == null) {
return '0.00';
}
@@ -39,14 +39,24 @@ class DashboardViewModel = DashboardViewModelBase with _$DashboardViewModel;
abstract class DashboardViewModelBase with Store {
DashboardViewModelBase(
{this.balanceViewModel,
this.appStore,
this.tradesStore,
this.tradeFilterStore,
this.transactionFilterStore,
this.settingsStore,
this.yatStore,
this.ordersStore}) {
{required this.balanceViewModel,
required this.appStore,
required this.tradesStore,
required this.tradeFilterStore,
required this.transactionFilterStore,
required this.settingsStore,
required this.yatStore,
required this.ordersStore})
: isOutdatedElectrumWallet = false,
hasSellAction = false,
isEnabledSellAction = false,
hasBuyAction = false,
isEnabledBuyAction = false,
hasExchangeAction = false,
isEnabledExchangeAction = false,
isShowFirstYatIntroduction = false,
isShowSecondYatIntroduction = false,
isShowThirdYatIntroduction = false,
filterItems = {
S.current.transactions: [
FilterItem(
@@ -69,10 +79,13 @@ abstract class DashboardViewModelBase with Store {
onChanged: (value) => tradeFilterStore
.toggleDisplayExchange(ExchangeProviderDescription.changeNow)),
]
};
name = appStore.wallet?.name;
wallet ??= appStore.wallet;
},
subname = '',
name = appStore.wallet!.name,
type = appStore.wallet!.type,
transactions = ObservableList<TransactionListItem>(),
wallet = appStore.wallet! {
name = wallet.name;
type = wallet.type;
isOutdatedElectrumWallet =
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
@@ -84,17 +97,17 @@ abstract class DashboardViewModelBase with Store {
final _wallet = wallet;
if (_wallet.type == WalletType.monero) {
subname = monero.getCurrentAccount(_wallet)?.label;
subname = monero!.getCurrentAccount(_wallet).label;
_onMoneroAccountChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet)
_onMoneroAccountChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet)
.account, (Account account) => _onMoneroAccountChange(_wallet));
_onMoneroBalanceChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet).balance,
_onMoneroBalanceChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet).balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(_wallet));
final _accountTransactions = _wallet
.transactionHistory.transactions.values
.where((tx) => monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id)
.where((tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
.toList();
transactions = ObservableList.of(_accountTransactions.map((transaction) =>
@@ -114,19 +127,23 @@ abstract class DashboardViewModelBase with Store {
reaction((_) => appStore.wallet, _onWalletChange);
connectMapToListWithTransform(
appStore.wallet.transactionHistory.transactions,
appStore.wallet!.transactionHistory.transactions,
transactions,
(TransactionInfo val) => TransactionListItem(
transaction: val,
(TransactionInfo? transaction) => TransactionListItem(
transaction: transaction!,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore),
filter: (TransactionInfo tx) {
final wallet = _wallet;
if (wallet.type == WalletType.monero) {
return monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id;
}
filter: (TransactionInfo? transaction) {
if (transaction == null) {
return false;
}
return true;
final wallet = _wallet;
if (wallet.type == WalletType.monero) {
return monero!.getTransactionInfoAccountId(transaction) == monero!.getCurrentAccount(wallet).id;
}
return true;
});
}
@@ -250,9 +267,9 @@ abstract class DashboardViewModelBase with Store {
@observable
bool hasSellAction;
ReactionDisposer _onMoneroAccountChangeReaction;
ReactionDisposer? _onMoneroAccountChangeReaction;
ReactionDisposer _onMoneroBalanceChangeReaction;
ReactionDisposer? _onMoneroBalanceChangeReaction;
@observable
bool isOutdatedElectrumWallet;
@@ -265,8 +282,12 @@ abstract class DashboardViewModelBase with Store {
@action
void _onWalletChange(
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
TransactionInfo>
TransactionInfo>?
wallet) {
if (wallet == null) {
return;
}
this.wallet = wallet;
type = wallet.type;
name = wallet.name;
@@ -275,20 +296,22 @@ abstract class DashboardViewModelBase with Store {
updateActions();
if (wallet.type == WalletType.monero) {
subname = monero.getCurrentAccount(wallet)?.label;
subname = monero!.getCurrentAccount(wallet).label;
_onMoneroAccountChangeReaction?.reaction?.dispose();
_onMoneroBalanceChangeReaction?.reaction?.dispose();
_onMoneroAccountChangeReaction?.reaction.dispose();
_onMoneroBalanceChangeReaction?.reaction.dispose();
_onMoneroAccountChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet)
_onMoneroAccountChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet)
.account, (Account account) => _onMoneroAccountChange(wallet));
_onMoneroBalanceChangeReaction = reaction((_) => monero.getMoneroWalletDetails(wallet).balance,
_onMoneroBalanceChangeReaction = reaction((_) => monero!.getMoneroWalletDetails(wallet).balance,
(MoneroBalance balance) => _onMoneroTransactionsUpdate(wallet));
_onMoneroTransactionsUpdate(wallet);
} else {
subname = null;
// FIX-ME: Check for side effects
// subname = null;
subname = '';
transactions.clear();
@@ -300,24 +323,29 @@ abstract class DashboardViewModelBase with Store {
}
connectMapToListWithTransform(
appStore.wallet.transactionHistory.transactions,
appStore.wallet!.transactionHistory.transactions,
transactions,
(TransactionInfo val) => TransactionListItem(
transaction: val,
(TransactionInfo? transaction)
=> TransactionListItem(
transaction: transaction!,
balanceViewModel: balanceViewModel,
settingsStore: appStore.settingsStore),
filter: (TransactionInfo tx) {
if (wallet.type == WalletType.monero) {
return monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id;
}
filter: (TransactionInfo? tx) {
if (tx == null) {
return false;
}
return true;
if (wallet.type == WalletType.monero) {
return monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id;
}
return true;
});
}
@action
void _onMoneroAccountChange(WalletBase wallet) {
subname = monero.getCurrentAccount(wallet)?.label;
subname = monero!.getCurrentAccount(wallet).label;
_onMoneroTransactionsUpdate(wallet);
}
@@ -325,8 +353,8 @@ abstract class DashboardViewModelBase with Store {
void _onMoneroTransactionsUpdate(WalletBase wallet) {
transactions.clear();
final _accountTransactions = monero.getTransactionHistory(wallet).transactions.values
.where((tx) => monero.getTransactionInfoAccountId(tx) == monero.getCurrentAccount(wallet).id)
final _accountTransactions = monero!.getTransactionHistory(wallet).transactions.values
.where((tx) => monero!.getTransactionInfoAccountId(tx) == monero!.getCurrentAccount(wallet).id)
.toList();
transactions.addAll(_accountTransactions.map((transaction) =>
+4 -1
View File
@@ -1,5 +1,8 @@
class FilterItem {
FilterItem({this.value, this.caption, this.onChanged});
FilterItem({
required this.value,
required this.caption,
required this.onChanged});
bool Function() value;
String caption;
@@ -3,7 +3,7 @@ import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
List<ActionListItem> formattedItemsList(List<ActionListItem> items) {
final formattedList = <ActionListItem>[];
DateTime lastDate;
DateTime? lastDate;
items.sort((a, b) => b.date.compareTo(a.date));
for (var i = 0; i < items.length; i++) {
@@ -4,7 +4,9 @@ import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
class OrderListItem extends ActionListItem {
OrderListItem({this.order, this.settingsStore});
OrderListItem({
required this.order,
required this.settingsStore});
final Order order;
final SettingsStore settingsStore;
@@ -4,7 +4,9 @@ import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
import 'package:cake_wallet/entities/balance_display_mode.dart';
class TradeListItem extends ActionListItem {
TradeListItem({this.trade, this.settingsStore});
TradeListItem({
required this.trade,
required this.settingsStore});
final Trade trade;
final SettingsStore settingsStore;
@@ -20,5 +22,5 @@ class TradeListItem extends ActionListItem {
}
@override
DateTime get date => trade.createdAt;
DateTime get date => trade.createdAt!;
}
@@ -13,7 +13,9 @@ import 'package:cw_core/wallet_type.dart';
class TransactionListItem extends ActionListItem with Keyable {
TransactionListItem(
{this.transaction, this.balanceViewModel, this.settingsStore});
{required this.transaction,
required this.balanceViewModel,
required this.settingsStore});
final TransactionInfo transaction;
final BalanceViewModel balanceViewModel;
@@ -40,20 +42,20 @@ class TransactionListItem extends ActionListItem with Keyable {
switch(balanceViewModel.wallet.type) {
case WalletType.monero:
amount = calculateFiatAmountRaw(
cryptoAmount: monero.formatterMoneroAmountToDouble(amount: transaction.amount),
cryptoAmount: monero!.formatterMoneroAmountToDouble(amount: transaction.amount),
price: price);
break;
case WalletType.bitcoin:
case WalletType.litecoin:
amount = calculateFiatAmountRaw(
cryptoAmount: bitcoin.formatterBitcoinAmountToDouble(amount: transaction.amount),
cryptoAmount: bitcoin!.formatterBitcoinAmountToDouble(amount: transaction.amount),
price: price);
break;
case WalletType.haven:
final asset = haven.assetOfTransaction(transaction);
final price = balanceViewModel.fiatConvertationStore.prices[asset];
final asset = haven!.assetOfTransaction(transaction);
final price = balanceViewModel.fiatConvertationStore.prices[asset]!;
amount = calculateFiatAmountRaw(
cryptoAmount: haven.formatterMoneroAmountToDouble(amount: transaction.amount),
cryptoAmount: haven!.formatterMoneroAmountToDouble(amount: transaction.amount),
price: price);
break;
default:
+1 -1
View File
@@ -1,5 +1,5 @@
class WalletBalance {
WalletBalance({this.unlockedBalance, this.totalBalance});
WalletBalance({required this.unlockedBalance, required this.totalBalance});
String unlockedBalance;
String totalBalance;
@@ -9,10 +9,9 @@ class EditBackupPasswordViewModel = EditBackupPasswordViewModelBase
with _$EditBackupPasswordViewModel;
abstract class EditBackupPasswordViewModelBase with Store {
EditBackupPasswordViewModelBase(this.secureStorage, this.secretStore) {
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
backupPassword = secretStore.read(key);
}
EditBackupPasswordViewModelBase(this.secureStorage, this.secretStore)
: backupPassword = secretStore.read(generateStoreKeyFor(key: SecretStoreKey.backupPassword)),
_originalPassword = '';
final FlutterSecureStorage secureStorage;
final SecretStore secretStore;
@@ -30,7 +29,7 @@ abstract class EditBackupPasswordViewModelBase with Store {
@action
Future<void> init() async {
final key = generateStoreKeyFor(key: SecretStoreKey.backupPassword);
final password = await secureStorage.read(key: key);
final password = (await secureStorage.read(key: key))!;
_originalPassword = password;
backupPassword = password;
}
@@ -23,12 +23,14 @@ class ExchangeTradeViewModel = ExchangeTradeViewModelBase
abstract class ExchangeTradeViewModelBase with Store {
ExchangeTradeViewModelBase(
{this.wallet, this.trades, this.tradesStore, this.sendViewModel}) {
trade = tradesStore.trade;
isSendable = trade.from == wallet.currency ||
trade.provider == ExchangeProviderDescription.xmrto;
{required this.wallet,
required this.trades,
required this.tradesStore,
required this.sendViewModel})
: trade = tradesStore.trade!,
isSendable = tradesStore.trade!.from == wallet.currency ||
tradesStore.trade!.provider == ExchangeProviderDescription.xmrto,
items = ObservableList<ExchangeTradeItem>() {
switch (trade.provider) {
case ExchangeProviderDescription.xmrto:
_provider = XMRTOExchangeProvider();
@@ -47,12 +49,8 @@ abstract class ExchangeTradeViewModelBase with Store {
break;
}
items = ObservableList<ExchangeTradeItem>();
_updateItems();
_updateTrade();
timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateTrade());
}
@@ -77,9 +75,9 @@ abstract class ExchangeTradeViewModelBase with Store {
@observable
ObservableList<ExchangeTradeItem> items;
ExchangeProvider _provider;
ExchangeProvider? _provider;
Timer timer;
Timer? timer;
@action
Future confirmSending() async {
@@ -89,8 +87,7 @@ abstract class ExchangeTradeViewModelBase with Store {
sendViewModel.clearOutputs();
final output = sendViewModel.outputs.first;
output.address = trade.inputAddress;
output.address = trade.inputAddress ?? '';
output.setCryptoAmount(trade.amount);
await sendViewModel.createTransaction();
}
@@ -98,7 +95,7 @@ abstract class ExchangeTradeViewModelBase with Store {
@action
Future<void> _updateTrade() async {
try {
final updatedTrade = await _provider.findTradeById(id: trade.id);
final updatedTrade = await _provider!.findTradeById(id: trade.id);
if (updatedTrade.createdAt == null && trade.createdAt != null) {
updatedTrade.createdAt = trade.createdAt;
@@ -113,8 +110,7 @@ abstract class ExchangeTradeViewModelBase with Store {
}
void _updateItems() {
items?.clear();
items.clear();
items.add(ExchangeTradeItem(
title: "${trade.provider.title} ${S.current.id}", data: '${trade.id}', isCopied: true));
@@ -136,7 +132,7 @@ abstract class ExchangeTradeViewModelBase with Store {
title: S.current.status, data: '${trade.state}', isCopied: false),
ExchangeTradeItem(
title: S.current.widgets_address + ':',
data: trade.inputAddress,
data: trade.inputAddress ?? '',
isCopied: true),
]);
}
@@ -39,14 +39,32 @@ class ExchangeViewModel = ExchangeViewModelBase with _$ExchangeViewModel;
abstract class ExchangeViewModelBase with Store {
ExchangeViewModelBase(this.wallet, this.trades, this._exchangeTemplateStore,
this.tradesStore, this._settingsStore, this.sharedPreferences) {
this.tradesStore, this._settingsStore, this.sharedPreferences)
: _cryptoNumberFormat = NumberFormat(),
isReverse = false,
isFixedRateMode = false,
isReceiveAmountEntered = false,
depositAmount = '',
receiveAmount = '',
receiveAddress = '',
depositAddress = '',
isDepositAddressEnabled = false,
isReceiveAddressEnabled = false,
isReceiveAmountEditable = false,
receiveCurrencies = <CryptoCurrency>[],
depositCurrencies = <CryptoCurrency>[],
limits = Limits(min: 0, max: 0),
tradeState = ExchangeTradeStateInitial(),
limitsState = LimitsInitialState(),
receiveCurrency = wallet.currency,
depositCurrency = wallet.currency,
providerList = [ChangeNowExchangeProvider(), SideShiftExchangeProvider(), SimpleSwapExchangeProvider()],
selectedProviders = ObservableList<ExchangeProvider>(),
currentTradeAvailableProviders = SplayTreeMap<double, ExchangeProvider>() {
const excludeDepositCurrencies = [CryptoCurrency.btt, CryptoCurrency.nano];
const excludeReceiveCurrencies = [CryptoCurrency.xlm, CryptoCurrency.xrp,
CryptoCurrency.bnb, CryptoCurrency.btt, CryptoCurrency.nano];
providerList = [ChangeNowExchangeProvider(), SideShiftExchangeProvider(), SimpleSwapExchangeProvider()];
_initialPairBasedOnWallet();
currentTradeAvailableProviders = SplayTreeMap<double, ExchangeProvider>();
final Map<String, dynamic> exchangeProvidersSelection = json
.decode(sharedPreferences.getString(PreferencesKey.exchangeProvidersSelection) ?? "{}") as Map<String, dynamic>;
@@ -65,12 +83,10 @@ abstract class ExchangeViewModelBase with Store {
receiveAddress = '';
depositAddress = depositCurrency == wallet.currency
? wallet.walletAddresses.address : '';
limitsState = LimitsInitialState();
tradeState = ExchangeTradeStateInitial();
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = wallet.type == WalletType.bitcoin ? 8 : 12;
provider = providersForCurrentPair().first;
final initialProvider = provider;
provider.checkIsAvailable().then((bool isAvailable) {
provider!.checkIsAvailable().then((bool isAvailable) {
if (!isAvailable && provider == initialProvider) {
provider = providerList.firstWhere(
(provider) => provider is ChangeNowExchangeProvider,
@@ -84,9 +100,6 @@ abstract class ExchangeViewModelBase with Store {
depositCurrencies = CryptoCurrency.all
.where((cryptoCurrency) => !excludeDepositCurrencies.contains(cryptoCurrency))
.toList();
isReverse = false;
isFixedRateMode = false;
isReceiveAmountEntered = false;
_defineIsReceiveAmountEditable();
loadLimits();
reaction(
@@ -101,7 +114,7 @@ abstract class ExchangeViewModelBase with Store {
final SharedPreferences sharedPreferences;
@observable
ExchangeProvider provider;
ExchangeProvider? provider;
/// Maps in dart are not sorted by default
/// SplayTreeMap is a map sorted by keys
@@ -179,7 +192,7 @@ abstract class ExchangeViewModelBase with Store {
final SettingsStore _settingsStore;
@action
void changeDepositCurrency({CryptoCurrency currency}) {
void changeDepositCurrency({required CryptoCurrency currency}) {
depositCurrency = currency;
isFixedRateMode = false;
_onPairChange();
@@ -188,7 +201,7 @@ abstract class ExchangeViewModelBase with Store {
}
@action
void changeReceiveCurrency({CryptoCurrency currency}) {
void changeReceiveCurrency({required CryptoCurrency currency}) {
receiveCurrency = currency;
isFixedRateMode = false;
_onPairChange();
@@ -197,7 +210,7 @@ abstract class ExchangeViewModelBase with Store {
}
@action
void changeReceiveAmount({String amount}) {
void changeReceiveAmount({required String amount}) {
receiveAmount = amount;
isReverse = true;
@@ -254,7 +267,7 @@ abstract class ExchangeViewModelBase with Store {
}
@action
void changeDepositAmount({String amount}) {
void changeDepositAmount({required String amount}) {
depositAmount = amount;
isReverse = false;
@@ -344,7 +357,7 @@ abstract class ExchangeViewModelBase with Store {
/// set the limits with the maximum provider limit
/// if there is a provider with null max then it's the maximum limit
if ((tempLimits.max ?? double.maxFinite) > limits.max) {
if ((tempLimits.max ?? double.maxFinite) > limits.max!) {
limits = tempLimits;
}
}
@@ -357,9 +370,9 @@ abstract class ExchangeViewModelBase with Store {
}
@action
Future createTrade() async {
TradeRequest request;
String amount;
Future<void> createTrade() async {
TradeRequest? request;
String amount = '';
for (var provider in currentTradeAvailableProviders.values) {
if (!(await provider.checkIsAvailable())) {
@@ -370,7 +383,7 @@ abstract class ExchangeViewModelBase with Store {
request = SideShiftRequest(
depositMethod: depositCurrency,
settleMethod: receiveCurrency,
depositAmount: depositAmount?.replaceAll(',', '.'),
depositAmount: depositAmount?.replaceAll(',', '.') ?? '',
settleAddress: receiveAddress,
refundAddress: depositAddress,
);
@@ -381,7 +394,7 @@ abstract class ExchangeViewModelBase with Store {
request = SimpleSwapRequest(
from: depositCurrency,
to: receiveCurrency,
amount: depositAmount?.replaceAll(',', '.'),
amount: depositAmount?.replaceAll(',', '.') ?? '',
address: receiveAddress,
refundAddress: depositAddress,
);
@@ -392,8 +405,8 @@ abstract class ExchangeViewModelBase with Store {
request = XMRTOTradeRequest(
from: depositCurrency,
to: receiveCurrency,
amount: depositAmount?.replaceAll(',', '.'),
receiveAmount: receiveAmount?.replaceAll(',', '.'),
amount: depositAmount?.replaceAll(',', '.') ?? '',
receiveAmount: receiveAmount?.replaceAll(',', '.') ?? '',
address: receiveAddress,
refundAddress: depositAddress,
isBTCRequest: isReceiveAmountEntered);
@@ -404,8 +417,8 @@ abstract class ExchangeViewModelBase with Store {
request = ChangeNowRequest(
from: depositCurrency,
to: receiveCurrency,
fromAmount: depositAmount?.replaceAll(',', '.'),
toAmount: receiveAmount?.replaceAll(',', '.'),
fromAmount: depositAmount?.replaceAll(',', '.') ?? '',
toAmount: receiveAmount?.replaceAll(',', '.') ?? '',
refundAddress: depositAddress,
address: receiveAddress,
isReverse: isReverse);
@@ -416,7 +429,7 @@ abstract class ExchangeViewModelBase with Store {
request = MorphTokenRequest(
from: depositCurrency,
to: receiveCurrency,
amount: depositAmount?.replaceAll(',', '.'),
amount: depositAmount?.replaceAll(',', '.') ?? '',
refundAddress: depositAddress,
address: receiveAddress);
amount = depositAmount;
@@ -425,15 +438,15 @@ abstract class ExchangeViewModelBase with Store {
amount = amount.replaceAll(',', '.');
if (limitsState is LimitsLoadedSuccessfully && amount != null) {
if (double.parse(amount) < limits.min) {
if (double.parse(amount) < limits.min!) {
continue;
} else if (limits.max != null && double.parse(amount) > limits.max) {
} else if (limits.max != null && double.parse(amount) > limits.max!) {
continue;
} else {
try {
tradeState = TradeIsCreating();
final trade = await provider.createTrade(
request: request, isFixedRateMode: isFixedRateMode);
request: request!, isFixedRateMode: isFixedRateMode);
trade.walletId = wallet.id;
tradesStore.setTrade(trade);
await trades.add(trade);
@@ -472,8 +485,8 @@ abstract class ExchangeViewModelBase with Store {
@action
void calculateDepositAllAmount() {
if (wallet.type == WalletType.bitcoin) {
final availableBalance = wallet.balance[wallet.currency].available;
final priority = _settingsStore.priority[wallet.type];
final availableBalance = wallet.balance[wallet.currency]!.available;
final priority = _settingsStore.priority[wallet.type]!;
final fee = wallet.calculateEstimatedFee(priority, null);
if (availableBalance < fee || availableBalance == 0) {
@@ -481,19 +494,19 @@ abstract class ExchangeViewModelBase with Store {
}
final amount = availableBalance - fee;
changeDepositAmount(amount: bitcoin.formatterBitcoinAmountToString(amount: amount));
changeDepositAmount(amount: bitcoin!.formatterBitcoinAmountToString(amount: amount));
}
}
void updateTemplate() => _exchangeTemplateStore.update();
void addTemplate(
{String amount,
String depositCurrency,
String receiveCurrency,
String provider,
String depositAddress,
String receiveAddress}) =>
{required String amount,
required String depositCurrency,
required String receiveCurrency,
required String provider,
required String depositAddress,
required String receiveAddress}) =>
_exchangeTemplateStore.addTemplate(
amount: amount,
depositCurrency: depositCurrency,
@@ -502,7 +515,7 @@ abstract class ExchangeViewModelBase with Store {
depositAddress: depositAddress,
receiveAddress: receiveAddress);
void removeTemplate({ExchangeTemplate template}) =>
void removeTemplate({required ExchangeTemplate template}) =>
_exchangeTemplateStore.remove(template: template);
List<ExchangeProvider> providersForCurrentPair() {
@@ -510,7 +523,7 @@ abstract class ExchangeViewModelBase with Store {
}
List<ExchangeProvider> _providersForPair(
{CryptoCurrency from, CryptoCurrency to}) {
{required CryptoCurrency from, required CryptoCurrency to}) {
final providers = providerList
.where((provider) => provider.pairList
.where((pair) =>
@@ -8,9 +8,10 @@ part 'ionia_account_view_model.g.dart';
class IoniaAccountViewModel = IoniaAccountViewModelBase with _$IoniaAccountViewModel;
abstract class IoniaAccountViewModelBase with Store {
IoniaAccountViewModelBase({this.ioniaService}) {
email = '';
giftCards = [];
IoniaAccountViewModelBase({required this.ioniaService})
: email = '',
giftCards = [],
merchantState = InitialIoniaMerchantLoadingState() {
ioniaService.getUserEmail().then((email) => this.email = email);
updateUserGiftCards();
}
@@ -8,10 +8,12 @@ class IoniaAuthViewModel = IoniaAuthViewModelBase with _$IoniaAuthViewModel;
abstract class IoniaAuthViewModelBase with Store {
IoniaAuthViewModelBase({this.ioniaService}):
IoniaAuthViewModelBase({required this.ioniaService}):
createUserState = IoniaInitialCreateState(),
signInState = IoniaInitialCreateState(),
otpState = IoniaOtpSendDisabled();
otpState = IoniaOtpSendDisabled(),
email = '',
otp = '';
final IoniaService ioniaService;
@@ -6,10 +6,9 @@ part 'ionia_buy_card_view_model.g.dart';
class IoniaBuyCardViewModel = IoniaBuyCardViewModelBase with _$IoniaBuyCardViewModel;
abstract class IoniaBuyCardViewModelBase with Store {
IoniaBuyCardViewModelBase({this.ioniaMerchant}) {
isEnablePurchase = false;
amount = 0;
}
IoniaBuyCardViewModelBase({required this.ioniaMerchant})
: isEnablePurchase = false,
amount = 0;
final IoniaMerchant ioniaMerchant;
@@ -4,9 +4,8 @@ part 'ionia_custom_redeem_view_model.g.dart';
class IoniaCustomRedeemViewModel = IoniaCustomRedeemViewModelBase with _$IoniaCustomRedeemViewModel;
abstract class IoniaCustomRedeemViewModelBase with Store {
IoniaCustomRedeemViewModelBase(this.giftCard){
amount = 0;
}
IoniaCustomRedeemViewModelBase(this.giftCard)
: amount = 0;
final IoniaGiftCard giftCard;
@@ -7,10 +7,13 @@ part 'ionia_custom_tip_view_model.g.dart';
class IoniaCustomTipViewModel = IoniaCustomTipViewModelBase with _$IoniaCustomTipViewModel;
abstract class IoniaCustomTipViewModelBase with Store {
IoniaCustomTipViewModelBase({this.amount, this.tip, this.ioniaMerchant}){
customTip = tip;
percentage = 0;
}
IoniaCustomTipViewModelBase({
required this.amount,
required this.tip,
required this.ioniaMerchant})
: customTip = tip,
percentage = 0;
final IoniaMerchant ioniaMerchant;
final double amount;
final IoniaTip tip;
@@ -10,12 +10,15 @@ class IoniaGiftCardDetailsViewModel = IoniaGiftCardDetailsViewModelBase with _$
abstract class IoniaGiftCardDetailsViewModelBase with Store {
IoniaGiftCardDetailsViewModelBase({this.ioniaService, this.giftCard}) {
redeemState = InitialExecutionState();
remainingAmount = giftCard.remainingAmount;
}
IoniaGiftCardDetailsViewModelBase({
required this.ioniaService,
required this.giftCard})
: redeemState = InitialExecutionState(),
remainingAmount = giftCard.remainingAmount,
brightness = 0;
final IoniaService ioniaService;
double brightness;
@observable
@@ -2,8 +2,6 @@ import 'package:cake_wallet/ionia/ionia_category.dart';
import 'package:cake_wallet/ionia/ionia_service.dart';
import 'package:cake_wallet/ionia/ionia_create_state.dart';
import 'package:cake_wallet/ionia/ionia_merchant.dart';
import 'package:cake_wallet/ionia/ionia_virtual_card.dart';
import 'package:flutter/material.dart';
import 'package:mobx/mobx.dart';
part 'ionia_gift_cards_list_view_model.g.dart';
@@ -11,13 +9,18 @@ class IoniaGiftCardsListViewModel = IoniaGiftCardsListViewModelBase with _$Ionia
abstract class IoniaGiftCardsListViewModelBase with Store {
IoniaGiftCardsListViewModelBase({
@required this.ioniaService,
required this.ioniaService,
}) :
cardState = IoniaNoCardState(),
ioniaMerchants = [],
ioniaCategories = IoniaCategory.allCategories,
selectedIndices = ObservableList<IoniaCategory>.of([IoniaCategory.all]),
scrollOffsetFromTop = 0.0 {
scrollOffsetFromTop = 0.0,
isLoggedIn = false,
merchantState = InitialIoniaMerchantLoadingState(),
createCardState = IoniaCreateCardState(),
searchString = '',
ioniaMerchantList = <IoniaMerchant>[] {
_getAuthStatus().then((value) => isLoggedIn = value);
}
@@ -56,16 +59,14 @@ abstract class IoniaGiftCardsListViewModelBase with Store {
}
@action
Future<IoniaVirtualCard> createCard() async {
createCardState = IoniaCreateCardLoading();
Future<void> createCard() async {
try {
createCardState = IoniaCreateCardLoading();
final card = await ioniaService.createCard();
createCardState = IoniaCreateCardSuccess();
return card;
} on Exception catch (e) {
} catch (e) {
createCardState = IoniaCreateCardFailure(error: e.toString());
}
return null;
}
@action
@@ -12,17 +12,18 @@ class IoniaPaymentStatusViewModel = IoniaPaymentStatusViewModelBase with _$Ionia
abstract class IoniaPaymentStatusViewModelBase with Store {
IoniaPaymentStatusViewModelBase(
this.ioniaService,{
@required this.paymentInfo,
@required this.committedInfo}) {
_timer = Timer.periodic(updateTime, (timer) async {
await updatePaymentStatus();
this.ioniaService, {
required this.paymentInfo,
required this.committedInfo})
: error = '' {
_timer = Timer.periodic(updateTime, (timer) async {
await updatePaymentStatus();
if (giftCard != null) {
timer?.cancel();
}
});
}
if (giftCard != null) {
timer?.cancel();
}
});
}
static const updateTime = Duration(seconds: 3);
@@ -31,14 +32,14 @@ abstract class IoniaPaymentStatusViewModelBase with Store {
final AnyPayPaymentCommittedInfo committedInfo;
@observable
IoniaGiftCard giftCard;
IoniaGiftCard? giftCard;
@observable
String error;
Timer get timer => _timer;
Timer? get timer => _timer;
Timer _timer;
Timer? _timer;
@action
Future<void> updatePaymentStatus() async {
@@ -14,19 +14,20 @@ class IoniaMerchPurchaseViewModel = IoniaMerchPurchaseViewModelBase with _$Ionia
abstract class IoniaMerchPurchaseViewModelBase with Store {
IoniaMerchPurchaseViewModelBase({
@required this.ioniaAnyPayService,
@required this.amount,
@required this.ioniaMerchant,
}) {
tipAmount = 0.0;
percentage = 0.0;
tips = <IoniaTip>[
IoniaTip(percentage: 0, originalAmount: amount),
IoniaTip(percentage: 15, originalAmount: amount),
IoniaTip(percentage: 18, originalAmount: amount),
IoniaTip(percentage: 20, originalAmount: amount),
IoniaTip(percentage: 0, originalAmount: amount, isCustom: true),
];
required this.ioniaAnyPayService,
required this.amount,
required this.ioniaMerchant,
}) : tipAmount = 0.0,
percentage = 0.0,
invoiceCreationState = InitialExecutionState(),
invoiceCommittingState = InitialExecutionState(),
tips = <IoniaTip>[
IoniaTip(percentage: 0, originalAmount: amount),
IoniaTip(percentage: 15, originalAmount: amount),
IoniaTip(percentage: 18, originalAmount: amount),
IoniaTip(percentage: 20, originalAmount: amount),
IoniaTip(percentage: 0, originalAmount: amount, isCustom: true),
] {
selectedTip = tips.first;
}
@@ -35,17 +36,17 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
List<IoniaTip> tips;
@observable
IoniaTip selectedTip;
IoniaTip? selectedTip;
final IoniaMerchant ioniaMerchant;
final IoniaAnyPay ioniaAnyPayService;
IoniaAnyPayPaymentInfo paymentInfo;
IoniaAnyPayPaymentInfo? paymentInfo;
AnyPayPayment get invoice => paymentInfo?.anyPayPayment;
AnyPayPayment? get invoice => paymentInfo?.anyPayPayment;
AnyPayPaymentCommittedInfo committedInfo;
AnyPayPaymentCommittedInfo? committedInfo;
@observable
ExecutionState invoiceCreationState;
@@ -85,9 +86,13 @@ abstract class IoniaMerchPurchaseViewModelBase with Store {
@action
Future<void> commitPaymentInvoice() async {
try {
if (invoice == null) {
throw Exception('Invoice is created. Invoince is null');
}
invoiceCommittingState = IsExecutingState();
committedInfo = await ioniaAnyPayService.commitInvoice(invoice);
invoiceCommittingState = ExecutedSuccessfullyState(payload: committedInfo);
committedInfo = await ioniaAnyPayService.commitInvoice(invoice!);
invoiceCommittingState = ExecutedSuccessfullyState(payload: committedInfo!);
} catch (e) {
invoiceCommittingState = FailureState(e.toString());
}
@@ -2,7 +2,7 @@ import 'package:flutter/foundation.dart';
class AccountListItem {
AccountListItem(
{@required this.label, @required this.id, this.isSelected = false});
{required this.label, required this.id, this.isSelected = false});
final String label;
final int id;
@@ -14,7 +14,7 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas
abstract class MoneroAccountEditOrCreateViewModelBase with Store {
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._havenAccountList,
{@required WalletBase wallet, AccountListItem accountListItem})
{required WalletBase wallet, AccountListItem? accountListItem})
: state = InitialExecutionState(),
isEdit = accountListItem != null,
label = accountListItem?.label??'',
@@ -30,8 +30,8 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
String label;
final MoneroAccountList _moneroAccountList;
final HavenAccountList _havenAccountList;
final AccountListItem _accountListItem;
final HavenAccountList? _havenAccountList;
final AccountListItem? _accountListItem;
final WalletBase _wallet;
Future<void> save() async {
@@ -51,7 +51,7 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
if (_accountListItem != null) {
await _moneroAccountList.setLabelAccount(
_wallet,
accountIndex: _accountListItem.id,
accountIndex: _accountListItem!.id,
label: label);
} else {
await _moneroAccountList.addAccount(
@@ -75,12 +75,12 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
state = IsExecutingState();
if (_accountListItem != null) {
await _havenAccountList.setLabelAccount(
await _havenAccountList!.setLabelAccount(
_wallet,
accountIndex: _accountListItem.id,
accountIndex: _accountListItem!.id,
label: label);
} else {
await _havenAccountList.addAccount(
await _havenAccountList!.addAccount(
_wallet,
label: label);
}
@@ -25,37 +25,39 @@ abstract class MoneroAccountListViewModelBase with Store {
List<AccountListItem> get accounts {
if (_wallet.type == WalletType.haven) {
return haven
.getAccountList(_wallet)
!.getAccountList(_wallet)
.accounts.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
isSelected: acc.id == haven.getCurrentAccount(_wallet).id))
isSelected: acc.id == haven!.getCurrentAccount(_wallet).id))
.toList();
}
if (_wallet.type == WalletType.monero) {
return monero
.getAccountList(_wallet)
!.getAccountList(_wallet)
.accounts.map((acc) => AccountListItem(
label: acc.label,
id: acc.id,
isSelected: acc.id == monero.getCurrentAccount(_wallet).id))
isSelected: acc.id == monero!.getCurrentAccount(_wallet).id))
.toList();
}
throw Exception('Unexpected wallet type: ${_wallet.type}');
}
final WalletBase _wallet;
void select(AccountListItem item) {
if (_wallet.type == WalletType.monero) {
monero.setCurrentAccount(
monero!.setCurrentAccount(
_wallet,
item.id,
item.label);
}
if (_wallet.type == WalletType.haven) {
haven.setCurrentAccount(
haven!.setCurrentAccount(
_wallet,
item.id,
item.label);
@@ -14,7 +14,11 @@ abstract class NodeCreateOrEditViewModelBase with Store {
NodeCreateOrEditViewModelBase(this._nodeSource, this._wallet)
: state = InitialExecutionState(),
connectionState = InitialExecutionState(),
useSSL = false;
useSSL = false,
address = '',
port = '',
login = '',
password = '';
@observable
ExecutionState state;
@@ -39,7 +43,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
@computed
bool get isReady =>
(address?.isNotEmpty ?? false) && (port?.isNotEmpty ?? false);
address.isNotEmpty && port.isNotEmpty;
bool get hasAuthCredentials => _wallet.type == WalletType.monero ||
_wallet.type == WalletType.haven;
@@ -47,7 +51,7 @@ abstract class NodeCreateOrEditViewModelBase with Store {
String get uri {
var uri = address;
if (port != null && port.isNotEmpty) {
if (port.isNotEmpty) {
uri += ':' + port;
}
@@ -20,7 +20,15 @@ abstract class NodeListViewModelBase with Store {
}
@computed
Node get currentNode => settingsStore.nodes[wallet.type];
Node get currentNode {
final node = settingsStore.nodes[wallet.type];
if (node == null) {
throw Exception('No node for wallet type: ${wallet.type}');
}
return node;
}
final ObservableList<Node> nodes;
final SettingsStore settingsStore;
@@ -34,16 +42,16 @@ abstract class NodeListViewModelBase with Store {
switch (wallet.type) {
case WalletType.bitcoin:
node = getBitcoinDefaultElectrumServer(nodes: _nodeSource);
node = getBitcoinDefaultElectrumServer(nodes: _nodeSource)!;
break;
case WalletType.monero:
node = getMoneroDefaultNode(nodes: _nodeSource);
break;
case WalletType.litecoin:
node = getLitecoinDefaultElectrumServer(nodes: _nodeSource);
node = getLitecoinDefaultElectrumServer(nodes: _nodeSource)!;
break;
default:
break;
throw Exception('Unexpected wallet type: ${wallet.type}');
}
await setAsCurrent(node);
+9 -15
View File
@@ -18,9 +18,9 @@ class OrderDetailsViewModel = OrderDetailsViewModelBase
with _$OrderDetailsViewModel;
abstract class OrderDetailsViewModelBase with Store {
OrderDetailsViewModelBase({WalletBase wallet, Order orderForDetails}) {
order = orderForDetails;
OrderDetailsViewModelBase({required WalletBase wallet, required Order orderForDetails})
: items = ObservableList<StandartListItem>(),
order = orderForDetails {
if (order.provider != null) {
switch (order.provider) {
case BuyProviderDescription.wyre:
@@ -32,12 +32,8 @@ abstract class OrderDetailsViewModelBase with Store {
}
}
items = ObservableList<StandartListItem>();
_updateItems();
_updateOrder();
timer = Timer.periodic(Duration(seconds: 20), (_) async => _updateOrder());
}
@@ -47,15 +43,15 @@ abstract class OrderDetailsViewModelBase with Store {
@observable
ObservableList<StandartListItem> items;
BuyProvider _provider;
BuyProvider? _provider;
Timer timer;
Timer? timer;
@action
Future<void> _updateOrder() async {
try {
if (_provider != null) {
final updatedOrder = await _provider.findOrderById(order.id);
final updatedOrder = await _provider!.findOrderById(order.id);
updatedOrder.from = order.from;
updatedOrder.to = order.to;
updatedOrder.receiveAddress = order.receiveAddress;
@@ -73,9 +69,7 @@ abstract class OrderDetailsViewModelBase with Store {
void _updateItems() {
final dateFormat = DateFormatter.withCurrentLocal();
items?.clear();
items.clear();
items.addAll([
StandartListItem(
title: 'Transfer ID',
@@ -95,8 +89,8 @@ abstract class OrderDetailsViewModelBase with Store {
);
}
if (_provider?.trackUrl?.isNotEmpty ?? false) {
final buildURL = _provider.trackUrl + '${order.transferId}';
if (_provider!.trackUrl?.isNotEmpty ?? false) {
final buildURL = _provider!.trackUrl + '${order.transferId}';
items.add(
TrackTradeListItem(
title: 'Track',
+6 -6
View File
@@ -8,20 +8,20 @@ class RescanViewModel = RescanViewModelBase with _$RescanViewModel;
enum RescanWalletState { rescaning, none }
abstract class RescanViewModelBase with Store {
RescanViewModelBase(this._wallet) {
state = RescanWalletState.none;
isButtonEnabled = false;
}
RescanViewModelBase(this._wallet)
: state = RescanWalletState.none,
isButtonEnabled = false;
final WalletBase _wallet;
@observable
RescanWalletState state;
final WalletBase _wallet;
@observable
bool isButtonEnabled;
@action
Future<void> rescanCurrentWallet({int restoreHeight}) async {
Future<void> rescanCurrentWallet({required int restoreHeight}) async {
state = RescanWalletState.rescaning;
await _wallet.rescan(height: restoreHeight);
state = RescanWalletState.none;
@@ -15,7 +15,11 @@ class RestoreFromBackupViewModel = RestoreFromBackupViewModelBase
with _$RestoreFromBackupViewModel;
abstract class RestoreFromBackupViewModelBase with Store {
RestoreFromBackupViewModelBase(this.backupService);
RestoreFromBackupViewModelBase(this.backupService)
: state = InitialExecutionState(),
filePath = '';
final BackupService backupService;
@observable
String filePath;
@@ -23,8 +27,6 @@ abstract class RestoreFromBackupViewModelBase with Store {
@observable
ExecutionState state;
final BackupService backupService;
@action
void reset() => filePath = '';
@@ -45,15 +47,16 @@ abstract class RestoreFromBackupViewModelBase with Store {
await main();
final store = getIt.get<AppStore>();
ReactionDisposer reaction;
await store.settingsStore.reload(nodeSource: getIt.get<Box<Node>>());
ReactionDisposer? reaction;
// FIX-ME: SettingsStore reload
// await store.settingsStore.reload(nodeSource: getIt.get<Box<Node>>());
reaction = autorun((_) {
final wallet = store.wallet;
if (wallet != null) {
store.authenticationStore.state = AuthenticationState.allowed;
reaction?.reaction?.dispose();
reaction?.reaction.dispose();
}
});
+20 -14
View File
@@ -25,10 +25,16 @@ class Output = OutputBase with _$Output;
abstract class OutputBase with Store {
OutputBase(this._wallet, this._settingsStore, this._fiatConversationStore, this.cryptoCurrencyHandler)
: _cryptoNumberFormat = NumberFormat(cryptoNumberPattern) {
reset();
: _cryptoNumberFormat = NumberFormat(cryptoNumberPattern),
key = UniqueKey(),
sendAll = false,
cryptoAmount = '',
fiatAmount = '',
address = '',
note = '',
extractedAddress = '',
parsedAddress = ParsedAddress(addresses: []) {
_setCryptoNumMaximumFractionDigits();
key = UniqueKey();
}
Key key;
@@ -69,18 +75,18 @@ abstract class OutputBase with Store {
int _amount = 0;
switch (walletType) {
case WalletType.monero:
_amount = monero.formatterMoneroParseAmount(amount: _cryptoAmount);
_amount = monero!.formatterMoneroParseAmount(amount: _cryptoAmount);
break;
case WalletType.bitcoin:
_amount =
bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
break;
case WalletType.litecoin:
_amount =
bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
bitcoin!.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
break;
case WalletType.haven:
_amount = haven.formatterMoneroParseAmount(amount: _cryptoAmount);
_amount = haven!.formatterMoneroParseAmount(amount: _cryptoAmount);
break;
default:
break;
@@ -101,19 +107,19 @@ abstract class OutputBase with Store {
double get estimatedFee {
try {
final fee = _wallet.calculateEstimatedFee(
_settingsStore.priority[_wallet.type], formattedCryptoAmount);
_settingsStore.priority[_wallet.type]!, formattedCryptoAmount);
if (_wallet.type == WalletType.bitcoin ||
_wallet.type == WalletType.litecoin) {
return bitcoin.formatterBitcoinAmountToDouble(amount: fee);
return bitcoin!.formatterBitcoinAmountToDouble(amount: fee);
}
if (_wallet.type == WalletType.monero) {
return monero.formatterMoneroAmountToDouble(amount: fee);
return monero!.formatterMoneroAmountToDouble(amount: fee);
}
if (_wallet.type == WalletType.haven) {
return haven.formatterMoneroAmountToDouble(amount: fee);
return haven!.formatterMoneroAmountToDouble(amount: fee);
}
} catch (e) {
print(e.toString());
@@ -126,7 +132,7 @@ abstract class OutputBase with Store {
String get estimatedFeeFiatAmount {
try {
final fiat = calculateFiatAmountRaw(
price: _fiatConversationStore.prices[cryptoCurrencyHandler()],
price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
cryptoAmount: estimatedFee);
return fiat;
} catch (_) {
@@ -179,7 +185,7 @@ abstract class OutputBase with Store {
void _updateFiatAmount() {
try {
final fiat = calculateFiatAmount(
price: _fiatConversationStore.prices[cryptoCurrencyHandler()],
price: _fiatConversationStore.prices[cryptoCurrencyHandler()]!,
cryptoAmount: cryptoAmount.replaceAll(',', '.'));
if (fiatAmount != fiat) {
fiatAmount = fiat;
@@ -193,7 +199,7 @@ abstract class OutputBase with Store {
void _updateCryptoAmount() {
try {
final crypto = double.parse(fiatAmount.replaceAll(',', '.')) /
_fiatConversationStore.prices[cryptoCurrencyHandler()];
_fiatConversationStore.prices[cryptoCurrencyHandler()]!;
final cryptoAmountTmp = _cryptoNumberFormat.format(crypto);
if (cryptoAmount != cryptoAmountTmp) {
@@ -19,8 +19,8 @@ class SendTemplateViewModel = SendTemplateViewModelBase
abstract class SendTemplateViewModelBase with Store {
SendTemplateViewModelBase(this._wallet, this._settingsStore,
this._sendTemplateStore, this._fiatConversationStore) {
this._sendTemplateStore, this._fiatConversationStore)
: output = Output(_wallet, _settingsStore, _fiatConversationStore, () => _wallet.currency) {
output = Output(_wallet, _settingsStore, _fiatConversationStore, () => currency);
}
@@ -65,13 +65,13 @@ abstract class SendTemplateViewModelBase with Store {
void updateTemplate() => _sendTemplateStore.update();
void addTemplate(
{String name,
bool isCurrencySelected,
String address,
String cryptoCurrency,
String fiatCurrency,
String amount,
String amountFiat}) {
{required String name,
required bool isCurrencySelected,
required String address,
required String cryptoCurrency,
required String fiatCurrency,
required String amount,
required String amountFiat}) {
_sendTemplateStore.addTemplate(
name: name,
isCurrencySelected: isCurrencySelected,
@@ -83,7 +83,7 @@ abstract class SendTemplateViewModelBase with Store {
updateTemplate();
}
void removeTemplate({Template template}) {
void removeTemplate({required Template template}) {
_sendTemplateStore.remove(template: template);
updateTemplate();
}
+53 -24
View File
@@ -39,18 +39,18 @@ abstract class SendViewModelBase with Store {
this._fiatConversationStore,
this.balanceViewModel,
this.transactionDescriptionBox)
: state = InitialExecutionState() {
: state = InitialExecutionState(),
currencies = _wallet.balance.keys.toList(),
selectedCryptoCurrency = _wallet.currency,
outputs = ObservableList<Output>() {
final priority = _settingsStore.priority[_wallet.type];
final priorities = priorityForWalletType(_wallet.type);
selectedCryptoCurrency = _wallet.currency;
currencies = _wallet.balance.keys.toList();
if (!priorityForWalletType(_wallet.type).contains(priority)) {
_settingsStore.priority[_wallet.type] = priorities.first;
}
outputs = ObservableList<Output>()
..add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
}
@observable
@@ -84,8 +84,8 @@ abstract class SendViewModelBase with Store {
try {
if (pendingTransaction != null) {
final fiat = calculateFiatAmount(
price: _fiatConversationStore.prices[selectedCryptoCurrency],
cryptoAmount: pendingTransaction.amountFormatted);
price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
cryptoAmount: pendingTransaction!.amountFormatted);
return fiat;
} else {
return '0.00';
@@ -100,8 +100,8 @@ abstract class SendViewModelBase with Store {
try {
if (pendingTransaction != null) {
final fiat = calculateFiatAmount(
price: _fiatConversationStore.prices[selectedCryptoCurrency],
cryptoAmount: pendingTransaction.feeFormatted);
price: _fiatConversationStore.prices[selectedCryptoCurrency]!,
cryptoAmount: pendingTransaction!.feeFormatted);
return fiat;
} else {
return '0.00';
@@ -113,8 +113,15 @@ abstract class SendViewModelBase with Store {
FiatCurrency get fiat => _settingsStore.fiatCurrency;
TransactionPriority get transactionPriority =>
_settingsStore.priority[_wallet.type];
TransactionPriority get transactionPriority {
final priority = _settingsStore.priority[_wallet.type];
if (priority == null) {
throw Exception('Unexpected type ${_wallet.type}');
}
return priority;
}
CryptoCurrency get currency => _wallet.currency;
@@ -127,7 +134,7 @@ abstract class SendViewModelBase with Store {
Validator get textValidator => TextValidator();
@observable
PendingTransaction pendingTransaction;
PendingTransaction? pendingTransaction;
@computed
String get balance => balanceViewModel.availableBalance ?? '0.0';
@@ -179,6 +186,10 @@ abstract class SendViewModelBase with Store {
@action
Future<void> commitTransaction() async {
if (pendingTransaction == null) {
throw Exception("Pending transaction doesn't exist. It should not be happened.");
}
String address = outputs.fold('', (acc, value) {
return value.isParsedAddress
? acc + value.address + '\n' + value.extractedAddress + '\n\n'
@@ -195,16 +206,16 @@ abstract class SendViewModelBase with Store {
try {
state = TransactionCommitting();
await pendingTransaction.commit();
await pendingTransaction!.commit();
if (pendingTransaction.id?.isNotEmpty ?? false) {
if (pendingTransaction!.id?.isNotEmpty ?? false) {
_settingsStore.shouldSaveRecipientAddress
? await transactionDescriptionBox.add(TransactionDescription(
id: pendingTransaction.id,
id: pendingTransaction!.id,
recipientAddress: address,
transactionNote: note))
: await transactionDescriptionBox.add(TransactionDescription(
id: pendingTransaction.id, transactionNote: note));
id: pendingTransaction!.id, transactionNote: note));
}
state = TransactionCommitted();
@@ -222,23 +233,39 @@ abstract class SendViewModelBase with Store {
case WalletType.bitcoin:
final priority = _settingsStore.priority[_wallet.type];
return bitcoin.createBitcoinTransactionCredentials(outputs, priority: priority);
if (priority == null) {
throw Exception('Priority is null for wallet type: ${_wallet.type}');
}
return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
case WalletType.litecoin:
final priority = _settingsStore.priority[_wallet.type];
return bitcoin.createBitcoinTransactionCredentials(outputs, priority: priority);
if (priority == null) {
throw Exception('Priority is null for wallet type: ${_wallet.type}');
}
return bitcoin!.createBitcoinTransactionCredentials(outputs, priority: priority);
case WalletType.monero:
final priority = _settingsStore.priority[_wallet.type];
return monero.createMoneroTransactionCreationCredentials(
if (priority == null) {
throw Exception('Priority is null for wallet type: ${_wallet.type}');
}
return monero!.createMoneroTransactionCreationCredentials(
outputs: outputs, priority: priority);
case WalletType.haven:
final priority = _settingsStore.priority[_wallet.type];
return haven.createHavenTransactionCreationCredentials(
if (priority == null) {
throw Exception('Priority is null for wallet type: ${_wallet.type}');
}
return haven!.createHavenTransactionCreationCredentials(
outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
default:
return null;
throw Exception('Unexpected wallet type: ${_wallet.type}');
}
}
@@ -247,8 +274,10 @@ abstract class SendViewModelBase with Store {
final wallet = _wallet;
if (isElectrumWallet) {
final rate = bitcoin.getFeeRate(wallet, _priority);
return '${priority.labelWithRate(rate)}';
final rate = bitcoin!.getFeeRate(wallet, _priority);
// FIX-ME: labelWithRate
// return '${priority.labelWithRate(rate)}';
return '';
}
return priority.toString();
@@ -4,18 +4,18 @@ import 'package:flutter/material.dart';
class ChoicesListItem<ItemType> extends SettingsListItem {
ChoicesListItem(
{@required String title,
@required this.selectedItem,
@required this.items,
{required String title,
required this.selectedItem,
required this.items,
this.displayItem,
void Function(ItemType item) onItemSelected})
void Function(ItemType item)? onItemSelected})
: _onItemSelected = onItemSelected,
super(title);
final ItemType selectedItem;
final List<ItemType> items;
final String Function(ItemType item) displayItem;
final void Function(ItemType item) _onItemSelected;
final String Function(ItemType item)? displayItem;
final void Function(ItemType item)? _onItemSelected;
void onItemSelected(dynamic item) {
if (item is ItemType) {
+4 -4
View File
@@ -4,14 +4,14 @@ import 'package:flutter/material.dart';
class LinkListItem extends SettingsListItem {
LinkListItem(
{@required String title,
@required this.link,
@required this.linkTitle,
{required String title,
required this.link,
required this.linkTitle,
this.icon,
this.hasIconColor = false})
: super(title);
final String icon;
final String? icon;
final String link;
final String linkTitle;
final bool hasIconColor;
+12 -12
View File
@@ -2,29 +2,29 @@ import 'package:flutter/foundation.dart';
import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
import 'package:flutter/material.dart';
class PickerListItem<ItemType> extends SettingsListItem {
class PickerListItem<ItemType extends Object> extends SettingsListItem {
PickerListItem(
{@required String title,
@required this.selectedItem,
@required this.items,
{required String title,
required this.selectedItem,
required this.items,
this.displayItem,
this.images,
this.searchHintText,
this.isGridView = false,
void Function(ItemType item) onItemSelected,
bool Function(ItemType item, String searchText) matchingCriteria})
void Function(ItemType item)? onItemSelected,
bool Function(ItemType item, String searchText)? matchingCriteria})
: _onItemSelected = onItemSelected,
_matchingCriteria = matchingCriteria,
super(title);
final ItemType Function() selectedItem;
final List<ItemType> items;
final String Function(ItemType item) displayItem;
final void Function(ItemType item) _onItemSelected;
final List<Image> images;
final String searchHintText;
final String Function(ItemType item)? displayItem;
final void Function(ItemType item)? _onItemSelected;
final List<Image>? images;
final String? searchHintText;
final bool isGridView;
final bool Function(ItemType, String) _matchingCriteria;
final bool Function(ItemType, String)? _matchingCriteria;
void onItemSelected(dynamic item) {
if (item is ItemType) {
@@ -34,7 +34,7 @@ class PickerListItem<ItemType> extends SettingsListItem {
bool matchingCriteria(dynamic item, String searchText) {
if (item is ItemType) {
return _matchingCriteria?.call(item, searchText);
return _matchingCriteria?.call(item, searchText) ?? false;
}
return true;
}
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
class RegularListItem extends SettingsListItem {
RegularListItem({@required String title, this.handler}) : super(title);
RegularListItem({required String title, this.handler}) : super(title);
final void Function(BuildContext context) handler;
final void Function(BuildContext context)? handler;
}
@@ -39,13 +39,13 @@ class SettingsViewModel = SettingsViewModelBase with _$SettingsViewModel;
List<TransactionPriority> priorityForWalletType(WalletType type) {
switch (type) {
case WalletType.monero:
return monero.getTransactionPriorities();
return monero!.getTransactionPriorities();
case WalletType.bitcoin:
return bitcoin.getTransactionPriorities();
return bitcoin!.getTransactionPriorities();
case WalletType.litecoin:
return bitcoin.getLitecoinTransactionPriorities();
return bitcoin!.getLitecoinTransactionPriorities();
case WalletType.haven:
return haven.getTransactionPriorities();
return haven!.getTransactionPriorities();
default:
return [];
}
@@ -60,8 +60,9 @@ abstract class SettingsViewModelBase with Store {
wallet)
: itemHeaders = {},
_walletType = wallet.type,
_biometricAuth = BiometricAuth() {
currentVersion = '';
_biometricAuth = BiometricAuth(),
sections = <List<SettingsListItem>>[],
currentVersion = '' {
PackageInfo.fromPlatform().then(
(PackageInfo packageInfo) => currentVersion = packageInfo.version);
@@ -134,8 +135,10 @@ abstract class SettingsViewModelBase with Store {
if (wallet.type == WalletType.bitcoin
|| wallet.type == WalletType.litecoin) {
final rate = bitcoin.getFeeRate(wallet, _priority);
return '${priority.labelWithRate(rate)}';
final rate = bitcoin!.getFeeRate(wallet, _priority);
// FIX-ME: BitcoinTransactionPriority
// return '${priority.labelWithRate(rate)}';
return '';
}
return priority.toString();
@@ -169,7 +172,7 @@ abstract class SettingsViewModelBase with Store {
searchHintText: S.current.search_language,
items: LanguageService.list.keys.toList(),
displayItem: (dynamic code) {
return LanguageService.list[code];
return LanguageService.list[code] ?? '';
},
selectedItem: () => _settingsStore.languageCode,
onItemSelected: (String code) {
@@ -179,7 +182,7 @@ abstract class SettingsViewModelBase with Store {
(e) => Image.asset("assets/images/flags/${LanguageService.localeCountryCode[e]}.png"))
.toList(),
matchingCriteria: (String code, String searchText) {
return LanguageService.list[code].toLowerCase().contains(searchText);
return LanguageService.list[code]?.toLowerCase().contains(searchText) ?? false;
},
),
SwitcherListItem(
@@ -256,8 +259,15 @@ abstract class SettingsViewModelBase with Store {
_settingsStore.actionlistDisplayMode;
@computed
TransactionPriority get transactionPriority =>
_settingsStore.priority[_walletType];
TransactionPriority get transactionPriority {
final priority = _settingsStore.priority[_walletType];
if (priority == null) {
throw Exception('Unexpected type ${_walletType.toString()}');
}
return priority;
}
@computed
BalanceDisplayMode get balanceDisplayMode =>
@@ -4,9 +4,9 @@ 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})
{required String title,
required this.value,
required this.onValueChange})
: super(title);
final bool Function() value;
@@ -2,5 +2,5 @@ import 'package:flutter/foundation.dart';
import 'package:cake_wallet/view_model/settings/settings_list_item.dart';
class VersionListItem extends SettingsListItem {
VersionListItem({@required String title}) : super(title);
VersionListItem({required String title}) : super(title);
}
+17 -17
View File
@@ -14,8 +14,8 @@ part 'support_view_model.g.dart';
class SupportViewModel = SupportViewModelBase with _$SupportViewModel;
abstract class SupportViewModelBase with Store {
SupportViewModelBase() {
items = [
SupportViewModelBase()
: items = [
RegularListItem(
title: S.current.faq,
handler: (BuildContext context) async {
@@ -53,27 +53,27 @@ abstract class SupportViewModelBase with Store {
icon: 'assets/images/change_now.png',
linkTitle: 'support@changenow.io',
link: 'mailto:support@changenow.io'),
if (!isMoneroOnly) ... [
LinkListItem(
title: 'Wyre',
icon: 'assets/images/wyre.png',
linkTitle: S.current.submit_request,
link: 'https://wyre-support.zendesk.com/hc/en-us/requests/new'),
LinkListItem(
title: 'MoonPay',
icon: 'assets/images/moonpay.png',
hasIconColor: true,
linkTitle: S.current.submit_request,
link: 'https://support.moonpay.com/hc/en-gb/requests/new')
]
if (!isMoneroOnly) ... [
LinkListItem(
title: 'Wyre',
icon: 'assets/images/wyre.png',
linkTitle: S.current.submit_request,
link: 'https://wyre-support.zendesk.com/hc/en-us/requests/new'),
LinkListItem(
title: 'MoonPay',
icon: 'assets/images/moonpay.png',
hasIconColor: true,
linkTitle: S.current.submit_request,
link: 'https://support.moonpay.com/hc/en-gb/requests/new')
]
//LinkListItem(
// title: 'Yat',
// icon: 'assets/images/yat_mini_logo.png',
// hasIconColor: true,
// linkTitle: 'support@y.at',
// link: 'mailto:support@y.at')
];
}
];
static const url = 'https://cakewallet.com/guide/';
List<SettingsListItem> items;
+12 -9
View File
@@ -26,9 +26,12 @@ class TradeDetailsViewModel = TradeDetailsViewModelBase
with _$TradeDetailsViewModel;
abstract class TradeDetailsViewModelBase with Store {
TradeDetailsViewModelBase({Trade tradeForDetails, this.trades, this.settingsStore}) {
trade = tradeForDetails;
TradeDetailsViewModelBase({
required Trade tradeForDetails,
required this.trades,
required this.settingsStore})
: items = ObservableList<StandartListItem>(),
trade = tradeForDetails {
switch (trade.provider) {
case ExchangeProviderDescription.xmrto:
_provider = XMRTOExchangeProvider();
@@ -64,16 +67,16 @@ abstract class TradeDetailsViewModelBase with Store {
@observable
ObservableList<StandartListItem> items;
ExchangeProvider _provider;
ExchangeProvider? _provider;
Timer timer;
Timer? timer;
final SettingsStore settingsStore;
@action
Future<void> _updateTrade() async {
try {
final updatedTrade = await _provider.findTradeById(id: trade.id);
final updatedTrade = await _provider!.findTradeById(id: trade.id);
if (updatedTrade.createdAt == null && trade.createdAt != null) {
updatedTrade.createdAt = trade.createdAt;
@@ -90,7 +93,7 @@ abstract class TradeDetailsViewModelBase with Store {
void _updateItems() {
final dateFormat = DateFormatter.withCurrentLocal(reverse: true);
items?.clear();
items.clear();
items.add(
DetailsListStatusItem(
@@ -102,7 +105,7 @@ abstract class TradeDetailsViewModelBase with Store {
items.add(TradeDetailsListCardItem.tradeDetails(
id: trade.id,
createdAt: dateFormat.format(trade.createdAt),
createdAt: trade.createdAt != null ? dateFormat.format(trade.createdAt!) : '',
from: trade.from,
to: trade.to,
onTap: (BuildContext context) {
@@ -143,7 +146,7 @@ abstract class TradeDetailsViewModelBase with Store {
if (trade.createdAt != null) {
items.add(StandartListItem(
title: S.current.trade_details_created_at,
value: dateFormat.format(trade.createdAt).toString()));
value: trade.createdAt != null ? dateFormat.format(trade.createdAt!).toString() : ''));
}
if (trade.from != null && trade.to != null) {
@@ -23,21 +23,21 @@ class TransactionDetailsViewModel = TransactionDetailsViewModelBase
abstract class TransactionDetailsViewModelBase with Store {
TransactionDetailsViewModelBase(
{this.transactionInfo,
this.transactionDescriptionBox,
this.wallet,
this.settingsStore})
: items = [] {
showRecipientAddress = settingsStore?.shouldSaveRecipientAddress ?? false;
isRecipientAddressShown = false;
{required this.transactionInfo,
required this.transactionDescriptionBox,
required this.wallet,
required this.settingsStore})
: items = [],
isRecipientAddressShown = false,
showRecipientAddress = settingsStore.shouldSaveRecipientAddress {
final dateFormat = DateFormatter.withCurrentLocal();
final tx = transactionInfo;
if (wallet.type == WalletType.monero) {
final key = tx.additionalInfo['key'] as String;
final key = tx.additionalInfo['key'] as String?;
final accountIndex = tx.additionalInfo['accountIndex'] as int;
final addressIndex = tx.additionalInfo['addressIndex'] as int;
final feeFormatted = tx.feeFormatted();
final _items = [
StandartListItem(
title: S.current.transaction_details_transaction_id, value: tx.id),
@@ -49,18 +49,19 @@ abstract class TransactionDetailsViewModelBase with Store {
StandartListItem(
title: S.current.transaction_details_amount,
value: tx.amountFormatted()),
StandartListItem(
title: S.current.transaction_details_fee, value: tx.feeFormatted()),
if (feeFormatted != null)
StandartListItem(
title: S.current.transaction_details_fee, value: feeFormatted),
if (key?.isNotEmpty ?? false)
StandartListItem(title: S.current.transaction_key, value: key)
StandartListItem(title: S.current.transaction_key, value: key!)
];
if (tx.direction == TransactionDirection.incoming &&
accountIndex != null &&
addressIndex != null) {
try {
final address = monero.getTransactionAddress(wallet, accountIndex, addressIndex);
final label = monero.getSubaddressLabel(wallet, accountIndex, addressIndex);
final address = monero!.getTransactionAddress(wallet, accountIndex, addressIndex);
final label = monero!.getSubaddressLabel(wallet, accountIndex, addressIndex);
if (address?.isNotEmpty ?? false) {
isRecipientAddressShown = true;
@@ -95,16 +96,16 @@ abstract class TransactionDetailsViewModelBase with Store {
value: dateFormat.format(tx.date)),
StandartListItem(
title: S.current.confirmations,
value: tx.confirmations?.toString()),
value: tx.confirmations.toString()),
StandartListItem(
title: S.current.transaction_details_height, value: '${tx.height}'),
StandartListItem(
title: S.current.transaction_details_amount,
value: tx.amountFormatted()),
if (tx.feeFormatted()?.isNotEmpty)
if (tx.feeFormatted()?.isNotEmpty ?? false)
StandartListItem(
title: S.current.transaction_details_fee,
value: tx.feeFormatted()),
value: tx.feeFormatted()!),
];
items.addAll(_items);
@@ -122,20 +123,25 @@ abstract class TransactionDetailsViewModelBase with Store {
StandartListItem(
title: S.current.transaction_details_amount,
value: tx.amountFormatted()),
StandartListItem(
title: S.current.transaction_details_fee, value: tx.feeFormatted()),
if (tx.feeFormatted()?.isNotEmpty ?? false)
StandartListItem(
title: S.current.transaction_details_fee, value: tx.feeFormatted()!),
]);
}
if (showRecipientAddress && !isRecipientAddressShown) {
final recipientAddress = transactionDescriptionBox.values
.firstWhere((val) => val.id == transactionInfo.id, orElse: () => null)
?.recipientAddress;
try {
final recipientAddress = transactionDescriptionBox.values
.firstWhere((val) => val.id == transactionInfo.id)
.recipientAddress;
if (recipientAddress?.isNotEmpty ?? false) {
items.add(StandartListItem(
title: S.current.transaction_details_recipient_address,
value: recipientAddress));
if (recipientAddress?.isNotEmpty ?? false) {
items.add(StandartListItem(
title: S.current.transaction_details_recipient_address,
value: recipientAddress!));
}
} catch(_) {
// FIX-ME: Unhandled exception
}
}
@@ -14,21 +14,19 @@ class UnspentCoinsDetailsViewModel = UnspentCoinsDetailsViewModelBase
abstract class UnspentCoinsDetailsViewModelBase with Store {
UnspentCoinsDetailsViewModelBase({
this.unspentCoinsItem, this.unspentCoinsListViewModel}) {
final amount = unspentCoinsItem.amount ?? '';
final address = unspentCoinsItem.address ?? '';
isFrozen = unspentCoinsItem.isFrozen ?? false;
note = unspentCoinsItem.note ?? '';
required this.unspentCoinsItem,
required this.unspentCoinsListViewModel})
: items = <TransactionDetailsListItem>[],
isFrozen = unspentCoinsItem.isFrozen,
note = unspentCoinsItem.note {
items = [
StandartListItem(
title: S.current.transaction_details_amount,
value: amount
value: unspentCoinsItem.amount
),
StandartListItem(
title: S.current.widgets_address,
value: address
value: unspentCoinsItem.address
),
TextFieldListItem(
title: S.current.note_tap_to_change,
@@ -6,12 +6,12 @@ class UnspentCoinsItem = UnspentCoinsItemBase with _$UnspentCoinsItem;
abstract class UnspentCoinsItemBase with Store {
UnspentCoinsItemBase({
this.address,
this.amount,
this.hash,
this.isFrozen,
this.note,
this.isSending});
required this.address,
required this.amount,
required this.hash,
required this.isFrozen,
required this.note,
required this.isSending});
@observable
String address;
@@ -14,18 +14,18 @@ class UnspentCoinsListViewModel = UnspentCoinsListViewModelBase with _$UnspentCo
abstract class UnspentCoinsListViewModelBase with Store {
UnspentCoinsListViewModelBase({
@required this.wallet,
@required Box<UnspentCoinsInfo> unspentCoinsInfo}) {
_unspentCoinsInfo = unspentCoinsInfo;
bitcoin.updateUnspents(wallet);
required this.wallet,
required Box<UnspentCoinsInfo> unspentCoinsInfo})
: _unspentCoinsInfo = unspentCoinsInfo {
bitcoin!.updateUnspents(wallet);
}
WalletBase wallet;
Box<UnspentCoinsInfo> _unspentCoinsInfo;
@computed
ObservableList<UnspentCoinsItem> get items => ObservableList.of(bitcoin.getUnspents(wallet).map((elem) {
final amount = bitcoin.formatterBitcoinAmountToString(amount: elem.value) +
ObservableList<UnspentCoinsItem> get items => ObservableList.of(bitcoin!.getUnspents(wallet).map((elem) {
final amount = bitcoin!.formatterBitcoinAmountToString(amount: elem.value) +
' ${wallet.currency.title}';
final info = _unspentCoinsInfo.values
@@ -52,7 +52,7 @@ abstract class UnspentCoinsListViewModelBase with Store {
info.note = item.note;
await info.save();
bitcoin.updateUnspents(wallet);
bitcoin!.updateUnspents(wallet);
} catch (e) {
print(e.toString());
}
@@ -2,10 +2,10 @@ import 'package:cake_wallet/src/screens/transaction_details/transaction_details_
class UnspentCoinsSwitchItem extends TransactionDetailsListItem {
UnspentCoinsSwitchItem({
String title,
String value,
this.switchValue,
this.onSwitchValueChange}) : super(title: title, value: value);
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;
@@ -20,17 +20,17 @@ class AddressIsSaving extends AddressEditOrCreateState {}
class AddressSavedSuccessfully extends AddressEditOrCreateState {}
class AddressEditOrCreateStateFailure extends AddressEditOrCreateState {
AddressEditOrCreateStateFailure({this.error});
AddressEditOrCreateStateFailure({required this.error});
String error;
}
abstract class WalletAddressEditOrCreateViewModelBase with Store {
WalletAddressEditOrCreateViewModelBase(
{@required WalletBase wallet, dynamic item})
{required WalletBase wallet, dynamic item})
: isEdit = item != null,
state = AddressEditOrCreateStateInitial(),
label = item?.name as String,
label = item?.name as String? ?? '',
_item = item,
_wallet = wallet;
@@ -66,26 +66,26 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
if (wallet.type == WalletType.bitcoin
|| wallet.type == WalletType.litecoin) {
await bitcoin.generateNewAddress(wallet);
await bitcoin!.generateNewAddress(wallet);
await wallet.save();
}
if (wallet.type == WalletType.monero) {
await monero
.getSubaddressList(wallet)
!.getSubaddressList(wallet)
.addSubaddress(
wallet,
accountIndex: monero.getCurrentAccount(wallet).id,
accountIndex: monero!.getCurrentAccount(wallet).id,
label: label);
await wallet.save();
}
if (wallet.type == WalletType.haven) {
await haven
.getSubaddressList(wallet)
!.getSubaddressList(wallet)
.addSubaddress(
wallet,
accountIndex: haven.getCurrentAccount(wallet).id,
accountIndex: haven!.getCurrentAccount(wallet).id,
label: label);
await wallet.save();
}
@@ -101,10 +101,10 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
if (wallet.type == WalletType.monero) {
await monero
.getSubaddressList(wallet)
!.getSubaddressList(wallet)
.setLabelSubaddress(
wallet,
accountIndex: monero.getCurrentAccount(wallet).id,
accountIndex: monero!.getCurrentAccount(wallet).id,
addressIndex: _item.id as int,
label: label);
await wallet.save();
@@ -112,10 +112,10 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
if (wallet.type == WalletType.haven) {
await haven
.getSubaddressList(wallet)
!.getSubaddressList(wallet)
.setLabelSubaddress(
wallet,
accountIndex: haven.getCurrentAccount(wallet).id,
accountIndex: haven!.getCurrentAccount(wallet).id,
addressIndex: _item.id as int,
label: label);
await wallet.save();
@@ -2,13 +2,17 @@ import 'package:flutter/foundation.dart';
import 'package:cake_wallet/utils/list_item.dart';
class WalletAddressListItem extends ListItem {
const WalletAddressListItem({@required this.address, @required this.isPrimary,
this.name, this.id}) : super();
const WalletAddressListItem({
required this.address,
required this.isPrimary,
this.id,
this.name})
: super();
final int id;
final int? id;
final bool isPrimary;
final String address;
final String name;
final String? name;
@override
String toString() => name ?? address;
@@ -23,14 +23,18 @@ class WalletAddressListViewModel = WalletAddressListViewModelBase
with _$WalletAddressListViewModel;
abstract class PaymentURI {
PaymentURI({this.amount, this.address});
PaymentURI({
required this.amount,
required this.address});
final String amount;
final String address;
}
class MoneroURI extends PaymentURI {
MoneroURI({String amount, String address})
MoneroURI({
required String amount,
required String address})
: super(amount: amount, address: address);
@override
@@ -46,7 +50,9 @@ class MoneroURI extends PaymentURI {
}
class HavenURI extends PaymentURI {
HavenURI({String amount, String address})
HavenURI({
required String amount,
required String address})
: super(amount: amount, address: address);
@override
@@ -62,7 +68,9 @@ class HavenURI extends PaymentURI {
}
class BitcoinURI extends PaymentURI {
BitcoinURI({String amount, String address})
BitcoinURI({
required String amount,
required String address})
: super(amount: amount, address: address);
@override
@@ -78,7 +86,9 @@ class BitcoinURI extends PaymentURI {
}
class LitecoinURI extends PaymentURI {
LitecoinURI({String amount, String address})
LitecoinURI({
required String amount,
required String address})
: super(amount: amount, address: address);
@override
@@ -95,16 +105,19 @@ class LitecoinURI extends PaymentURI {
abstract class WalletAddressListViewModelBase with Store {
WalletAddressListViewModelBase({
@required AppStore appStore,
@required this.yatStore
}) {
_appStore = appStore;
_wallet = _appStore.wallet;
hasAccounts = _wallet?.type == WalletType.monero || _wallet?.type == WalletType.haven;
required AppStore appStore,
required this.yatStore
}) : _appStore = appStore,
_baseItems = <ListItem>[],
_wallet = appStore.wallet!,
hasAccounts = appStore.wallet!.type == WalletType.monero || appStore.wallet!.type == WalletType.haven,
amount = '' {
_onWalletChangeReaction = reaction((_) => _appStore.wallet, (WalletBase<
Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
wallet) {
if (wallet == null) {
return;
}
_wallet = wallet;
hasAccounts = _wallet.type == WalletType.monero;
});
@@ -119,7 +132,7 @@ abstract class WalletAddressListViewModelBase with Store {
@computed
WalletAddressListItem get address =>
WalletAddressListItem(address: _wallet.walletAddresses.address);
WalletAddressListItem(address: _wallet.walletAddresses.address, isPrimary: false);
@computed
PaymentURI get uri {
@@ -139,7 +152,7 @@ abstract class WalletAddressListViewModelBase with Store {
return LitecoinURI(amount: amount, address: address.address);
}
return null;
throw Exception('Unexpected type: ${type.toString()}');
}
@computed
@@ -152,9 +165,9 @@ abstract class WalletAddressListViewModelBase with Store {
final addressList = ObservableList<ListItem>();
if (wallet.type == WalletType.monero) {
final primaryAddress = monero.getSubaddressList(wallet).subaddresses.first;
final primaryAddress = monero!.getSubaddressList(wallet).subaddresses.first;
final addressItems = monero
.getSubaddressList(wallet)
!.getSubaddressList(wallet)
.subaddresses
.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
@@ -169,9 +182,9 @@ abstract class WalletAddressListViewModelBase with Store {
}
if (wallet.type == WalletType.haven) {
final primaryAddress = haven.getSubaddressList(wallet).subaddresses.first;
final primaryAddress = haven!.getSubaddressList(wallet).subaddresses.first;
final addressItems = haven
.getSubaddressList(wallet)
!.getSubaddressList(wallet)
.subaddresses
.map((subaddress) {
final isPrimary = subaddress == primaryAddress;
@@ -186,8 +199,8 @@ abstract class WalletAddressListViewModelBase with Store {
}
if (wallet.type == WalletType.bitcoin) {
final primaryAddress = bitcoin.getAddress(wallet);
final bitcoinAddresses = bitcoin.getAddresses(wallet).map((addr) {
final primaryAddress = bitcoin!.getAddress(wallet);
final bitcoinAddresses = bitcoin!.getAddresses(wallet).map((addr) {
final isPrimary = addr == primaryAddress;
return WalletAddressListItem(
@@ -207,14 +220,14 @@ abstract class WalletAddressListViewModelBase with Store {
final wallet = _wallet;
if (wallet.type == WalletType.monero) {
return monero.getCurrentAccount(wallet).label;
return monero!.getCurrentAccount(wallet).label;
}
if (wallet.type == WalletType.haven) {
return haven.getCurrentAccount(wallet).label;
return haven!.getCurrentAccount(wallet).label;
}
return null;
return '';
}
@computed
@@ -230,7 +243,7 @@ abstract class WalletAddressListViewModelBase with Store {
final YatStore yatStore;
ReactionDisposer _onWalletChangeReaction;
ReactionDisposer? _onWalletChangeReaction;
@action
void setAddress(WalletAddressListItem address) =>
+5 -5
View File
@@ -17,10 +17,9 @@ class WalletCreationVM = WalletCreationVMBase with _$WalletCreationVM;
abstract class WalletCreationVMBase with Store {
WalletCreationVMBase(this._appStore, this._walletInfoSource, this.walletCreationService,
{@required this.type, @required this.isRecovery}) {
state = InitialExecutionState();
name = '';
}
{required this.type, required this.isRecovery})
: state = InitialExecutionState(),
name = '';
@observable
String name;
@@ -43,7 +42,7 @@ abstract class WalletCreationVMBase with Store {
Future<void> create({dynamic options}) async {
try {
state = IsExecutingState();
if (name?.isEmpty ?? true) {
if (name.isEmpty) {
name = await generateName();
}
@@ -60,6 +59,7 @@ abstract class WalletCreationVMBase with Store {
date: DateTime.now(),
path: path,
dirPath: dirPath,
address: '',
showIntroCakePayCard: (!walletCreationService.typeExists(type)) && type != WalletType.haven);
credentials.walletInfo = walletInfo;
final wallet = await process(credentials);
+18 -10
View File
@@ -17,25 +17,33 @@ abstract class WalletKeysViewModelBase with Store {
: S.current.wallet_keys,
items = ObservableList<StandartListItem>() {
if (wallet.type == WalletType.monero) {
final keys = monero.getKeys(wallet);
final keys = monero!.getKeys(wallet);
items.addAll([
StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']),
StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']),
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']),
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']),
if (keys['publicSpendKey'] != null)
StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!),
if (keys['privateSpendKey'] != null)
StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']!),
if (keys['publicViewKey'] != null)
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
if (keys['privateViewKey'] != null)
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
StandartListItem(title: S.current.wallet_seed, value: wallet.seed),
]);
}
if (wallet.type == WalletType.haven) {
final keys = haven.getKeys(wallet);
final keys = haven!.getKeys(wallet);
items.addAll([
StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']),
StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']),
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']),
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']),
if (keys['publicSpendKey'] != null)
StandartListItem(title: S.current.spend_key_public, value: keys['publicSpendKey']!),
if (keys['privateSpendKey'] != null)
StandartListItem(title: S.current.spend_key_private, value: keys['privateSpendKey']!),
if (keys['publicViewKey'] != null)
StandartListItem(title: S.current.view_key_public, value: keys['publicViewKey']!),
if (keys['privateViewKey'] != null)
StandartListItem(title: S.current.view_key_private, value: keys['privateViewKey']!),
StandartListItem(title: S.current.wallet_seed, value: wallet.seed),
]);
}
@@ -3,9 +3,9 @@ import 'package:cw_core/wallet_type.dart';
class WalletListItem {
const WalletListItem(
{@required this.name,
@required this.type,
@required this.key,
{required this.name,
required this.type,
required this.key,
this.isCurrent = false,
this.isEnabled = true});
@@ -16,8 +16,8 @@ class WalletListViewModel = WalletListViewModelBase with _$WalletListViewModel;
abstract class WalletListViewModelBase with Store {
WalletListViewModelBase(this._walletInfoSource, this._appStore,
this._walletLoadingService) {
wallets = ObservableList<WalletListItem>();
this._walletLoadingService)
: wallets = ObservableList<WalletListItem>() {
_updateList();
}
@@ -28,7 +28,7 @@ abstract class WalletListViewModelBase with Store {
final Box<WalletInfo> _walletInfoSource;
final WalletLoadingService _walletLoadingService;
WalletType get currentWalletType => _appStore.wallet.type;
WalletType get currentWalletType => _appStore.wallet!.type;
@action
Future<void> loadWallet(WalletListItem walletItem) async {
@@ -51,8 +51,8 @@ abstract class WalletListViewModelBase with Store {
name: info.name,
type: info.type,
key: info.key,
isCurrent: info.name == _appStore.wallet.name &&
info.type == _appStore.wallet.type,
isCurrent: info.name == _appStore.wallet!.name &&
info.type == _appStore.wallet!.type,
isEnabled: availableWalletTypes.contains(info.type))));
}
}
+6 -6
View File
@@ -19,7 +19,7 @@ class WalletNewVM = WalletNewVMBase with _$WalletNewVM;
abstract class WalletNewVMBase extends WalletCreationVM with Store {
WalletNewVMBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource,
{@required WalletType type})
{required WalletType type})
: selectedMnemonicLanguage = '',
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: false);
@@ -32,17 +32,17 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
WalletCredentials getCredentials(dynamic options) {
switch (type) {
case WalletType.monero:
return monero.createMoneroNewWalletCredentials(
return monero!.createMoneroNewWalletCredentials(
name: name, language: options as String);
case WalletType.bitcoin:
return bitcoin.createBitcoinNewWalletCredentials(name: name);
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
case WalletType.litecoin:
return bitcoin.createBitcoinNewWalletCredentials(name: name);
return bitcoin!.createBitcoinNewWalletCredentials(name: name);
case WalletType.haven:
return haven.createHavenNewWalletCredentials(
return haven!.createHavenNewWalletCredentials(
name: name, language: options as String);
default:
return null;
throw Exception('Unexpected type: ${type.toString()}');;
}
}
@@ -21,8 +21,13 @@ abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
with Store {
WalletRestorationFromKeysVMBase(AppStore appStore,
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
{@required WalletType type, @required this.language})
: super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
{required WalletType type, required this.language})
: height = 0,
viewKey = '',
spendKey = '',
wif = '',
address = '',
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
@observable
int height;
@@ -49,7 +54,7 @@ abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
switch (type) {
case WalletType.monero:
return monero.createMoneroRestoreWalletFromKeysCredentials(
return monero!.createMoneroRestoreWalletFromKeysCredentials(
name: name,
password: password,
language: language,
@@ -58,10 +63,10 @@ abstract class WalletRestorationFromKeysVMBase extends WalletCreationVM
spendKey: spendKey,
height: height);
case WalletType.bitcoin:
return bitcoin.createBitcoinRestoreWalletFromWIFCredentials(
return bitcoin!.createBitcoinRestoreWalletFromWIFCredentials(
name: name, password: password, wif: wif);
default:
return null;
throw Exception('Unexpected type: ${type.toString()}');;
}
}
@@ -21,8 +21,9 @@ abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
with Store {
WalletRestorationFromSeedVMBase(AppStore appStore,
WalletCreationService walletCreationService, Box<WalletInfo> walletInfoSource,
{@required WalletType type, @required this.language, this.seed})
: super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
{required WalletType type, required this.language, this.seed = ''})
: height = 0,
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true);
@observable
String seed;
@@ -40,13 +41,13 @@ abstract class WalletRestorationFromSeedVMBase extends WalletCreationVM
switch (type) {
case WalletType.monero:
return monero.createMoneroRestoreWalletFromSeedCredentials(
return monero!.createMoneroRestoreWalletFromSeedCredentials(
name: name, height: height, mnemonic: seed, password: password);
case WalletType.bitcoin:
return bitcoin.createBitcoinRestoreWalletFromSeedCredentials(
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name, mnemonic: seed, password: password);
default:
return null;
throw Exception('Unexpected type: ${type.toString()}');
}
}
+13 -12
View File
@@ -24,16 +24,17 @@ class WalletRestoreViewModel = WalletRestoreViewModelBase
abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
WalletRestoreViewModelBase(AppStore appStore, WalletCreationService walletCreationService,
Box<WalletInfo> walletInfoSource,
{@required WalletType type})
{required WalletType type})
: availableModes = (type == WalletType.monero || type == WalletType.haven)
? WalletRestoreMode.values
: [WalletRestoreMode.seed],
hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
isButtonEnabled = false,
mode = WalletRestoreMode.seed,
super(appStore, walletInfoSource, walletCreationService, type: type, isRecovery: true) {
isButtonEnabled =
!hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
mode = WalletRestoreMode.seed;
walletCreationService.changeWalletType(type: type);
}
@@ -54,7 +55,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
@override
WalletCredentials getCredentials(dynamic options) {
final password = generateWalletPassword();
final height = options['height'] as int;
final height = options['height'] as int? ?? 0;
name = options['name'] as String;
if (mode == WalletRestoreMode.seed) {
@@ -62,25 +63,25 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
switch (type) {
case WalletType.monero:
return monero.createMoneroRestoreWalletFromSeedCredentials(
return monero!.createMoneroRestoreWalletFromSeedCredentials(
name: name,
height: height ?? 0,
height: height,
mnemonic: seed,
password: password);
case WalletType.bitcoin:
return bitcoin.createBitcoinRestoreWalletFromSeedCredentials(
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password);
case WalletType.litecoin:
return bitcoin.createBitcoinRestoreWalletFromSeedCredentials(
return bitcoin!.createBitcoinRestoreWalletFromSeedCredentials(
name: name,
mnemonic: seed,
password: password);
case WalletType.haven:
return haven.createHavenRestoreWalletFromSeedCredentials(
return haven!.createHavenRestoreWalletFromSeedCredentials(
name: name,
height: height ?? 0,
height: height,
mnemonic: seed,
password: password);
default:
@@ -94,7 +95,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
final address = options['address'] as String;
if (type == WalletType.monero) {
return monero.createMoneroRestoreWalletFromKeysCredentials(
return monero!.createMoneroRestoreWalletFromKeysCredentials(
name: name,
height: height,
spendKey: spendKey,
@@ -105,7 +106,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
}
if (type == WalletType.haven) {
return haven.createHavenRestoreWalletFromKeysCredentials(
return haven!.createHavenRestoreWalletFromKeysCredentials(
name: name,
height: height,
spendKey: spendKey,
@@ -116,7 +117,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
}
}
return null;
throw Exception('Unexpected type: ${type.toString()}');
}
@override