mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-19 05:58:50 +02:00
Flutter upgrade
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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,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);
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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) =>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()}');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user