mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-18 05:51:34 +02:00
@@ -46,6 +46,22 @@ class AddressValidator extends TextValidator {
|
||||
return '[0-9a-zA-Z]';
|
||||
case CryptoCurrency.xrp:
|
||||
return '^[0-9a-zA-Z]{34}\$|^X[0-9a-zA-Z]{46}\$';
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xag:
|
||||
case CryptoCurrency.xau:
|
||||
case CryptoCurrency.xaud:
|
||||
case CryptoCurrency.xbtc:
|
||||
case CryptoCurrency.xcad:
|
||||
case CryptoCurrency.xchf:
|
||||
case CryptoCurrency.xcny:
|
||||
case CryptoCurrency.xeur:
|
||||
case CryptoCurrency.xgbp:
|
||||
case CryptoCurrency.xjpy:
|
||||
case CryptoCurrency.xnok:
|
||||
case CryptoCurrency.xnzd:
|
||||
case CryptoCurrency.xusd:
|
||||
return '[0-9a-zA-Z]';
|
||||
default:
|
||||
return '[0-9a-zA-Z]';
|
||||
}
|
||||
@@ -85,6 +101,22 @@ class AddressValidator extends TextValidator {
|
||||
return [56];
|
||||
case CryptoCurrency.xrp:
|
||||
return null;
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xag:
|
||||
case CryptoCurrency.xau:
|
||||
case CryptoCurrency.xaud:
|
||||
case CryptoCurrency.xbtc:
|
||||
case CryptoCurrency.xcad:
|
||||
case CryptoCurrency.xchf:
|
||||
case CryptoCurrency.xcny:
|
||||
case CryptoCurrency.xeur:
|
||||
case CryptoCurrency.xgbp:
|
||||
case CryptoCurrency.xjpy:
|
||||
case CryptoCurrency.xnok:
|
||||
case CryptoCurrency.xnzd:
|
||||
case CryptoCurrency.xusd:
|
||||
return [98, 99, 106];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
||||
@@ -31,6 +31,21 @@ class AmountConverter {
|
||||
return _ethereumAmountToDouble(amount);
|
||||
case CryptoCurrency.ltc:
|
||||
return _litecoinAmountToDouble(amount);
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xag:
|
||||
case CryptoCurrency.xau:
|
||||
case CryptoCurrency.xaud:
|
||||
case CryptoCurrency.xbtc:
|
||||
case CryptoCurrency.xcad:
|
||||
case CryptoCurrency.xchf:
|
||||
case CryptoCurrency.xcny:
|
||||
case CryptoCurrency.xeur:
|
||||
case CryptoCurrency.xgbp:
|
||||
case CryptoCurrency.xjpy:
|
||||
case CryptoCurrency.xnok:
|
||||
case CryptoCurrency.xnzd:
|
||||
case CryptoCurrency.xusd:
|
||||
return _moneroAmountToDouble(amount);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -40,6 +55,21 @@ class AmountConverter {
|
||||
switch (cryptoCurrency) {
|
||||
case CryptoCurrency.xmr:
|
||||
return _moneroParseAmount(amount);
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xag:
|
||||
case CryptoCurrency.xau:
|
||||
case CryptoCurrency.xaud:
|
||||
case CryptoCurrency.xbtc:
|
||||
case CryptoCurrency.xcad:
|
||||
case CryptoCurrency.xchf:
|
||||
case CryptoCurrency.xcny:
|
||||
case CryptoCurrency.xeur:
|
||||
case CryptoCurrency.xgbp:
|
||||
case CryptoCurrency.xjpy:
|
||||
case CryptoCurrency.xnok:
|
||||
case CryptoCurrency.xnzd:
|
||||
case CryptoCurrency.xusd:
|
||||
return _moneroParseAmount(amount);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -51,6 +81,21 @@ class AmountConverter {
|
||||
return _moneroAmountToString(amount);
|
||||
case CryptoCurrency.btc:
|
||||
return _bitcoinAmountToString(amount);
|
||||
case CryptoCurrency.xhv:
|
||||
case CryptoCurrency.xag:
|
||||
case CryptoCurrency.xau:
|
||||
case CryptoCurrency.xaud:
|
||||
case CryptoCurrency.xbtc:
|
||||
case CryptoCurrency.xcad:
|
||||
case CryptoCurrency.xchf:
|
||||
case CryptoCurrency.xcny:
|
||||
case CryptoCurrency.xeur:
|
||||
case CryptoCurrency.xgbp:
|
||||
case CryptoCurrency.xjpy:
|
||||
case CryptoCurrency.xnok:
|
||||
case CryptoCurrency.xnzd:
|
||||
case CryptoCurrency.xusd:
|
||||
return _moneroAmountToString(amount);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/core/validator.dart';
|
||||
import 'package:cake_wallet/entities/mnemonic_item.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
@@ -21,6 +22,8 @@ class SeedValidator extends Validator<MnemonicItem> {
|
||||
return getBitcoinWordList(language);
|
||||
case WalletType.monero:
|
||||
return monero.getMoneroWordList(language);
|
||||
case WalletType.haven:
|
||||
return haven.getMoneroWordList(language);
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
|
||||
+11
-3
@@ -2,6 +2,8 @@ import 'package:cake_wallet/core/yat_service.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/entities/wake_lock.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/balance_page.dart';
|
||||
import 'package:cw_core/unspent_coins_info.dart';
|
||||
@@ -122,6 +124,7 @@ import 'package:cake_wallet/store/templates/exchange_template_store.dart';
|
||||
import 'package:cake_wallet/entities/template.dart';
|
||||
import 'package:cake_wallet/exchange/exchange_template.dart';
|
||||
import 'package:cake_wallet/.secrets.g.dart' as secrets;
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
|
||||
|
||||
final getIt = GetIt.instance;
|
||||
|
||||
@@ -312,6 +315,9 @@ Future setup(
|
||||
getIt.registerFactory<DashboardPage>(() => DashboardPage( balancePage: getIt.get<BalancePage>(), walletViewModel: getIt.get<DashboardViewModel>(), addressListViewModel: getIt.get<WalletAddressListViewModel>()));
|
||||
getIt.registerFactory<ReceivePage>(() => ReceivePage(
|
||||
addressListViewModel: getIt.get<WalletAddressListViewModel>()));
|
||||
getIt.registerFactory<AddressPage>(() => AddressPage(
|
||||
addressListViewModel: getIt.get<WalletAddressListViewModel>(),
|
||||
walletViewModel: getIt.get<DashboardViewModel>()));
|
||||
|
||||
getIt.registerFactoryParam<WalletAddressEditOrCreateViewModel, dynamic, void>(
|
||||
(dynamic item, _) => WalletAddressEditOrCreateViewModel(
|
||||
@@ -344,8 +350,7 @@ Future setup(
|
||||
getIt.registerFactory(() => WalletListViewModel(
|
||||
_walletInfoSource,
|
||||
getIt.get<AppStore>(),
|
||||
getIt.get<KeyService>(),
|
||||
getIt.get<WalletNewVM>(param1: WalletType.monero)));
|
||||
getIt.get<KeyService>()));
|
||||
|
||||
getIt.registerFactory(() =>
|
||||
WalletListPage(walletListViewModel: getIt.get<WalletListViewModel>()));
|
||||
@@ -353,7 +358,7 @@ Future setup(
|
||||
getIt.registerFactory(() {
|
||||
final wallet = getIt.get<AppStore>().wallet;
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
if (wallet.type == WalletType.monero || wallet.type == WalletType.haven) {
|
||||
return MoneroAccountListViewModel(wallet);
|
||||
}
|
||||
|
||||
@@ -383,6 +388,7 @@ Future setup(
|
||||
AccountListItem, void>(
|
||||
(AccountListItem account, _) => MoneroAccountEditOrCreateViewModel(
|
||||
monero.getAccountList(getIt.get<AppStore>().wallet),
|
||||
haven.getAccountList(getIt.get<AppStore>().wallet),
|
||||
wallet: getIt.get<AppStore>().wallet,
|
||||
accountListItem: account));
|
||||
|
||||
@@ -469,6 +475,8 @@ Future setup(
|
||||
getIt.registerFactoryParam<WalletService, WalletType, void>(
|
||||
(WalletType param1, __) {
|
||||
switch (param1) {
|
||||
case WalletType.haven:
|
||||
return haven.createHavenWalletService(_walletInfoSource);
|
||||
case WalletType.monero:
|
||||
return monero.createMoneroWalletService(_walletInfoSource);
|
||||
case WalletType.bitcoin:
|
||||
|
||||
@@ -11,5 +11,16 @@ String calculateFiatAmount({double price, String cryptoAmount}) {
|
||||
return '0.00';
|
||||
}
|
||||
|
||||
return result > 0.01 ? result.toStringAsFixed(2) : '< 0.01';
|
||||
var formatted = '';
|
||||
final parts = result.toString().split('.');
|
||||
|
||||
if (parts.length >= 2) {
|
||||
if (parts[1].length > 2) {
|
||||
formatted = parts[0] + '.' + parts[1].substring(0, 2);
|
||||
} else {
|
||||
formatted = parts[0] + '.' + parts[1];
|
||||
}
|
||||
}
|
||||
|
||||
return result > 0.01 ? formatted : '< 0.01';
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import 'package:encrypt/encrypt.dart' as encrypt;
|
||||
const newCakeWalletMoneroUri = 'xmr-node.cakewallet.com:18081';
|
||||
const cakeWalletBitcoinElectrumUri = 'electrum.cakewallet.com:50002';
|
||||
const cakeWalletLitecoinElectrumUri = 'ltc-electrum.cakewallet.com:50002';
|
||||
const havenDefaultNodeUri = 'vault.havenprotocol.org:443';
|
||||
|
||||
Future defaultSettingsMigration(
|
||||
{@required int version,
|
||||
@@ -120,6 +121,13 @@ Future defaultSettingsMigration(
|
||||
await checkCurrentNodes(nodes, sharedPreferences);
|
||||
break;
|
||||
|
||||
case 16:
|
||||
await addHavenNodeList(nodes: nodes);
|
||||
await changeHavenCurrentNodeToDefault(
|
||||
sharedPreferences: sharedPreferences, nodes: nodes);
|
||||
await checkCurrentNodes(nodes, sharedPreferences);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -182,6 +190,14 @@ Node getLitecoinDefaultElectrumServer({@required Box<Node> nodes}) {
|
||||
orElse: () => null);
|
||||
}
|
||||
|
||||
Node getHavenDefaultNode({@required Box<Node> nodes}) {
|
||||
return nodes.values.firstWhere(
|
||||
(Node node) => node.uriRaw == havenDefaultNodeUri,
|
||||
orElse: () => null) ??
|
||||
nodes.values.firstWhere((node) => node.type == WalletType.haven,
|
||||
orElse: () => null);
|
||||
}
|
||||
|
||||
Node getMoneroDefaultNode({@required Box<Node> nodes}) {
|
||||
final timeZone = DateTime.now().timeZoneOffset.inHours;
|
||||
var nodeUri = '';
|
||||
@@ -217,6 +233,15 @@ Future<void> changeLitecoinCurrentElectrumServerToDefault(
|
||||
await sharedPreferences.setInt('current_node_id_ltc', serverId);
|
||||
}
|
||||
|
||||
Future<void> changeHavenCurrentNodeToDefault(
|
||||
{@required SharedPreferences sharedPreferences,
|
||||
@required Box<Node> nodes}) async {
|
||||
final node = getHavenDefaultNode(nodes: nodes);
|
||||
final nodeId = node?.key as int ?? 0;
|
||||
|
||||
await sharedPreferences.setInt(PreferencesKey.currentHavenNodeIdKey, nodeId);
|
||||
}
|
||||
|
||||
Future<void> replaceDefaultNode(
|
||||
{@required SharedPreferences sharedPreferences,
|
||||
@required Box<Node> nodes}) async {
|
||||
@@ -258,6 +283,11 @@ Future<void> addLitecoinElectrumServerList({@required Box<Node> nodes}) async {
|
||||
await nodes.addAll(serverList);
|
||||
}
|
||||
|
||||
Future<void> addHavenNodeList({@required Box<Node> nodes}) async {
|
||||
final nodeList = await loadDefaultHavenNodes();
|
||||
await nodes.addAll(nodeList);
|
||||
}
|
||||
|
||||
Future<void> addAddressesForMoneroWallets(
|
||||
Box<WalletInfo> walletInfoSource) async {
|
||||
final moneroWalletsInfo =
|
||||
@@ -347,6 +377,8 @@ Future<void> checkCurrentNodes(
|
||||
sharedPreferences.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
|
||||
final currentLitecoinElectrumSeverId = sharedPreferences
|
||||
.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
|
||||
final currentHavenNodeId = sharedPreferences
|
||||
.getInt(PreferencesKey.currentHavenNodeIdKey);
|
||||
final currentMoneroNode = nodeSource.values.firstWhere(
|
||||
(node) => node.key == currentMoneroNodeId,
|
||||
orElse: () => null);
|
||||
@@ -356,6 +388,9 @@ Future<void> checkCurrentNodes(
|
||||
final currentLitecoinElectrumServer = nodeSource.values.firstWhere(
|
||||
(node) => node.key == currentLitecoinElectrumSeverId,
|
||||
orElse: () => null);
|
||||
final currentHavenNodeServer = nodeSource.values.firstWhere(
|
||||
(node) => node.key == currentHavenNodeId,
|
||||
orElse: () => null);
|
||||
|
||||
if (currentMoneroNode == null) {
|
||||
final newCakeWalletNode =
|
||||
@@ -382,6 +417,14 @@ Future<void> checkCurrentNodes(
|
||||
PreferencesKey.currentLitecoinElectrumSererIdKey,
|
||||
cakeWalletElectrum.key as int);
|
||||
}
|
||||
|
||||
if (currentHavenNodeServer == null) {
|
||||
final nodes = await loadDefaultHavenNodes();
|
||||
final node = nodes.first;
|
||||
await nodeSource.add(node);
|
||||
await sharedPreferences.setInt(
|
||||
PreferencesKey.currentHavenNodeIdKey, node.key as int);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> resetBitcoinElectrumServer(
|
||||
|
||||
@@ -54,12 +54,32 @@ Future<List<Node>> loadLitecoinElectrumServerList() async {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future<List<Node>> loadDefaultHavenNodes() async {
|
||||
final nodesRaw = await rootBundle.loadString('assets/haven_node_list.yml');
|
||||
final nodes = loadYaml(nodesRaw) as YamlList;
|
||||
|
||||
return nodes.map((dynamic raw) {
|
||||
if (raw is Map) {
|
||||
final node = Node.fromMap(raw);
|
||||
node?.type = WalletType.haven;
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
return null;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
Future resetToDefault(Box<Node> nodeSource) async {
|
||||
final moneroNodes = await loadDefaultNodes();
|
||||
final bitcoinElectrumServerList = await loadBitcoinElectrumServerList();
|
||||
final litecoinElectrumServerList = await loadLitecoinElectrumServerList();
|
||||
final havenNodes = await loadDefaultHavenNodes();
|
||||
final nodes =
|
||||
moneroNodes + bitcoinElectrumServerList + litecoinElectrumServerList;
|
||||
moneroNodes +
|
||||
bitcoinElectrumServerList +
|
||||
litecoinElectrumServerList +
|
||||
havenNodes;
|
||||
|
||||
await nodeSource.clear();
|
||||
await nodeSource.addAll(nodes);
|
||||
|
||||
@@ -4,6 +4,7 @@ class PreferencesKey {
|
||||
static const currentNodeIdKey = 'current_node_id';
|
||||
static const currentBitcoinElectrumSererIdKey = 'current_node_id_btc';
|
||||
static const currentLitecoinElectrumSererIdKey = 'current_node_id_ltc';
|
||||
static const currentHavenNodeIdKey = 'current_node_id_xhv';
|
||||
static const currentFiatCurrencyKey = 'current_fiat_currency';
|
||||
static const currentTransactionPriorityKeyLegacy = 'current_fee_priority';
|
||||
static const currentBalanceDisplayModeKey = 'current_balance_display_mode';
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_haven/api/balance_list.dart';
|
||||
|
||||
Future<void> updateHavenRate(FiatConversionStore fiatConversionStore) async {
|
||||
final rate = getRate();
|
||||
final base = rate.firstWhere((row) => row.getAssetType() == 'XUSD', orElse: () => null);
|
||||
rate.forEach((row) {
|
||||
final cur = CryptoCurrency.fromString(row.getAssetType());
|
||||
final baseRate = moneroAmountToDouble(amount: base.getRate());
|
||||
final rowRate = moneroAmountToDouble(amount: row.getRate());
|
||||
|
||||
if (cur == CryptoCurrency.xusd) {
|
||||
fiatConversionStore.prices[cur] = 1.0;
|
||||
return;
|
||||
}
|
||||
|
||||
fiatConversionStore.prices[cur] = baseRate / rowRate;
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
part of 'haven.dart';
|
||||
|
||||
class CWHavenAccountList extends HavenAccountList {
|
||||
CWHavenAccountList(this._wallet);
|
||||
Object _wallet;
|
||||
|
||||
@override
|
||||
@computed
|
||||
ObservableList<Account> get accounts {
|
||||
final havenWallet = _wallet as HavenWallet;
|
||||
final accounts = havenWallet.walletAddresses.accountList
|
||||
.accounts
|
||||
.map((acc) => Account(id: acc.id, label: acc.label))
|
||||
.toList();
|
||||
return ObservableList<Account>.of(accounts);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
havenWallet.walletAddresses.accountList.update();
|
||||
}
|
||||
|
||||
@override
|
||||
void refresh(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
havenWallet.walletAddresses.accountList.refresh();
|
||||
}
|
||||
|
||||
@override
|
||||
List<Account> getAll(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
return havenWallet.walletAddresses.accountList
|
||||
.getAll()
|
||||
.map((acc) => Account(id: acc.id, label: acc.label))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addAccount(Object wallet, {String label}) async {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
await havenWallet.walletAddresses.accountList.addAccount(label: label);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setLabelAccount(Object wallet, {int accountIndex, String label}) async {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
await havenWallet.walletAddresses.accountList
|
||||
.setLabelAccount(
|
||||
accountIndex: accountIndex,
|
||||
label: label);
|
||||
}
|
||||
}
|
||||
|
||||
class CWHavenSubaddressList extends MoneroSubaddressList {
|
||||
CWHavenSubaddressList(this._wallet);
|
||||
Object _wallet;
|
||||
|
||||
@override
|
||||
@computed
|
||||
ObservableList<Subaddress> get subaddresses {
|
||||
final havenWallet = _wallet as HavenWallet;
|
||||
final subAddresses = havenWallet.walletAddresses.subaddressList
|
||||
.subaddresses
|
||||
.map((sub) => Subaddress(
|
||||
id: sub.id,
|
||||
address: sub.address,
|
||||
label: sub.label))
|
||||
.toList();
|
||||
return ObservableList<Subaddress>.of(subAddresses);
|
||||
}
|
||||
|
||||
@override
|
||||
void update(Object wallet, {int accountIndex}) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
havenWallet.walletAddresses.subaddressList.update(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
void refresh(Object wallet, {int accountIndex}) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
havenWallet.walletAddresses.subaddressList.refresh(accountIndex: accountIndex);
|
||||
}
|
||||
|
||||
@override
|
||||
List<Subaddress> getAll(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
return havenWallet.walletAddresses
|
||||
.subaddressList
|
||||
.getAll()
|
||||
.map((sub) => Subaddress(id: sub.id, label: sub.label, address: sub.address))
|
||||
.toList();
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> addSubaddress(Object wallet, {int accountIndex, String label}) async {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
await havenWallet.walletAddresses.subaddressList
|
||||
.addSubaddress(
|
||||
accountIndex: accountIndex,
|
||||
label: label);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> setLabelSubaddress(Object wallet,
|
||||
{int accountIndex, int addressIndex, String label}) async {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
await havenWallet.walletAddresses.subaddressList
|
||||
.setLabelSubaddress(
|
||||
accountIndex: accountIndex,
|
||||
addressIndex: addressIndex,
|
||||
label: label);
|
||||
}
|
||||
}
|
||||
|
||||
class CWHavenWalletDetails extends HavenWalletDetails {
|
||||
CWHavenWalletDetails(this._wallet);
|
||||
Object _wallet;
|
||||
|
||||
@computed
|
||||
Account get account {
|
||||
final havenWallet = _wallet as HavenWallet;
|
||||
final acc = havenWallet.walletAddresses.account as monero_account.Account;
|
||||
return Account(id: acc.id, label: acc.label);
|
||||
}
|
||||
|
||||
@computed
|
||||
HavenBalance get balance {
|
||||
final havenWallet = _wallet as HavenWallet;
|
||||
final balance = havenWallet.balance;
|
||||
return null;
|
||||
//return HavenBalance(
|
||||
// fullBalance: balance.fullBalance,
|
||||
// unlockedBalance: balance.unlockedBalance);
|
||||
}
|
||||
}
|
||||
|
||||
class CWHaven extends Haven {
|
||||
HavenAccountList getAccountList(Object wallet) {
|
||||
return CWHavenAccountList(wallet);
|
||||
}
|
||||
|
||||
MoneroSubaddressList getSubaddressList(Object wallet) {
|
||||
return CWHavenSubaddressList(wallet);
|
||||
}
|
||||
|
||||
TransactionHistoryBase getTransactionHistory(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
return havenWallet.transactionHistory;
|
||||
}
|
||||
|
||||
HavenWalletDetails getMoneroWalletDetails(Object wallet) {
|
||||
return CWHavenWalletDetails(wallet);
|
||||
}
|
||||
|
||||
int getHeigthByDate({DateTime date}) {
|
||||
return getMoneroHeigthByDate(date: date);
|
||||
}
|
||||
|
||||
TransactionPriority getDefaultTransactionPriority() {
|
||||
return MoneroTransactionPriority.slow;
|
||||
}
|
||||
|
||||
TransactionPriority deserializeMoneroTransactionPriority({int raw}) {
|
||||
return MoneroTransactionPriority.deserialize(raw: raw);
|
||||
}
|
||||
|
||||
List<TransactionPriority> getTransactionPriorities() {
|
||||
return MoneroTransactionPriority.all;
|
||||
}
|
||||
|
||||
List<String> getMoneroWordList(String language) {
|
||||
switch (language.toLowerCase()) {
|
||||
case 'english':
|
||||
return EnglishMnemonics.words;
|
||||
case 'chinese (simplified)':
|
||||
return ChineseSimplifiedMnemonics.words;
|
||||
case 'dutch':
|
||||
return DutchMnemonics.words;
|
||||
case 'german':
|
||||
return GermanMnemonics.words;
|
||||
case 'japanese':
|
||||
return JapaneseMnemonics.words;
|
||||
case 'portuguese':
|
||||
return PortugueseMnemonics.words;
|
||||
case 'russian':
|
||||
return RussianMnemonics.words;
|
||||
case 'spanish':
|
||||
return SpanishMnemonics.words;
|
||||
case 'french':
|
||||
return FrenchMnemonics.words;
|
||||
case 'italian':
|
||||
return ItalianMnemonics.words;
|
||||
default:
|
||||
return EnglishMnemonics.words;
|
||||
}
|
||||
}
|
||||
|
||||
WalletCredentials createHavenRestoreWalletFromKeysCredentials({
|
||||
String name,
|
||||
String spendKey,
|
||||
String viewKey,
|
||||
String address,
|
||||
String password,
|
||||
String language,
|
||||
int height}) {
|
||||
return HavenRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
spendKey: spendKey,
|
||||
viewKey: viewKey,
|
||||
address: address,
|
||||
password: password,
|
||||
language: language,
|
||||
height: height);
|
||||
}
|
||||
|
||||
WalletCredentials createHavenRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic}) {
|
||||
return HavenRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
height: height,
|
||||
mnemonic: mnemonic);
|
||||
}
|
||||
|
||||
WalletCredentials createHavenNewWalletCredentials({String name, String password, String language}) {
|
||||
return HavenNewWalletCredentials(
|
||||
name: name,
|
||||
password: password,
|
||||
language: language);
|
||||
}
|
||||
|
||||
Map<String, String> getKeys(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
final keys = havenWallet.keys;
|
||||
return <String, String>{
|
||||
'privateSpendKey': keys.privateSpendKey,
|
||||
'privateViewKey': keys.privateViewKey,
|
||||
'publicSpendKey': keys.publicSpendKey,
|
||||
'publicViewKey': keys.publicViewKey};
|
||||
}
|
||||
|
||||
Object createHavenTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority, String assetType}) {
|
||||
return HavenTransactionCreationCredentials(
|
||||
outputs: outputs.map((out) => OutputInfo(
|
||||
fiatAmount: out.fiatAmount,
|
||||
cryptoAmount: out.cryptoAmount,
|
||||
address: out.address,
|
||||
note: out.note,
|
||||
sendAll: out.sendAll,
|
||||
extractedAddress: out.extractedAddress,
|
||||
isParsedAddress: out.isParsedAddress,
|
||||
formattedCryptoAmount: out.formattedCryptoAmount))
|
||||
.toList(),
|
||||
priority: priority as MoneroTransactionPriority,
|
||||
assetType: assetType);
|
||||
}
|
||||
|
||||
String formatterMoneroAmountToString({int amount}) {
|
||||
return moneroAmountToString(amount: amount);
|
||||
}
|
||||
|
||||
double formatterMoneroAmountToDouble({int amount}) {
|
||||
return moneroAmountToDouble(amount: amount);
|
||||
}
|
||||
|
||||
int formatterMoneroParseAmount({String amount}) {
|
||||
return moneroParseAmount(amount: amount);
|
||||
}
|
||||
|
||||
Account getCurrentAccount(Object wallet) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
final acc = havenWallet.walletAddresses.account as monero_account.Account;
|
||||
return Account(id: acc.id, label: acc.label);
|
||||
}
|
||||
|
||||
void setCurrentAccount(Object wallet, int id, String label) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
havenWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
|
||||
}
|
||||
|
||||
void onStartup() {
|
||||
monero_wallet_api.onStartup();
|
||||
}
|
||||
|
||||
int getTransactionInfoAccountId(TransactionInfo tx) {
|
||||
final havenTransactionInfo = tx as HavenTransactionInfo;
|
||||
return havenTransactionInfo.accountIndex;
|
||||
}
|
||||
|
||||
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource) {
|
||||
return HavenWalletService(walletInfoSource);
|
||||
}
|
||||
|
||||
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex) {
|
||||
final havenWallet = wallet as HavenWallet;
|
||||
return havenWallet.getTransactionAddress(accountIndex, addressIndex);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/wallet_credentials.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/output_info.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:cw_core/wallet_service.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cw_core/get_height_by_date.dart';
|
||||
import 'package:cw_core/monero_amount_format.dart';
|
||||
import 'package:cw_core/monero_transaction_priority.dart';
|
||||
import 'package:cw_haven/haven_wallet_service.dart';
|
||||
import 'package:cw_haven/haven_wallet.dart';
|
||||
import 'package:cw_haven/haven_transaction_info.dart';
|
||||
import 'package:cw_haven/haven_transaction_history.dart';
|
||||
import 'package:cw_core/account.dart' as monero_account;
|
||||
import 'package:cw_haven/api/wallet.dart' as monero_wallet_api;
|
||||
import 'package:cw_haven/mnemonics/english.dart';
|
||||
import 'package:cw_haven/mnemonics/chinese_simplified.dart';
|
||||
import 'package:cw_haven/mnemonics/dutch.dart';
|
||||
import 'package:cw_haven/mnemonics/german.dart';
|
||||
import 'package:cw_haven/mnemonics/japanese.dart';
|
||||
import 'package:cw_haven/mnemonics/russian.dart';
|
||||
import 'package:cw_haven/mnemonics/spanish.dart';
|
||||
import 'package:cw_haven/mnemonics/portuguese.dart';
|
||||
import 'package:cw_haven/mnemonics/french.dart';
|
||||
import 'package:cw_haven/mnemonics/italian.dart';
|
||||
import 'package:cw_haven/haven_transaction_creation_credentials.dart';
|
||||
|
||||
part 'cw_haven.dart';
|
||||
|
||||
Haven haven = CWHaven();
|
||||
|
||||
class Account {
|
||||
Account({this.id, this.label});
|
||||
final int id;
|
||||
final String label;
|
||||
}
|
||||
|
||||
class Subaddress {
|
||||
Subaddress({this.id, this.accountId, this.label, this.address});
|
||||
final int id;
|
||||
final int accountId;
|
||||
final String label;
|
||||
final String address;
|
||||
}
|
||||
|
||||
class HavenBalance extends Balance {
|
||||
HavenBalance({@required this.fullBalance, @required this.unlockedBalance})
|
||||
: formattedFullBalance = haven.formatterMoneroAmountToString(amount: fullBalance),
|
||||
formattedUnlockedBalance =
|
||||
haven.formatterMoneroAmountToString(amount: unlockedBalance),
|
||||
super(unlockedBalance, fullBalance);
|
||||
|
||||
HavenBalance.fromString(
|
||||
{@required this.formattedFullBalance,
|
||||
@required this.formattedUnlockedBalance})
|
||||
: fullBalance = haven.formatterMoneroParseAmount(amount: formattedFullBalance),
|
||||
unlockedBalance = haven.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
|
||||
super(haven.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
|
||||
haven.formatterMoneroParseAmount(amount: formattedFullBalance));
|
||||
|
||||
final int fullBalance;
|
||||
final int unlockedBalance;
|
||||
final String formattedFullBalance;
|
||||
final String formattedUnlockedBalance;
|
||||
|
||||
@override
|
||||
String get formattedAvailableBalance => formattedUnlockedBalance;
|
||||
|
||||
@override
|
||||
String get formattedAdditionalBalance => formattedFullBalance;
|
||||
}
|
||||
|
||||
abstract class HavenWalletDetails {
|
||||
@observable
|
||||
Account account;
|
||||
|
||||
@observable
|
||||
HavenBalance balance;
|
||||
}
|
||||
|
||||
abstract class Haven {
|
||||
HavenAccountList getAccountList(Object wallet);
|
||||
|
||||
MoneroSubaddressList getSubaddressList(Object wallet);
|
||||
|
||||
TransactionHistoryBase getTransactionHistory(Object wallet);
|
||||
|
||||
HavenWalletDetails getMoneroWalletDetails(Object wallet);
|
||||
|
||||
String getTransactionAddress(Object wallet, int accountIndex, int addressIndex);
|
||||
|
||||
int getHeigthByDate({DateTime date});
|
||||
TransactionPriority getDefaultTransactionPriority();
|
||||
TransactionPriority deserializeMoneroTransactionPriority({int raw});
|
||||
List<TransactionPriority> getTransactionPriorities();
|
||||
List<String> getMoneroWordList(String language);
|
||||
|
||||
WalletCredentials createHavenRestoreWalletFromKeysCredentials({
|
||||
String name,
|
||||
String spendKey,
|
||||
String viewKey,
|
||||
String address,
|
||||
String password,
|
||||
String language,
|
||||
int height});
|
||||
WalletCredentials createHavenRestoreWalletFromSeedCredentials({String name, String password, int height, String mnemonic});
|
||||
WalletCredentials createHavenNewWalletCredentials({String name, String password, String language});
|
||||
Map<String, String> getKeys(Object wallet);
|
||||
Object createHavenTransactionCreationCredentials({List<Output> outputs, TransactionPriority priority, String assetType});
|
||||
String formatterMoneroAmountToString({int amount});
|
||||
double formatterMoneroAmountToDouble({int amount});
|
||||
int formatterMoneroParseAmount({String amount});
|
||||
Account getCurrentAccount(Object wallet);
|
||||
void setCurrentAccount(Object wallet, int id, String label);
|
||||
void onStartup();
|
||||
int getTransactionInfoAccountId(TransactionInfo tx);
|
||||
WalletService createHavenWalletService(Box<WalletInfo> walletInfoSource);
|
||||
}
|
||||
|
||||
abstract class MoneroSubaddressList {
|
||||
ObservableList<Subaddress> get subaddresses;
|
||||
void update(Object wallet, {int accountIndex});
|
||||
void refresh(Object wallet, {int accountIndex});
|
||||
List<Subaddress> getAll(Object wallet);
|
||||
Future<void> addSubaddress(Object wallet, {int accountIndex, String label});
|
||||
Future<void> setLabelSubaddress(Object wallet,
|
||||
{int accountIndex, int addressIndex, String label});
|
||||
}
|
||||
|
||||
abstract class HavenAccountList {
|
||||
ObservableList<Account> get accounts;
|
||||
void update(Object wallet);
|
||||
void refresh(Object wallet);
|
||||
List<Account> getAll(Object wallet);
|
||||
Future<void> addAccount(Object wallet, {String label});
|
||||
Future<void> setLabelAccount(Object wallet, {int accountIndex, String label});
|
||||
}
|
||||
|
||||
+12
-1
@@ -112,6 +112,17 @@ Future<void> main() async {
|
||||
if (!isMoneroOnly) {
|
||||
unspentCoinsInfoSource = await Hive.openBox<UnspentCoinsInfo>(UnspentCoinsInfo.boxName);
|
||||
}
|
||||
|
||||
FlutterError.onError = (FlutterErrorDetails details) {
|
||||
runApp(MaterialApp(
|
||||
debugShowCheckedModeBanner: true,
|
||||
home: Scaffold(
|
||||
body: Container(
|
||||
margin: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
|
||||
child: Text(
|
||||
'Error:\n${details.stack.toString()}',
|
||||
style: TextStyle(fontSize: 22))))));
|
||||
};
|
||||
|
||||
await initialSetup(
|
||||
sharedPreferences: await SharedPreferences.getInstance(),
|
||||
@@ -126,7 +137,7 @@ Future<void> main() async {
|
||||
exchangeTemplates: exchangeTemplates,
|
||||
transactionDescriptions: transactionDescriptions,
|
||||
secureStorage: secureStorage,
|
||||
initialMigrationVersion: 15);
|
||||
initialMigrationVersion: 16);
|
||||
runApp(App());
|
||||
} catch (e) {
|
||||
runApp(MaterialApp(
|
||||
|
||||
@@ -128,9 +128,10 @@ class CWMoneroWalletDetails extends MoneroWalletDetails {
|
||||
MoneroBalance get balance {
|
||||
final moneroWallet = _wallet as MoneroWallet;
|
||||
final balance = moneroWallet.balance;
|
||||
return MoneroBalance(
|
||||
fullBalance: balance.fullBalance,
|
||||
unlockedBalance: balance.unlockedBalance);
|
||||
return MoneroBalance();
|
||||
//return MoneroBalance(
|
||||
// fullBalance: balance.fullBalance,
|
||||
// unlockedBalance: balance.unlockedBalance);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,9 +272,9 @@ class CWMonero extends Monero {
|
||||
return Account(id: acc.id, label: acc.label);
|
||||
}
|
||||
|
||||
void setCurrentAccount(Object wallet, Account account) {
|
||||
void setCurrentAccount(Object wallet, int id, String label) {
|
||||
final moneroWallet = wallet as MoneroWallet;
|
||||
moneroWallet.walletAddresses.account = monero_account.Account(id: account.id, label: account.label);
|
||||
moneroWallet.walletAddresses.account = monero_account.Account(id: id, label: label);
|
||||
}
|
||||
|
||||
void onStartup() {
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/core/fiat_conversion_service.dart';
|
||||
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
Timer _timer;
|
||||
|
||||
@@ -18,7 +20,16 @@ Future<void> startFiatRateUpdate(AppStore appStore, SettingsStore settingsStore,
|
||||
|
||||
_timer = Timer.periodic(
|
||||
Duration(seconds: 30),
|
||||
(_) async => fiatConversionStore.prices[appStore.wallet.currency] =
|
||||
await FiatConversionService.fetchPrice(
|
||||
appStore.wallet.currency, settingsStore.fiatCurrency));
|
||||
(_) async {
|
||||
try {
|
||||
if (appStore.wallet.type == WalletType.haven) {
|
||||
await updateHavenRate(fiatConversionStore);
|
||||
} else {
|
||||
fiatConversionStore.prices[appStore.wallet.currency] = await FiatConversionService.fetchPrice(
|
||||
appStore.wallet.currency, settingsStore.fiatCurrency);
|
||||
}
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
@@ -51,7 +53,7 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
||||
wallet) async {
|
||||
try {
|
||||
final node = settingsStore.getCurrentNode(wallet.type);
|
||||
startWalletSyncStatusChangeReaction(wallet);
|
||||
startWalletSyncStatusChangeReaction(wallet, fiatConversionStore);
|
||||
startCheckConnectionReaction(wallet, settingsStore);
|
||||
await getIt
|
||||
.get<SharedPreferences>()
|
||||
@@ -60,6 +62,11 @@ void startCurrentWalletChangeReaction(AppStore appStore,
|
||||
PreferencesKey.currentWalletType, serializeToInt(wallet.type));
|
||||
await wallet.connectToNode(node: node);
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
settingsStore.fiatCurrency = FiatCurrency.usd;
|
||||
await updateHavenRate(fiatConversionStore);
|
||||
}
|
||||
|
||||
if (wallet.walletInfo.address?.isEmpty ?? true) {
|
||||
wallet.walletInfo.address = wallet.walletAddresses.address;
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/update_haven_rate.dart';
|
||||
import 'package:cake_wallet/entities/wake_lock.dart';
|
||||
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
@@ -12,14 +15,18 @@ ReactionDisposer _onWalletSyncStatusChangeReaction;
|
||||
|
||||
void startWalletSyncStatusChangeReaction(
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo>
|
||||
wallet) {
|
||||
TransactionInfo> wallet,
|
||||
FiatConversionStore fiatConversionStore) {
|
||||
final _wakeLock = getIt.get<WakeLock>();
|
||||
_onWalletSyncStatusChangeReaction?.reaction?.dispose();
|
||||
_onWalletSyncStatusChangeReaction =
|
||||
reaction((_) => wallet.syncStatus, (SyncStatus status) async {
|
||||
if (status is ConnectedSyncStatus) {
|
||||
await wallet.startSync();
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
await updateHavenRate(fiatConversionStore);
|
||||
}
|
||||
}
|
||||
if (status is SyncingSyncStatus) {
|
||||
await _wakeLock.enableWake();
|
||||
|
||||
+11
-5
@@ -68,6 +68,8 @@ import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_page.dart'
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/address_page.dart';
|
||||
|
||||
RouteSettings currentRouteSettings;
|
||||
|
||||
@@ -82,11 +84,11 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||
return CupertinoPageRoute<void>(
|
||||
builder: (_) => getIt.get<SetupPinCodePage>(
|
||||
param1: (PinCodeState<PinCodeWidget> context, dynamic _) {
|
||||
if (isMoneroOnly) {
|
||||
Navigator.of(context.context).pushNamed(Routes.newWallet, arguments: WalletType.monero);
|
||||
} else {
|
||||
Navigator.of(context.context).pushNamed(Routes.newWalletType);
|
||||
}
|
||||
if (availableWalletTypes.length == 1) {
|
||||
Navigator.of(context.context).pushNamed(Routes.newWallet, arguments: availableWalletTypes.first);
|
||||
} else {
|
||||
Navigator.of(context.context).pushNamed(Routes.newWalletType);
|
||||
}
|
||||
}),
|
||||
fullscreenDialog: true);
|
||||
|
||||
@@ -216,6 +218,10 @@ Route<dynamic> createRoute(RouteSettings settings) {
|
||||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true, builder: (_) => getIt.get<ReceivePage>());
|
||||
|
||||
case Routes.addressPage:
|
||||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true, builder: (_) => getIt.get<AddressPage>());
|
||||
|
||||
case Routes.transactionDetails:
|
||||
return CupertinoPageRoute<void>(
|
||||
fullscreenDialog: true,
|
||||
|
||||
@@ -59,4 +59,5 @@ class Routes {
|
||||
static const unspentCoinsDetails = '/unspent_coins_details';
|
||||
static const moneroRestoreWalletFromWelcome = '/monero_restore_wallet';
|
||||
static const moneroNewWalletFromWelcome = '/monero_new_wallet';
|
||||
static const addressPage = '/address_page';
|
||||
}
|
||||
@@ -224,6 +224,9 @@ class ContactListPage extends BasePage {
|
||||
case CryptoCurrency.xrp:
|
||||
image = Image.asset('assets/images/xrp.png', height: 24, width: 24);
|
||||
break;
|
||||
case CryptoCurrency.xhv:
|
||||
image = Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
||||
break;
|
||||
default:
|
||||
image = null;
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ class DashboardPage extends BasePage {
|
||||
|
||||
final DashboardViewModel walletViewModel;
|
||||
final WalletAddressListViewModel addressListViewModel;
|
||||
final controller = PageController(initialPage: 1);
|
||||
final controller = PageController(initialPage: 0);
|
||||
|
||||
var pages = <Widget>[];
|
||||
bool _isEffectsInstalled = false;
|
||||
@@ -101,21 +101,10 @@ class DashboardPage extends BasePage {
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final exchangeImage = Image.asset('assets/images/transfer.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final buyImage = Image.asset('assets/images/buy.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
final sellImage = Image.asset('assets/images/sell.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor);
|
||||
_setEffects(context);
|
||||
|
||||
return SafeArea(
|
||||
minimum: EdgeInsets.only(bottom: 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: <Widget>[
|
||||
@@ -125,7 +114,7 @@ class DashboardPage extends BasePage {
|
||||
itemCount: pages.length,
|
||||
itemBuilder: (context, index) => pages[index])),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 24),
|
||||
padding: EdgeInsets.only(bottom: 24, top: 10),
|
||||
child: SmoothPageIndicator(
|
||||
controller: controller,
|
||||
count: pages.length,
|
||||
@@ -140,48 +129,89 @@ class DashboardPage extends BasePage {
|
||||
.display1
|
||||
.backgroundColor),
|
||||
)),
|
||||
|
||||
ClipRect(
|
||||
child:Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16, bottom: 38),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50.0),
|
||||
border: Border.all(color: currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 32, right: 32, bottom: 14, top: 16),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
if (!isMoneroOnly)
|
||||
Observer(builder: (_) {
|
||||
return ClipRect(
|
||||
child:Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16),
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(50.0),
|
||||
border: Border.all(color: currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(left: 32, right: 32),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
if (walletViewModel.hasBuyAction)
|
||||
ActionButton(
|
||||
image: Image.asset('assets/images/buy.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: !walletViewModel.isEnabledBuyAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
title: S.of(context).buy,
|
||||
onClick: () async => await _onClickBuyButton(context),
|
||||
textColor: !walletViewModel.isEnabledBuyAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: null),
|
||||
ActionButton(
|
||||
image: buyImage,
|
||||
title: S.of(context).buy,
|
||||
onClick: () async => await _onClickBuyButton(context),
|
||||
),
|
||||
ActionButton(
|
||||
image: receiveImage,
|
||||
title: S.of(context).receive,
|
||||
route: Routes.receive),
|
||||
ActionButton(
|
||||
image: exchangeImage,
|
||||
title: S.of(context).exchange,
|
||||
route: Routes.exchange),
|
||||
ActionButton(
|
||||
image: sendImage,
|
||||
title: S.of(context).send,
|
||||
route: Routes.send),
|
||||
if (!isMoneroOnly)
|
||||
image: receiveImage,
|
||||
title: S.of(context).receive,
|
||||
route: Routes.addressPage),
|
||||
if (walletViewModel.hasExchangeAction)
|
||||
ActionButton(
|
||||
image: Image.asset('assets/images/transfer.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: !walletViewModel.isEnabledExchangeAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
title: S.of(context).exchange,
|
||||
onClick: () async => _onClickExchangeButton(context),
|
||||
textColor: !walletViewModel.isEnabledExchangeAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: null),
|
||||
ActionButton(
|
||||
image: sellImage,
|
||||
title: S.of(context).sell,
|
||||
onClick: () async => await _onClickSellButton(context),
|
||||
),
|
||||
],
|
||||
),),
|
||||
),),),
|
||||
image: sendImage,
|
||||
title: S.of(context).send,
|
||||
route: Routes.send),
|
||||
if (walletViewModel.hasSellAction)
|
||||
ActionButton(
|
||||
image: Image.asset('assets/images/sell.png',
|
||||
height: 24,
|
||||
width: 24,
|
||||
color: !walletViewModel.isEnabledSellAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
title: S.of(context).sell,
|
||||
onClick: () async => await _onClickSellButton(context),
|
||||
textColor: !walletViewModel.isEnabledSellAction
|
||||
? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor
|
||||
: null),
|
||||
],
|
||||
),),
|
||||
),),);
|
||||
}),
|
||||
|
||||
],
|
||||
));
|
||||
@@ -192,9 +222,6 @@ class DashboardPage extends BasePage {
|
||||
return;
|
||||
}
|
||||
|
||||
pages.add(AddressPage(
|
||||
addressListViewModel: addressListViewModel,
|
||||
walletViewModel: walletViewModel));
|
||||
pages.add(balancePage);
|
||||
pages.add(TransactionsPage(dashboardViewModel: walletViewModel));
|
||||
_isEffectsInstalled = true;
|
||||
@@ -289,4 +316,24 @@ class DashboardPage extends BasePage {
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _onClickExchangeButton(BuildContext context) async {
|
||||
final walletType = walletViewModel.type;
|
||||
|
||||
switch (walletType) {
|
||||
case WalletType.haven:
|
||||
await showPopUp<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: 'Exchange',
|
||||
alertContent: 'Exchange for this asset is not supported yet.',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
break;
|
||||
default:
|
||||
await Navigator.of(context).pushNamed(Routes.exchange);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,17 +6,25 @@ class ActionButton extends StatelessWidget {
|
||||
@required this.title,
|
||||
this.route,
|
||||
this.onClick,
|
||||
this.alignment = Alignment.center});
|
||||
this.alignment = Alignment.center,
|
||||
this.textColor});
|
||||
|
||||
final Image image;
|
||||
final String title;
|
||||
final String route;
|
||||
final Alignment alignment;
|
||||
final void Function() onClick;
|
||||
final Color textColor;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var _textColor = textColor ?? Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor;
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 14, bottom: 16, left: 10, right: 10),
|
||||
alignment: alignment,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -42,8 +50,7 @@ class ActionButton extends StatelessWidget {
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 10,
|
||||
color: Theme.of(context).accentTextTheme.display3
|
||||
.backgroundColor),
|
||||
color: _textColor),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/keyboard_done_button.dart';
|
||||
@@ -15,7 +16,7 @@ import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:keyboard_actions/keyboard_actions.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
|
||||
class AddressPage extends StatelessWidget {
|
||||
class AddressPage extends BasePage {
|
||||
AddressPage({@required this.addressListViewModel,
|
||||
this.walletViewModel})
|
||||
: _cryptoAmountFocus = FocusNode();
|
||||
@@ -26,7 +27,64 @@ class AddressPage extends StatelessWidget {
|
||||
final FocusNode _cryptoAmountFocus;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String get title => S.current.receive;
|
||||
|
||||
@override
|
||||
Color get backgroundLightColor => currentTheme.type == ThemeType.bright
|
||||
? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Color get backgroundDarkColor => Colors.transparent;
|
||||
|
||||
@override
|
||||
bool get resizeToAvoidBottomInset => false;
|
||||
|
||||
@override
|
||||
Widget leading(BuildContext context) {
|
||||
final _backButton = Icon(Icons.arrow_back_ios,
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor,
|
||||
size: 16,);
|
||||
|
||||
return SizedBox(
|
||||
height: 37,
|
||||
width: 37,
|
||||
child: ButtonTheme(
|
||||
minWidth: double.minPositive,
|
||||
child: FlatButton(
|
||||
highlightColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
padding: EdgeInsets.all(0),
|
||||
onPressed: () => onClose(context),
|
||||
child: _backButton),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget middle(BuildContext context) {
|
||||
return Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Lato',
|
||||
color: Theme.of(context).accentTextTheme.display3.backgroundColor),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget Function(BuildContext, Widget) get rootWrapper =>
|
||||
(BuildContext context, Widget scaffold) => Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(colors: [
|
||||
Theme.of(context).accentColor,
|
||||
Theme.of(context).scaffoldBackgroundColor,
|
||||
Theme.of(context).primaryColor,
|
||||
], begin: Alignment.topRight, end: Alignment.bottomLeft)),
|
||||
child: scaffold);
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
autorun((_) async {
|
||||
if (!walletViewModel.isOutdatedElectrumWallet
|
||||
|| !walletViewModel.settingsStore.shouldShowReceiveWarning) {
|
||||
@@ -66,7 +124,6 @@ class AddressPage extends StatelessWidget {
|
||||
)
|
||||
]),
|
||||
child: Container(
|
||||
height: 1,
|
||||
padding: EdgeInsets.fromLTRB(24, 24, 24, 32),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/src/widgets/standard_list.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -15,23 +16,21 @@ class BalancePage extends StatelessWidget{
|
||||
|
||||
Color get backgroundLightColor =>
|
||||
settingsStore.currentTheme.type == ThemeType.bright ? Colors.transparent : Colors.white;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onLongPress: () =>
|
||||
dashboardViewModel.balanceViewModel.isReversing =
|
||||
!dashboardViewModel.balanceViewModel.isReversing,
|
||||
onLongPressUp: () =>
|
||||
dashboardViewModel.balanceViewModel.isReversing =
|
||||
!dashboardViewModel.balanceViewModel.isReversing,
|
||||
onLongPress: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
|
||||
onLongPressUp: () => dashboardViewModel.balanceViewModel.isReversing = !dashboardViewModel.balanceViewModel.isReversing,
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 56),
|
||||
Container(
|
||||
alignment: Alignment.topLeft,
|
||||
margin: const EdgeInsets.only(left: 24, bottom: 16),
|
||||
child: Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.asset,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
@@ -44,162 +43,140 @@ class BalancePage extends StatelessWidget{
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
})),
|
||||
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor
|
||||
),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 24, left: 24, right: 24, bottom: 24),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 8,),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 8,),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
dashboardViewModel.balanceViewModel.availableBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
SizedBox(height: 4,),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.availableFiatBalance.toString()}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 26),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
SizedBox(height: 8),
|
||||
Observer(builder: (_) {
|
||||
return AutoSizeText(
|
||||
dashboardViewModel.balanceViewModel.additionalBalance
|
||||
.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center);
|
||||
}),
|
||||
SizedBox(height: 4,),
|
||||
Observer(builder: (_) {
|
||||
return Column(
|
||||
children: [
|
||||
Text(
|
||||
'${dashboardViewModel.balanceViewModel.additionalFiatBalance.toString()}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
],
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return Text(
|
||||
dashboardViewModel.balanceViewModel.currency.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
);
|
||||
}),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
],
|
||||
})),
|
||||
Observer(builder: (_) {
|
||||
return ListView.separated(
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
shrinkWrap: true,
|
||||
separatorBuilder: (_, __) => Container(padding: EdgeInsets.only(bottom: 8)),
|
||||
itemCount: dashboardViewModel.balanceViewModel.formattedBalances.length,
|
||||
itemBuilder: (__, index) {
|
||||
final balance = dashboardViewModel.balanceViewModel.formattedBalances.elementAt(index);
|
||||
return buildBalanceRow(context,
|
||||
availableBalanceLabel: '${dashboardViewModel.balanceViewModel.availableBalanceLabel}',
|
||||
availableBalance: balance.availableBalance,
|
||||
availableFiatBalance: balance.fiatAvailableBalance,
|
||||
additionalBalanceLabel: '${dashboardViewModel.balanceViewModel.additionalBalanceLabel}',
|
||||
additionalBalance: balance.additionalBalance,
|
||||
additionalFiatBalance: balance.fiatAdditionalBalance,
|
||||
currency: balance.formattedAssetTitle);
|
||||
});
|
||||
})
|
||||
])));
|
||||
}
|
||||
|
||||
Widget buildBalanceRow(BuildContext context,
|
||||
{String availableBalanceLabel,
|
||||
String availableBalance,
|
||||
String availableFiatBalance,
|
||||
String additionalBalanceLabel,
|
||||
String additionalBalance,
|
||||
String additionalFiatBalance,
|
||||
String currency}) {
|
||||
return Container(
|
||||
margin: const EdgeInsets.only(left: 16, right: 16),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
border: Border.all(color: settingsStore.currentTheme.type == ThemeType.bright ? Color.fromRGBO(255, 255, 255, 0.2): Colors.transparent, width: 1, ),
|
||||
color:Theme.of(context).textTheme.title.backgroundColor
|
||||
),
|
||||
|
||||
child: Container(
|
||||
margin: const EdgeInsets.only(top: 16, left: 24, right: 24, bottom: 24),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(height: 4,),
|
||||
Text('${availableBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
SizedBox(height: 5),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
AutoSizeText(
|
||||
availableBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 24,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w900,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center),
|
||||
Text(currency,
|
||||
style: TextStyle(
|
||||
fontSize: 28,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
]),
|
||||
SizedBox(height: 4,),
|
||||
Text('${availableFiatBalance}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
SizedBox(height: 26),
|
||||
Text('${additionalBalanceLabel}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.backgroundColor,
|
||||
height: 1)),
|
||||
SizedBox(height: 8),
|
||||
AutoSizeText(
|
||||
additionalBalance,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
maxLines: 1,
|
||||
textAlign: TextAlign.center),
|
||||
SizedBox(height: 4,),
|
||||
Text('${additionalFiatBalance}',
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontFamily: 'Lato',
|
||||
fontWeight: FontWeight.w400,
|
||||
color: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display3
|
||||
.backgroundColor,
|
||||
height: 1),
|
||||
)
|
||||
])),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
Image moneroIcon;
|
||||
Image bitcoinIcon;
|
||||
Image litecoinIcon;
|
||||
Image havenIcon;
|
||||
final largeScreen = 731;
|
||||
|
||||
double menuWidth;
|
||||
@@ -78,6 +79,7 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
bitcoinIcon = Image.asset('assets/images/bitcoin_menu.png',
|
||||
color: Theme.of(context).accentTextTheme.overline.decorationColor);
|
||||
litecoinIcon = Image.asset('assets/images/litecoin_menu.png');
|
||||
havenIcon = Image.asset('assets/images/haven_menu.png');
|
||||
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
@@ -242,6 +244,8 @@ class MenuWidgetState extends State<MenuWidget> {
|
||||
return bitcoinIcon;
|
||||
case WalletType.litecoin:
|
||||
return litecoinIcon;
|
||||
case WalletType.haven:
|
||||
return havenIcon;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
final walletTypeImage = Image.asset('assets/images/wallet_type.png');
|
||||
final walletTypeLightImage =
|
||||
Image.asset('assets/images/wallet_type_light.png');
|
||||
final havenIcon =
|
||||
Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
||||
|
||||
WalletType selected;
|
||||
List<WalletType> types;
|
||||
@@ -129,6 +131,8 @@ class WalletTypeFormState extends State<WalletTypeForm> {
|
||||
return bitcoinIcon;
|
||||
case WalletType.litecoin:
|
||||
return litecoinIcon;
|
||||
case WalletType.haven:
|
||||
return havenIcon;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ class ReceivePage extends BasePage {
|
||||
|
||||
@override
|
||||
Widget body(BuildContext context) {
|
||||
return addressListViewModel.type == WalletType.monero
|
||||
return (addressListViewModel.type == WalletType.monero || addressListViewModel.type == WalletType.haven)
|
||||
? KeyboardActions(
|
||||
config: KeyboardActionsConfig(
|
||||
keyboardActionsPlatform: KeyboardActionsPlatform.IOS,
|
||||
|
||||
@@ -133,54 +133,7 @@ class QRWidget extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
))),
|
||||
),
|
||||
Observer(builder: (_) {
|
||||
return addressListViewModel.emoji.isNotEmpty
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(bottom: 10),
|
||||
child: Builder(
|
||||
builder: (context) => GestureDetector(
|
||||
onTap: () {
|
||||
Clipboard.setData(ClipboardData(
|
||||
text: addressListViewModel.emoji));
|
||||
showBar<void>(
|
||||
context, S.of(context).copied_to_clipboard);
|
||||
},
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).yat,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).accentTextTheme.
|
||||
display3.backgroundColor),
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(child:Text(
|
||||
addressListViewModel.emoji,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 26))),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 12),
|
||||
child: copyImage,
|
||||
)]
|
||||
),
|
||||
)
|
||||
]
|
||||
)
|
||||
)),
|
||||
)
|
||||
: Container();
|
||||
})
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,8 @@ class WalletRestoreFromSeedFormState extends State<WalletRestoreFromSeedForm> {
|
||||
BlockchainHeightWidget(
|
||||
focusNode: widget.blockHeightFocusNode,
|
||||
key: blockchainHeightKey,
|
||||
onHeightOrDateEntered: widget.onHeightOrDateEntered)
|
||||
onHeightOrDateEntered: widget.onHeightOrDateEntered,
|
||||
hasDatePicker: widget.type == WalletType.monero)
|
||||
]));
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ class WalletRestorePage extends BasePage {
|
||||
.text
|
||||
.split(' ');
|
||||
|
||||
if (walletRestoreViewModel.type == WalletType.monero &&
|
||||
if ((walletRestoreViewModel.type == WalletType.monero || walletRestoreViewModel.type == WalletType.haven) &&
|
||||
seedWords.length != WalletRestoreViewModelBase.moneroSeedMnemonicLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:ui';
|
||||
import 'package:cake_wallet/src/screens/dashboard/widgets/sync_indicator_icon.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/send_card.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/src/widgets/picker.dart';
|
||||
import 'package:cake_wallet/src/widgets/template_tile.dart';
|
||||
import 'package:cake_wallet/view_model/send/output.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
@@ -22,6 +23,7 @@ import 'package:dotted_border/dotted_border.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_one_action.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/confirm_sending_alert.dart';
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
|
||||
class SendPage extends BasePage {
|
||||
SendPage({@required this.sendViewModel}) : _formKey = GlobalKey<FormState>();
|
||||
@@ -140,6 +142,7 @@ class SendPage extends BasePage {
|
||||
),
|
||||
),
|
||||
),
|
||||
if (sendViewModel.hasMultiRecipient)
|
||||
Container(
|
||||
height: 40,
|
||||
width: double.infinity,
|
||||
@@ -256,27 +259,43 @@ class SendPage extends BasePage {
|
||||
EdgeInsets.only(left: 24, right: 24, bottom: 24),
|
||||
bottomSection: Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
sendViewModel.addOutput();
|
||||
Future.delayed(const Duration(milliseconds: 250), () {
|
||||
controller.jumpToPage(sendViewModel.outputs.length - 1);
|
||||
});
|
||||
},
|
||||
text: S.of(context).add_receiver,
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
isDottedBorder: true,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
)),
|
||||
if (sendViewModel.hasCurrecyChanger)
|
||||
Observer(builder: (_) =>
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () => presentCurrencyPicker(context),
|
||||
text: 'Change your asset (${sendViewModel.selectedCryptoCurrency})',
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
)
|
||||
)
|
||||
),
|
||||
if (sendViewModel.hasMultiRecipient)
|
||||
Padding(
|
||||
padding: EdgeInsets.only(bottom: 12),
|
||||
child: PrimaryButton(
|
||||
onPressed: () {
|
||||
sendViewModel.addOutput();
|
||||
Future.delayed(const Duration(milliseconds: 250), () {
|
||||
controller.jumpToPage(sendViewModel.outputs.length - 1);
|
||||
});
|
||||
},
|
||||
text: S.of(context).add_receiver,
|
||||
color: Colors.transparent,
|
||||
textColor: Theme.of(context)
|
||||
.accentTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
isDottedBorder: true,
|
||||
borderColor: Theme.of(context)
|
||||
.primaryTextTheme
|
||||
.display2
|
||||
.decorationColor,
|
||||
)),
|
||||
Observer(
|
||||
builder: (_) {
|
||||
return LoadingPrimaryButton(
|
||||
@@ -298,7 +317,7 @@ class SendPage extends BasePage {
|
||||
showErrorValidationAlert(context);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await sendViewModel.createTransaction();
|
||||
|
||||
},
|
||||
@@ -377,7 +396,7 @@ class SendPage extends BasePage {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: '',
|
||||
alertContent: S.of(context).send_success(
|
||||
sendViewModel.currency.toString()),
|
||||
sendViewModel.selectedCryptoCurrency.toString()),
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () =>
|
||||
Navigator.of(context).pop());
|
||||
@@ -418,4 +437,17 @@ class SendPage extends BasePage {
|
||||
buttonAction: () => Navigator.of(context).pop());
|
||||
});
|
||||
}
|
||||
|
||||
void presentCurrencyPicker(BuildContext context) async {
|
||||
await showPopUp<CryptoCurrency>(
|
||||
builder: (_) => Picker(
|
||||
items: sendViewModel.currencies,
|
||||
displayItem: (Object item) => item.toString(),
|
||||
selectedAtIndex: sendViewModel.currencies.indexOf(sendViewModel.selectedCryptoCurrency),
|
||||
title: S.of(context).please_select,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
onItemSelected: (CryptoCurrency cur) => sendViewModel.selectedCryptoCurrency = cur,
|
||||
),
|
||||
context: context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ class SendCardState extends State<SendCard>
|
||||
prefixIcon: Padding(
|
||||
padding: EdgeInsets.only(top: 9),
|
||||
child: Text(
|
||||
sendViewModel.currency.title +
|
||||
sendViewModel.selectedCryptoCurrency.title +
|
||||
':',
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
@@ -391,7 +391,7 @@ class SendCardState extends State<SendCard>
|
||||
.toString() +
|
||||
' ' +
|
||||
sendViewModel
|
||||
.currency.title,
|
||||
.selectedCryptoCurrency.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight:
|
||||
|
||||
@@ -45,6 +45,8 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
Image.asset('assets/images/litecoin_icon.png', height: 24, width: 24);
|
||||
final nonWalletTypeIcon =
|
||||
Image.asset('assets/images/close.png', height: 24, width: 24);
|
||||
final havenIcon =
|
||||
Image.asset('assets/images/haven_logo.png', height: 24, width: 24);
|
||||
final scrollController = ScrollController();
|
||||
final double tileHeight = 60;
|
||||
Flushbar<void> _progressBar;
|
||||
@@ -176,12 +178,12 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
bottomSection: Column(children: <Widget>[
|
||||
PrimaryImageButton(
|
||||
onPressed: () {
|
||||
if (isMoneroOnly) {
|
||||
Navigator.of(context).pushNamed(Routes.newWallet, arguments: WalletType.monero);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(Routes.newWalletType);
|
||||
}
|
||||
},
|
||||
if (isSingleCoin) {
|
||||
Navigator.of(context).pushNamed(Routes.newWallet, arguments: widget.walletListViewModel.currentWalletType);
|
||||
} else {
|
||||
Navigator.of(context).pushNamed(Routes.newWalletType);
|
||||
}
|
||||
},
|
||||
image: newWalletImage,
|
||||
text: S.of(context).wallet_list_create_new_wallet,
|
||||
color: Theme.of(context).accentTextTheme.body2.color,
|
||||
@@ -190,7 +192,7 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
SizedBox(height: 10.0),
|
||||
PrimaryImageButton(
|
||||
onPressed: () {
|
||||
if (isMoneroOnly) {
|
||||
if (isSingleCoin) {
|
||||
Navigator
|
||||
.of(context)
|
||||
.pushNamed(
|
||||
@@ -216,6 +218,8 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
return moneroIcon;
|
||||
case WalletType.litecoin:
|
||||
return litecoinIcon;
|
||||
case WalletType.haven:
|
||||
return havenIcon;
|
||||
default:
|
||||
return nonWalletTypeIcon;
|
||||
}
|
||||
@@ -264,18 +268,6 @@ class WalletListBodyState extends State<WalletListBody> {
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _generateNewWallet() async {
|
||||
try {
|
||||
changeProcessText(S.of(context).creating_new_wallet);
|
||||
await widget.walletListViewModel.walletNewVM
|
||||
.create(options: 'English'); // FIXME: Unnamed constant
|
||||
hideProgressText();
|
||||
await Navigator.of(context).pushNamed(Routes.preSeed);
|
||||
} catch (e) {
|
||||
changeProcessText(S.of(context).creating_new_wallet_error(e.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
void changeProcessText(String text) {
|
||||
_progressBar = createBar<void>(text, duration: null)..show(context);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,30 @@ class WelcomePage extends BasePage {
|
||||
final welcomeImageLight = Image.asset('assets/images/welcome_light.png');
|
||||
final welcomeImageDark = Image.asset('assets/images/welcome.png');
|
||||
|
||||
String appTitle(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app;
|
||||
}
|
||||
|
||||
return S.of(context).cake_wallet;
|
||||
}
|
||||
|
||||
String appDescription(BuildContext context) {
|
||||
if (isMoneroOnly) {
|
||||
return S.of(context).monero_com_wallet_text;
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return S.of(context).haven_app_wallet_text;
|
||||
}
|
||||
|
||||
return S.of(context).first_wallet_text;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -83,9 +107,7 @@ class WelcomePage extends BasePage {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
isMoneroOnly
|
||||
? S.of(context).monero_com
|
||||
: S.of(context).cake_wallet,
|
||||
appTitle(context),
|
||||
style: TextStyle(
|
||||
fontSize: 36,
|
||||
fontWeight: FontWeight.bold,
|
||||
@@ -101,9 +123,7 @@ class WelcomePage extends BasePage {
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 5),
|
||||
child: Text(
|
||||
isMoneroOnly
|
||||
? S.of(context).monero_com_wallet_text
|
||||
: S.of(context).first_wallet_text,
|
||||
appDescription(context),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w500,
|
||||
|
||||
@@ -7,12 +7,13 @@ import 'package:cake_wallet/src/widgets/base_text_form_field.dart';
|
||||
|
||||
class BlockchainHeightWidget extends StatefulWidget {
|
||||
BlockchainHeightWidget({GlobalKey key, this.onHeightChange, this.focusNode,
|
||||
this.onHeightOrDateEntered})
|
||||
this.onHeightOrDateEntered, this.hasDatePicker})
|
||||
: super(key: key);
|
||||
|
||||
final Function(int) onHeightChange;
|
||||
final Function(bool) onHeightOrDateEntered;
|
||||
final FocusNode focusNode;
|
||||
final bool hasDatePicker;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() => BlockchainHeightState();
|
||||
@@ -67,43 +68,45 @@ class BlockchainHeightState extends State<BlockchainHeightWidget> {
|
||||
)))
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Text(
|
||||
S.of(context).widgets_or,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: InkWell(
|
||||
onTap: () => _selectDate(context),
|
||||
child: IgnorePointer(
|
||||
child: BaseTextFormField(
|
||||
controller: dateController,
|
||||
hintText: S.of(context).widgets_restore_from_date,
|
||||
)),
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
|
||||
child: Text(
|
||||
S.of(context).restore_from_date_or_blockheight,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).hintColor
|
||||
if (widget.hasDatePicker) ...[
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 15, bottom: 15),
|
||||
child: Text(
|
||||
S.of(context).widgets_or,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Theme.of(context).primaryTextTheme.title.color),
|
||||
),
|
||||
),
|
||||
)
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Flexible(
|
||||
child: Container(
|
||||
child: InkWell(
|
||||
onTap: () => _selectDate(context),
|
||||
child: IgnorePointer(
|
||||
child: BaseTextFormField(
|
||||
controller: dateController,
|
||||
hintText: S.of(context).widgets_restore_from_date,
|
||||
)),
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(left: 40, right: 40, top: 24),
|
||||
child: Text(
|
||||
S.of(context).restore_from_date_or_blockheight,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.normal,
|
||||
color: Theme.of(context).hintColor
|
||||
),
|
||||
),
|
||||
)
|
||||
]
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -227,9 +227,12 @@ abstract class SettingsStoreBase with Store {
|
||||
.getInt(PreferencesKey.currentBitcoinElectrumSererIdKey);
|
||||
final litecoinElectrumServerId = sharedPreferences
|
||||
.getInt(PreferencesKey.currentLitecoinElectrumSererIdKey);
|
||||
final havenNodeId = sharedPreferences
|
||||
.getInt(PreferencesKey.currentHavenNodeIdKey);
|
||||
final moneroNode = nodeSource.get(nodeId);
|
||||
final bitcoinElectrumServer = nodeSource.get(bitcoinElectrumServerId);
|
||||
final litecoinElectrumServer = nodeSource.get(litecoinElectrumServerId);
|
||||
final havenNode = nodeSource.get(havenNodeId);
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final shouldShowYatPopup =
|
||||
sharedPreferences.getBool(PreferencesKey.shouldShowYatPopup) ?? true;
|
||||
@@ -239,7 +242,8 @@ abstract class SettingsStoreBase with Store {
|
||||
nodes: {
|
||||
WalletType.monero: moneroNode,
|
||||
WalletType.bitcoin: bitcoinElectrumServer,
|
||||
WalletType.litecoin: litecoinElectrumServer
|
||||
WalletType.litecoin: litecoinElectrumServer,
|
||||
WalletType.haven: havenNode
|
||||
},
|
||||
appVersion: packageInfo.version,
|
||||
isBitcoinBuyEnabled: isBitcoinBuyEnabled,
|
||||
|
||||
@@ -15,6 +15,21 @@ 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});
|
||||
final String fiatAdditionalBalance;
|
||||
final String fiatAvailableBalance;
|
||||
final String additionalBalance;
|
||||
final String availableBalance;
|
||||
final CryptoCurrency asset;
|
||||
final String formattedAssetTitle;
|
||||
}
|
||||
|
||||
class BalanceViewModel = BalanceViewModelBase with _$BalanceViewModel;
|
||||
|
||||
abstract class BalanceViewModelBase with Store {
|
||||
@@ -24,16 +39,7 @@ abstract class BalanceViewModelBase with Store {
|
||||
@required this.fiatConvertationStore}) {
|
||||
isReversing = false;
|
||||
wallet ??= appStore.wallet;
|
||||
balance = wallet.balance;
|
||||
|
||||
reaction((_) => appStore.wallet, _onWalletChange);
|
||||
|
||||
_onCurrentWalletChangeReaction =
|
||||
reaction<void>((_) => wallet.balance, (dynamic balance) {
|
||||
if (balance is Balance) {
|
||||
this.balance = balance;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
final AppStore appStore;
|
||||
@@ -45,9 +51,6 @@ abstract class BalanceViewModelBase with Store {
|
||||
@observable
|
||||
bool isReversing;
|
||||
|
||||
@observable
|
||||
Balance balance;
|
||||
|
||||
@observable
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
|
||||
wallet;
|
||||
@@ -58,47 +61,56 @@ abstract class BalanceViewModelBase with Store {
|
||||
@computed
|
||||
BalanceDisplayMode get savedDisplayMode => settingsStore.balanceDisplayMode;
|
||||
|
||||
@computed
|
||||
@computed
|
||||
String get asset {
|
||||
|
||||
switch(appStore.wallet.currency){
|
||||
case CryptoCurrency.btc:
|
||||
return 'Bitcoin Assets';
|
||||
case CryptoCurrency.xmr:
|
||||
return 'Monero Assets';
|
||||
case CryptoCurrency.ltc:
|
||||
return 'Litecoin Assets';
|
||||
final typeFormatted = walletTypeToString(appStore.wallet.type);
|
||||
|
||||
switch(wallet.type) {
|
||||
case WalletType.haven:
|
||||
return '$typeFormatted Assets';
|
||||
default:
|
||||
return '';
|
||||
return typeFormatted;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@computed
|
||||
BalanceDisplayMode get displayMode => isReversing
|
||||
? savedDisplayMode == BalanceDisplayMode.hiddenBalance
|
||||
? BalanceDisplayMode.displayableBalance
|
||||
: savedDisplayMode
|
||||
: savedDisplayMode;
|
||||
BalanceDisplayMode get displayMode {
|
||||
if (isReversing) {
|
||||
if (savedDisplayMode == BalanceDisplayMode.hiddenBalance) {
|
||||
return BalanceDisplayMode.displayableBalance;
|
||||
} else {
|
||||
return BalanceDisplayMode.hiddenBalance;
|
||||
}
|
||||
}
|
||||
|
||||
return savedDisplayMode;
|
||||
}
|
||||
|
||||
@computed
|
||||
String get availableBalanceLabel {
|
||||
if (wallet.type == WalletType.monero) {
|
||||
return S.current.xmr_available_balance;
|
||||
switch(wallet.type) {
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
return S.current.xmr_available_balance;
|
||||
default:
|
||||
return S.current.confirmed;
|
||||
}
|
||||
|
||||
return S.current.confirmed;
|
||||
}
|
||||
|
||||
@computed
|
||||
String get additionalBalanceLabel {
|
||||
if (wallet.type == WalletType.monero) {
|
||||
return S.current.xmr_full_balance;
|
||||
switch(wallet.type) {
|
||||
case WalletType.monero:
|
||||
case WalletType.haven:
|
||||
return S.current.xmr_full_balance;
|
||||
default:
|
||||
return S.current.unconfirmed;
|
||||
}
|
||||
|
||||
return S.current.unconfirmed;
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get hasMultiBalance => appStore.wallet.type == WalletType.haven;
|
||||
|
||||
@computed
|
||||
String get availableBalance {
|
||||
final walletBalance = _walletBalance;
|
||||
@@ -152,7 +164,73 @@ abstract class BalanceViewModelBase with Store {
|
||||
}
|
||||
|
||||
@computed
|
||||
Balance get _walletBalance => wallet.balance;
|
||||
Map<CryptoCurrency, BalanceRecord> get balances {
|
||||
return wallet.balance.map((key, value) {
|
||||
if (displayMode == BalanceDisplayMode.hiddenBalance) {
|
||||
return MapEntry(key, BalanceRecord(
|
||||
availableBalance: '---',
|
||||
additionalBalance: '---',
|
||||
fiatAdditionalBalance: '---',
|
||||
fiatAvailableBalance: '---',
|
||||
asset: key,
|
||||
formattedAssetTitle: _formatterAsset(key)));
|
||||
}
|
||||
final fiatCurrency = settingsStore.fiatCurrency;
|
||||
final additionalFiatBalance = fiatCurrency.toString()
|
||||
+ ' '
|
||||
+ _getFiatBalance(
|
||||
price: fiatConvertationStore.prices[key],
|
||||
cryptoAmount: value.formattedAdditionalBalance);
|
||||
|
||||
final availableFiatBalance = fiatCurrency.toString()
|
||||
+ ' '
|
||||
+ _getFiatBalance(
|
||||
price: fiatConvertationStore.prices[key],
|
||||
cryptoAmount: value.formattedAvailableBalance);
|
||||
|
||||
return MapEntry(key, BalanceRecord(
|
||||
availableBalance: value.formattedAvailableBalance,
|
||||
additionalBalance: value.formattedAdditionalBalance,
|
||||
fiatAdditionalBalance: additionalFiatBalance,
|
||||
fiatAvailableBalance: availableFiatBalance,
|
||||
asset: key,
|
||||
formattedAssetTitle: _formatterAsset(key)));
|
||||
});
|
||||
}
|
||||
|
||||
@computed
|
||||
List<BalanceRecord> get formattedBalances {
|
||||
final balance = balances.values.toList();
|
||||
|
||||
balance.sort((BalanceRecord a, BalanceRecord b) {
|
||||
if (b.asset == CryptoCurrency.xhv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xusd) {
|
||||
if (a.asset == CryptoCurrency.xhv) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xbtc) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b.asset == CryptoCurrency.xeur) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return balance;
|
||||
}
|
||||
|
||||
@computed
|
||||
Balance get _walletBalance => wallet.balance[wallet.currency];
|
||||
|
||||
@computed
|
||||
CryptoCurrency get currency => appStore.wallet.currency;
|
||||
@@ -164,11 +242,8 @@ abstract class BalanceViewModelBase with Store {
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>,
|
||||
TransactionInfo>
|
||||
wallet) {
|
||||
this.wallet = wallet;
|
||||
balance = wallet.balance;
|
||||
this.wallet = wallet;
|
||||
_onCurrentWalletChangeReaction?.reaction?.dispose();
|
||||
_onCurrentWalletChangeReaction = reaction<Balance>(
|
||||
(_) => wallet.balance, (Balance balance) => this.balance = balance);
|
||||
}
|
||||
|
||||
String _getFiatBalance({double price, String cryptoAmount}) {
|
||||
@@ -178,5 +253,20 @@ abstract class BalanceViewModelBase with Store {
|
||||
|
||||
return calculateFiatAmount(price: price, cryptoAmount: cryptoAmount);
|
||||
}
|
||||
|
||||
String _formatterAsset(CryptoCurrency asset) {
|
||||
switch (wallet.type) {
|
||||
case WalletType.haven:
|
||||
final assetStringified = asset.toString();
|
||||
|
||||
if (asset != CryptoCurrency.xhv && assetStringified[0].toUpperCase() == 'X') {
|
||||
return assetStringified.replaceFirst('X', 'x');
|
||||
}
|
||||
|
||||
return asset.toString();
|
||||
default:
|
||||
return asset.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
import 'package:cw_core/transaction_history.dart';
|
||||
import 'package:cw_core/balance.dart';
|
||||
import 'package:cake_wallet/buy/order.dart';
|
||||
@@ -78,6 +79,8 @@ abstract class DashboardViewModelBase with Store {
|
||||
isShowFirstYatIntroduction = false;
|
||||
isShowSecondYatIntroduction = false;
|
||||
isShowThirdYatIntroduction = false;
|
||||
updateActions();
|
||||
|
||||
final _wallet = wallet;
|
||||
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
@@ -229,6 +232,24 @@ abstract class DashboardViewModelBase with Store {
|
||||
void furtherShowYatPopup(bool shouldShow) =>
|
||||
settingsStore.shouldShowYatPopup = shouldShow;
|
||||
|
||||
@observable
|
||||
bool isEnabledExchangeAction;
|
||||
|
||||
@observable
|
||||
bool hasExchangeAction;
|
||||
|
||||
@observable
|
||||
bool isEnabledBuyAction;
|
||||
|
||||
@observable
|
||||
bool hasBuyAction;
|
||||
|
||||
@observable
|
||||
bool isEnabledSellAction;
|
||||
|
||||
@observable
|
||||
bool hasSellAction;
|
||||
|
||||
ReactionDisposer _onMoneroAccountChangeReaction;
|
||||
|
||||
ReactionDisposer _onMoneroBalanceChangeReaction;
|
||||
@@ -251,6 +272,7 @@ abstract class DashboardViewModelBase with Store {
|
||||
name = wallet.name;
|
||||
isOutdatedElectrumWallet =
|
||||
wallet.type == WalletType.bitcoin && wallet.seed.split(' ').length < 24;
|
||||
updateActions();
|
||||
|
||||
if (wallet.type == WalletType.monero) {
|
||||
subname = monero.getCurrentAccount(wallet)?.label;
|
||||
@@ -313,4 +335,16 @@ abstract class DashboardViewModelBase with Store {
|
||||
balanceViewModel: balanceViewModel,
|
||||
settingsStore: appStore.settingsStore)));
|
||||
}
|
||||
|
||||
void updateActions() {
|
||||
isEnabledExchangeAction = wallet.type != WalletType.haven;
|
||||
hasExchangeAction = !isHaven;
|
||||
isEnabledBuyAction = wallet.type != WalletType.haven
|
||||
&& wallet.type != WalletType.monero;
|
||||
hasBuyAction = !isMoneroOnly && !isHaven;
|
||||
isEnabledSellAction = wallet.type != WalletType.haven
|
||||
&& wallet.type != WalletType.monero
|
||||
&& wallet.type != WalletType.litecoin;
|
||||
hasSellAction = !isMoneroOnly && !isHaven;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/transaction_info.dart';
|
||||
import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/utils/mobx.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/action_list_item.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
||||
import 'package:cake_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
import 'package:cw_core/keyable.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_haven/haven_transaction_info.dart';
|
||||
|
||||
class TransactionListItem extends ActionListItem with Keyable {
|
||||
TransactionListItem(
|
||||
@@ -35,21 +38,33 @@ class TransactionListItem extends ActionListItem with Keyable {
|
||||
}
|
||||
|
||||
String get formattedFiatAmount {
|
||||
if (balanceViewModel.wallet.type == WalletType.monero) {
|
||||
final amount = calculateFiatAmountRaw(
|
||||
var amount = '';
|
||||
|
||||
switch(balanceViewModel.wallet.type) {
|
||||
case WalletType.monero:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: monero.formatterMoneroAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
transaction.changeFiatAmount(amount);
|
||||
}
|
||||
|
||||
if (balanceViewModel.wallet.type == WalletType.bitcoin
|
||||
|| balanceViewModel.wallet.type == WalletType.litecoin) {
|
||||
final amount = calculateFiatAmountRaw(
|
||||
break;
|
||||
case WalletType.bitcoin:
|
||||
case WalletType.litecoin:
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: bitcoin.formatterBitcoinAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
transaction.changeFiatAmount(amount);
|
||||
break;
|
||||
case WalletType.haven:
|
||||
final tx = transaction as HavenTransactionInfo;
|
||||
final asset = CryptoCurrency.fromString(tx.assetType);
|
||||
final price = balanceViewModel.fiatConvertationStore.prices[asset];
|
||||
amount = calculateFiatAmountRaw(
|
||||
cryptoAmount: haven.formatterMoneroAmountToDouble(amount: transaction.amount),
|
||||
price: price);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
transaction.changeFiatAmount(amount);
|
||||
return displayMode == BalanceDisplayMode.hiddenBalance
|
||||
? '---'
|
||||
: fiatCurrency.title + ' ' + transaction.fiatAmount();
|
||||
|
||||
@@ -338,7 +338,7 @@ abstract class ExchangeViewModelBase with Store {
|
||||
@action
|
||||
void calculateDepositAllAmount() {
|
||||
if (wallet.type == WalletType.bitcoin) {
|
||||
final availableBalance = wallet.balance.available;
|
||||
final availableBalance = wallet.balance[wallet.currency].available;
|
||||
final priority = _settingsStore.priority[wallet.type];
|
||||
final fee = wallet.calculateEstimatedFee(priority, null);
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cake_wallet/core/execution_state.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
||||
|
||||
part 'monero_account_edit_or_create_view_model.g.dart';
|
||||
@@ -11,7 +13,7 @@ class MoneroAccountEditOrCreateViewModel = MoneroAccountEditOrCreateViewModelBas
|
||||
with _$MoneroAccountEditOrCreateViewModel;
|
||||
|
||||
abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList,
|
||||
MoneroAccountEditOrCreateViewModelBase(this._moneroAccountList, this._havenAccountList,
|
||||
{@required WalletBase wallet, AccountListItem accountListItem})
|
||||
: state = InitialExecutionState(),
|
||||
isEdit = accountListItem != null,
|
||||
@@ -28,10 +30,21 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||
String label;
|
||||
|
||||
final MoneroAccountList _moneroAccountList;
|
||||
final HavenAccountList _havenAccountList;
|
||||
final AccountListItem _accountListItem;
|
||||
final WalletBase _wallet;
|
||||
|
||||
Future<void> save() async {
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
await saveMonero();
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.haven) {
|
||||
await saveHaven();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> saveMonero() async {
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
|
||||
@@ -52,4 +65,30 @@ abstract class MoneroAccountEditOrCreateViewModelBase with Store {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> saveHaven() async {
|
||||
if (!(_wallet.type == WalletType.haven)) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
state = IsExecutingState();
|
||||
|
||||
if (_accountListItem != null) {
|
||||
await _havenAccountList.setLabelAccount(
|
||||
_wallet,
|
||||
accountIndex: _accountListItem.id,
|
||||
label: label);
|
||||
} else {
|
||||
await _havenAccountList.addAccount(
|
||||
_wallet,
|
||||
label: label);
|
||||
}
|
||||
|
||||
await _wallet.save();
|
||||
state = ExecutedSuccessfullyState();
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/view_model/monero_account_list/account_list_item.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'monero_account_list_view_model.g.dart';
|
||||
|
||||
@@ -20,20 +22,43 @@ abstract class MoneroAccountListViewModelBase with Store {
|
||||
}
|
||||
|
||||
@computed
|
||||
List<AccountListItem> get accounts => monero
|
||||
.getAccountList(_wallet)
|
||||
.accounts.map((acc) => AccountListItem(
|
||||
label: acc.label,
|
||||
id: acc.id,
|
||||
isSelected: acc.id == monero.getCurrentAccount(_wallet).id))
|
||||
.toList();
|
||||
List<AccountListItem> get accounts {
|
||||
if (_wallet.type == WalletType.haven) {
|
||||
return haven
|
||||
.getAccountList(_wallet)
|
||||
.accounts.map((acc) => AccountListItem(
|
||||
label: acc.label,
|
||||
id: acc.id,
|
||||
isSelected: acc.id == haven.getCurrentAccount(_wallet).id))
|
||||
.toList();
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
return monero
|
||||
.getAccountList(_wallet)
|
||||
.accounts.map((acc) => AccountListItem(
|
||||
label: acc.label,
|
||||
id: acc.id,
|
||||
isSelected: acc.id == monero.getCurrentAccount(_wallet).id))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
final WalletBase _wallet;
|
||||
|
||||
void select(AccountListItem item) =>
|
||||
void select(AccountListItem item) {
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
monero.setCurrentAccount(
|
||||
_wallet,
|
||||
Account(
|
||||
id: item.id,
|
||||
label: item.label));
|
||||
item.id,
|
||||
item.label);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.haven) {
|
||||
haven.setCurrentAccount(
|
||||
_wallet,
|
||||
item.id,
|
||||
item.label);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ abstract class NodeCreateOrEditViewModelBase with Store {
|
||||
bool get isReady =>
|
||||
(address?.isNotEmpty ?? false) && (port?.isNotEmpty ?? false);
|
||||
|
||||
bool get hasAuthCredentials => _wallet.type == WalletType.monero;
|
||||
bool get hasAuthCredentials => _wallet.type == WalletType.monero ||
|
||||
_wallet.type == WalletType.haven;
|
||||
|
||||
String get uri {
|
||||
var uri = address;
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/calculate_fiat_amount_raw.dart';
|
||||
import 'package:cake_wallet/entities/parse_address_from_domain.dart';
|
||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/src/screens/send/widgets/extract_address_from_parsed.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
@@ -22,7 +24,7 @@ const String cryptoNumberPattern = '0.0';
|
||||
class Output = OutputBase with _$Output;
|
||||
|
||||
abstract class OutputBase with Store {
|
||||
OutputBase(this._wallet, this._settingsStore, this._fiatConversationStore)
|
||||
OutputBase(this._wallet, this._settingsStore, this._fiatConversationStore, this.cryptoCurrencyHandler)
|
||||
: _cryptoNumberFormat = NumberFormat(cryptoNumberPattern) {
|
||||
reset();
|
||||
_setCryptoNumMaximumFractionDigits();
|
||||
@@ -77,6 +79,9 @@ abstract class OutputBase with Store {
|
||||
_amount =
|
||||
bitcoin.formatterStringDoubleToBitcoinAmount(_cryptoAmount);
|
||||
break;
|
||||
case WalletType.haven:
|
||||
_amount = haven.formatterMoneroParseAmount(amount: _cryptoAmount);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -106,6 +111,10 @@ abstract class OutputBase with Store {
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
return monero.formatterMoneroAmountToDouble(amount: fee);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.haven) {
|
||||
return haven.formatterMoneroAmountToDouble(amount: fee);
|
||||
}
|
||||
} catch (e) {
|
||||
print(e.toString());
|
||||
}
|
||||
@@ -117,7 +126,7 @@ abstract class OutputBase with Store {
|
||||
String get estimatedFeeFiatAmount {
|
||||
try {
|
||||
final fiat = calculateFiatAmountRaw(
|
||||
price: _fiatConversationStore.prices[_wallet.currency],
|
||||
price: _fiatConversationStore.prices[cryptoCurrencyHandler()],
|
||||
cryptoAmount: estimatedFee);
|
||||
return fiat;
|
||||
} catch (_) {
|
||||
@@ -126,6 +135,7 @@ abstract class OutputBase with Store {
|
||||
}
|
||||
|
||||
WalletType get walletType => _wallet.type;
|
||||
final CryptoCurrency Function() cryptoCurrencyHandler;
|
||||
final WalletBase _wallet;
|
||||
final SettingsStore _settingsStore;
|
||||
final FiatConversionStore _fiatConversationStore;
|
||||
@@ -169,7 +179,7 @@ abstract class OutputBase with Store {
|
||||
void _updateFiatAmount() {
|
||||
try {
|
||||
final fiat = calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[_wallet.currency],
|
||||
price: _fiatConversationStore.prices[cryptoCurrencyHandler()],
|
||||
cryptoAmount: cryptoAmount.replaceAll(',', '.'));
|
||||
if (fiatAmount != fiat) {
|
||||
fiatAmount = fiat;
|
||||
@@ -183,7 +193,7 @@ abstract class OutputBase with Store {
|
||||
void _updateCryptoAmount() {
|
||||
try {
|
||||
final crypto = double.parse(fiatAmount.replaceAll(',', '.')) /
|
||||
_fiatConversationStore.prices[_wallet.currency];
|
||||
_fiatConversationStore.prices[cryptoCurrencyHandler()];
|
||||
final cryptoAmountTmp = _cryptoNumberFormat.format(crypto);
|
||||
|
||||
if (cryptoAmount != cryptoAmountTmp) {
|
||||
@@ -207,6 +217,9 @@ abstract class OutputBase with Store {
|
||||
case WalletType.litecoin:
|
||||
maximumFractionDigits = 8;
|
||||
break;
|
||||
case WalletType.haven:
|
||||
maximumFractionDigits = 12;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -216,7 +229,7 @@ abstract class OutputBase with Store {
|
||||
|
||||
Future<void> fetchParsedAddress(BuildContext context) async {
|
||||
final domain = address;
|
||||
final ticker = _wallet.currency.title.toLowerCase();
|
||||
final ticker = cryptoCurrencyHandler().title.toLowerCase();
|
||||
parsedAddress = await getIt.get<AddressResolver>().resolve(domain, ticker);
|
||||
extractedAddress = await extractAddressFromParsed(context, parsedAddress);
|
||||
note = parsedAddress.description;
|
||||
|
||||
@@ -21,7 +21,7 @@ abstract class SendTemplateViewModelBase with Store {
|
||||
SendTemplateViewModelBase(this._wallet, this._settingsStore,
|
||||
this._sendTemplateStore, this._fiatConversationStore) {
|
||||
|
||||
output = Output(_wallet, _settingsStore, _fiatConversationStore);
|
||||
output = Output(_wallet, _settingsStore, _fiatConversationStore, () => currency);
|
||||
}
|
||||
|
||||
Output output;
|
||||
|
||||
@@ -24,6 +24,7 @@ import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/view_model/send/send_view_model_state.dart';
|
||||
import 'package:cake_wallet/entities/parsed_address.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'send_view_model.g.dart';
|
||||
|
||||
@@ -39,13 +40,15 @@ abstract class SendViewModelBase with Store {
|
||||
: state = InitialExecutionState() {
|
||||
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));
|
||||
..add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
|
||||
}
|
||||
|
||||
@observable
|
||||
@@ -55,7 +58,7 @@ abstract class SendViewModelBase with Store {
|
||||
|
||||
@action
|
||||
void addOutput() {
|
||||
outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore));
|
||||
outputs.add(Output(_wallet, _settingsStore, _fiatConversationStore, () => selectedCryptoCurrency));
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -79,7 +82,7 @@ abstract class SendViewModelBase with Store {
|
||||
try {
|
||||
if (pendingTransaction != null) {
|
||||
final fiat = calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[_wallet.currency],
|
||||
price: _fiatConversationStore.prices[selectedCryptoCurrency],
|
||||
cryptoAmount: pendingTransaction.amountFormatted);
|
||||
return fiat;
|
||||
} else {
|
||||
@@ -95,7 +98,7 @@ abstract class SendViewModelBase with Store {
|
||||
try {
|
||||
if (pendingTransaction != null) {
|
||||
final fiat = calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[_wallet.currency],
|
||||
price: _fiatConversationStore.prices[selectedCryptoCurrency],
|
||||
cryptoAmount: pendingTransaction.feeFormatted);
|
||||
return fiat;
|
||||
} else {
|
||||
@@ -117,7 +120,7 @@ abstract class SendViewModelBase with Store {
|
||||
|
||||
Validator get allAmountValidator => AllAmountValidator();
|
||||
|
||||
Validator get addressValidator => AddressValidator(type: _wallet.currency);
|
||||
Validator get addressValidator => AddressValidator(type: selectedCryptoCurrency);
|
||||
|
||||
Validator get textValidator => TextValidator();
|
||||
|
||||
@@ -125,12 +128,7 @@ abstract class SendViewModelBase with Store {
|
||||
PendingTransaction pendingTransaction;
|
||||
|
||||
@computed
|
||||
String get balance {
|
||||
if(_settingsStore.balanceDisplayMode == BalanceDisplayMode.hiddenBalance){
|
||||
return '---';
|
||||
}
|
||||
return _wallet.balance.formattedAvailableBalance ?? '0.0' ;
|
||||
}
|
||||
String get balance => _wallet.balance[selectedCryptoCurrency].formattedAvailableBalance ?? '0.0';
|
||||
|
||||
@computed
|
||||
bool get isReadyForSend => _wallet.syncStatus is SyncedSyncStatus;
|
||||
@@ -144,11 +142,21 @@ abstract class SendViewModelBase with Store {
|
||||
bool get isElectrumWallet =>
|
||||
_wallet.type == WalletType.bitcoin || _wallet.type == WalletType.litecoin;
|
||||
|
||||
@observable
|
||||
CryptoCurrency selectedCryptoCurrency;
|
||||
|
||||
List<CryptoCurrency> currencies;
|
||||
|
||||
bool get hasMultiRecipient => _wallet.type != WalletType.haven;
|
||||
|
||||
bool get hasYat => outputs.any((out) =>
|
||||
out.isParsedAddress &&
|
||||
out.parsedAddress.parseFrom == ParseFrom.yatRecord);
|
||||
|
||||
WalletType get walletType => _wallet.type;
|
||||
|
||||
bool get hasCurrecyChanger => walletType == WalletType.haven;
|
||||
|
||||
final WalletBase _wallet;
|
||||
final SettingsStore _settingsStore;
|
||||
final SendTemplateViewModel sendTemplateViewModel;
|
||||
@@ -221,6 +229,11 @@ abstract class SendViewModelBase with Store {
|
||||
|
||||
return monero.createMoneroTransactionCreationCredentials(
|
||||
outputs: outputs, priority: priority);
|
||||
case WalletType.haven:
|
||||
final priority = _settingsStore.priority[_wallet.type];
|
||||
|
||||
return haven.createHavenTransactionCreationCredentials(
|
||||
outputs: outputs, priority: priority, assetType: selectedCryptoCurrency.title);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:cake_wallet/entities/balance_display_mode.dart';
|
||||
import 'package:cake_wallet/entities/fiat_currency.dart';
|
||||
import 'package:cw_core/node.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cake_wallet/entities/action_list_display_mode.dart';
|
||||
import 'package:cake_wallet/view_model/settings/version_list_item.dart';
|
||||
import 'package:cake_wallet/view_model/settings/picker_list_item.dart';
|
||||
@@ -29,6 +30,7 @@ import 'package:cw_core/transaction_priority.dart';
|
||||
import 'package:cake_wallet/themes/theme_base.dart';
|
||||
import 'package:cake_wallet/themes/theme_list.dart';
|
||||
import 'package:cake_wallet/src/screens/pin_code/pin_code_widget.dart';
|
||||
import 'package:cake_wallet/wallet_type_utils.dart';
|
||||
|
||||
part 'settings_view_model.g.dart';
|
||||
|
||||
@@ -42,6 +44,8 @@ List<TransactionPriority> priorityForWalletType(WalletType type) {
|
||||
return bitcoin.getTransactionPriorities();
|
||||
case WalletType.litecoin:
|
||||
return bitcoin.getLitecoinTransactionPriorities();
|
||||
case WalletType.haven:
|
||||
return haven.getTransactionPriorities();
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
@@ -101,12 +105,13 @@ abstract class SettingsViewModelBase with Store {
|
||||
selectedItem: () => balanceDisplayMode,
|
||||
onItemSelected: (BalanceDisplayMode mode) =>
|
||||
_settingsStore.balanceDisplayMode = mode),
|
||||
PickerListItem(
|
||||
title: S.current.settings_currency,
|
||||
items: FiatCurrency.all,
|
||||
selectedItem: () => fiatCurrency,
|
||||
onItemSelected: (FiatCurrency currency) =>
|
||||
setFiatCurrency(currency)),
|
||||
if (!isHaven)
|
||||
PickerListItem(
|
||||
title: S.current.settings_currency,
|
||||
items: FiatCurrency.all,
|
||||
selectedItem: () => fiatCurrency,
|
||||
onItemSelected: (FiatCurrency currency) =>
|
||||
setFiatCurrency(currency)),
|
||||
PickerListItem(
|
||||
title: S.current.settings_fee_priority,
|
||||
items: priorityForWalletType(wallet.type),
|
||||
|
||||
@@ -14,6 +14,7 @@ import 'package:cake_wallet/store/settings_store.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'transaction_details_view_model.g.dart';
|
||||
|
||||
@@ -100,6 +101,23 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
items.addAll(_items);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
items.addAll([
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_transaction_id, value: tx.id),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_date,
|
||||
value: dateFormat.format(tx.date)),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_height, value: '${tx.height}'),
|
||||
StandartListItem(
|
||||
title: S.current.transaction_details_amount,
|
||||
value: tx.amountFormatted()),
|
||||
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)
|
||||
@@ -154,6 +172,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return 'https://www.blockchain.com/btc/tx/${txId}';
|
||||
case WalletType.litecoin:
|
||||
return 'https://blockchair.com/litecoin/transaction/${txId}';
|
||||
case WalletType.haven:
|
||||
return 'https://explorer.havenprotocol.org/search?value=${txId}';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
@@ -167,6 +187,8 @@ abstract class TransactionDetailsViewModelBase with Store {
|
||||
return 'View Transaction on Blockchain.com';
|
||||
case WalletType.litecoin:
|
||||
return 'View Transaction on Blockchair.com';
|
||||
case WalletType.haven:
|
||||
return 'View Transaction on explorer.havenprotocol.org';
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
|
||||
part 'wallet_address_edit_or_create_view_model.g.dart';
|
||||
@@ -78,6 +79,16 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
await haven
|
||||
.getSubaddressList(wallet)
|
||||
.addSubaddress(
|
||||
wallet,
|
||||
accountIndex: haven.getCurrentAccount(wallet).id,
|
||||
label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _update() async {
|
||||
@@ -98,5 +109,16 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
|
||||
label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
await haven
|
||||
.getSubaddressList(wallet)
|
||||
.setLabelSubaddress(
|
||||
wallet,
|
||||
accountIndex: haven.getCurrentAccount(wallet).id,
|
||||
addressIndex: _item.id as int,
|
||||
label: label);
|
||||
await wallet.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/store/app_store.dart';
|
||||
import 'dart:async';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'wallet_address_list_view_model.g.dart';
|
||||
|
||||
@@ -44,6 +45,22 @@ class MoneroURI extends PaymentURI {
|
||||
}
|
||||
}
|
||||
|
||||
class HavenURI extends PaymentURI {
|
||||
HavenURI({String amount, String address})
|
||||
: super(amount: amount, address: address);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
var base = 'haven:' + address;
|
||||
|
||||
if (amount?.isNotEmpty ?? false) {
|
||||
base += '?tx_amount=${amount.replaceAll(',', '.')}';
|
||||
}
|
||||
|
||||
return base;
|
||||
}
|
||||
}
|
||||
|
||||
class BitcoinURI extends PaymentURI {
|
||||
BitcoinURI({String amount, String address})
|
||||
: super(amount: amount, address: address);
|
||||
@@ -83,30 +100,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
}) {
|
||||
_appStore = appStore;
|
||||
_wallet = _appStore.wallet;
|
||||
emoji = '';
|
||||
hasAccounts = _wallet?.type == WalletType.monero;
|
||||
reaction((_) => _wallet.walletAddresses.address, (String address) {
|
||||
if (address == _wallet.walletInfo.yatLastUsedAddress) {
|
||||
emoji = yatStore.emoji;
|
||||
} else {
|
||||
emoji = '';
|
||||
}
|
||||
});
|
||||
|
||||
//reaction((_) => yatStore.emoji, (String emojiId) => this.emoji = emojiId);
|
||||
|
||||
//_onLastUsedYatAddressSubscription =
|
||||
// _wallet.walletInfo.yatLastUsedAddressStream.listen((String yatAddress) {
|
||||
// if (yatAddress == _wallet.walletAddresses.address) {
|
||||
// emoji = yatStore.emoji;
|
||||
// } else {
|
||||
// emoji = '';
|
||||
// }
|
||||
//});
|
||||
|
||||
if (_wallet.walletAddresses.address == _wallet.walletInfo.yatLastUsedAddress) {
|
||||
emoji = yatStore.emoji;
|
||||
}
|
||||
hasAccounts = _wallet?.type == WalletType.monero || _wallet?.type == WalletType.haven;
|
||||
|
||||
_onWalletChangeReaction = reaction((_) => _appStore.wallet, (WalletBase<
|
||||
Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
|
||||
@@ -133,6 +127,10 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
return MoneroURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.haven) {
|
||||
return HavenURI(amount: amount, address: address.address);
|
||||
}
|
||||
|
||||
if (_wallet.type == WalletType.bitcoin) {
|
||||
return BitcoinURI(amount: amount, address: address.address);
|
||||
}
|
||||
@@ -170,6 +168,23 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
addressList.addAll(addressItems);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
final primaryAddress = haven.getSubaddressList(wallet).subaddresses.first;
|
||||
final addressItems = haven
|
||||
.getSubaddressList(wallet)
|
||||
.subaddresses
|
||||
.map((subaddress) {
|
||||
final isPrimary = subaddress == primaryAddress;
|
||||
|
||||
return WalletAddressListItem(
|
||||
id: subaddress.id,
|
||||
isPrimary: isPrimary,
|
||||
name: subaddress.label,
|
||||
address: subaddress.address);
|
||||
});
|
||||
addressList.addAll(addressItems);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.bitcoin) {
|
||||
final primaryAddress = bitcoin.getAddress(wallet);
|
||||
final bitcoinAddresses = bitcoin.getAddresses(wallet).map((addr) {
|
||||
@@ -195,14 +210,15 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
return monero.getCurrentAccount(wallet).label;
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
return haven.getCurrentAccount(wallet).label;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@computed
|
||||
bool get hasAddressList => _wallet.type == WalletType.monero;
|
||||
|
||||
@observable
|
||||
String emoji;
|
||||
bool get hasAddressList => _wallet.type == WalletType.monero || _wallet.type == WalletType.haven;
|
||||
|
||||
@observable
|
||||
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>
|
||||
@@ -216,9 +232,6 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
|
||||
ReactionDisposer _onWalletChangeReaction;
|
||||
|
||||
StreamSubscription<String> _onLastUsedYatAddressSubscription;
|
||||
StreamSubscription<String> _onEmojiIdChangeSubscription;
|
||||
|
||||
@action
|
||||
void setAddress(WalletAddressListItem address) =>
|
||||
_wallet.walletAddresses.address = address.address;
|
||||
@@ -226,7 +239,7 @@ abstract class WalletAddressListViewModelBase with Store {
|
||||
void _init() {
|
||||
_baseItems = [];
|
||||
|
||||
if (_wallet.type == WalletType.monero) {
|
||||
if (_wallet.type == WalletType.monero || _wallet.type == WalletType.haven) {
|
||||
_baseItems.add(WalletAccountListHeader());
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'package:cw_core/wallet_base.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/src/screens/transaction_details/standart_list_item.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'wallet_keys_view_model.g.dart';
|
||||
|
||||
@@ -29,6 +30,22 @@ abstract class WalletKeysViewModelBase with Store {
|
||||
]);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.haven) {
|
||||
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']),
|
||||
StandartListItem(title: S.current.wallet_seed, value: wallet.seed),
|
||||
]);
|
||||
}
|
||||
|
||||
if (wallet.type == WalletType.bitcoin || wallet.type == WalletType.litecoin) {
|
||||
final keys = bitcoin.getWalletKeys(wallet);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class WalletListViewModel = WalletListViewModelBase with _$WalletListViewModel;
|
||||
|
||||
abstract class WalletListViewModelBase with Store {
|
||||
WalletListViewModelBase(this._walletInfoSource, this._appStore,
|
||||
this._keyService, this.walletNewVM) {
|
||||
this._keyService) {
|
||||
wallets = ObservableList<WalletListItem>();
|
||||
_updateList();
|
||||
}
|
||||
@@ -27,7 +27,6 @@ abstract class WalletListViewModelBase with Store {
|
||||
final AppStore _appStore;
|
||||
final Box<WalletInfo> _walletInfoSource;
|
||||
final KeyService _keyService;
|
||||
final WalletNewVM walletNewVM;
|
||||
|
||||
WalletType get currentWalletType => _appStore.wallet.type;
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
|
||||
import 'package:cake_wallet/bitcoin/bitcoin.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'wallet_new_vm.g.dart';
|
||||
|
||||
@@ -25,7 +26,7 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
@observable
|
||||
String selectedMnemonicLanguage;
|
||||
|
||||
bool get hasLanguageSelector => type == WalletType.monero;
|
||||
bool get hasLanguageSelector => type == WalletType.monero || type == WalletType.haven;
|
||||
|
||||
final WalletCreationService _walletCreationService;
|
||||
|
||||
@@ -39,6 +40,9 @@ abstract class WalletNewVMBase extends WalletCreationVM with Store {
|
||||
return bitcoin.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.litecoin:
|
||||
return bitcoin.createBitcoinNewWalletCredentials(name: name);
|
||||
case WalletType.haven:
|
||||
return haven.createHavenNewWalletCredentials(
|
||||
name: name, language: options as String);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cw_core/wallet_info.dart';
|
||||
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
|
||||
import 'package:cake_wallet/monero/monero.dart';
|
||||
import 'package:cake_wallet/haven/haven.dart';
|
||||
|
||||
part 'wallet_restore_view_model.g.dart';
|
||||
|
||||
@@ -24,11 +25,11 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
WalletRestoreViewModelBase(AppStore appStore, this._walletCreationService,
|
||||
Box<WalletInfo> walletInfoSource,
|
||||
{@required WalletType type})
|
||||
: availableModes = type == WalletType.monero
|
||||
: availableModes = (type == WalletType.monero || type == WalletType.haven)
|
||||
? WalletRestoreMode.values
|
||||
: [WalletRestoreMode.seed],
|
||||
hasSeedLanguageSelector = type == WalletType.monero,
|
||||
hasBlockchainHeightLanguageSelector = type == WalletType.monero,
|
||||
hasSeedLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||
hasBlockchainHeightLanguageSelector = type == WalletType.monero || type == WalletType.haven,
|
||||
super(appStore, walletInfoSource, type: type, isRecovery: true) {
|
||||
isButtonEnabled =
|
||||
!hasSeedLanguageSelector && !hasBlockchainHeightLanguageSelector;
|
||||
@@ -64,7 +65,7 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
case WalletType.monero:
|
||||
return monero.createMoneroRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
height: height ?? 0,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
case WalletType.bitcoin:
|
||||
@@ -77,6 +78,12 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
name: name,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
case WalletType.haven:
|
||||
return haven.createHavenRestoreWalletFromSeedCredentials(
|
||||
name: name,
|
||||
height: height ?? 0,
|
||||
mnemonic: seed,
|
||||
password: password);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -87,14 +94,27 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store {
|
||||
final spendKey = options['spendKey'] as String;
|
||||
final address = options['address'] as String;
|
||||
|
||||
return monero.createMoneroRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
spendKey: spendKey,
|
||||
viewKey: viewKey,
|
||||
address: address,
|
||||
password: password,
|
||||
language: 'English');
|
||||
if (type == WalletType.monero) {
|
||||
return monero.createMoneroRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
spendKey: spendKey,
|
||||
viewKey: viewKey,
|
||||
address: address,
|
||||
password: password,
|
||||
language: 'English');
|
||||
}
|
||||
|
||||
if (type == WalletType.haven) {
|
||||
return haven.createHavenRestoreWalletFromKeysCredentials(
|
||||
name: name,
|
||||
height: height,
|
||||
spendKey: spendKey,
|
||||
viewKey: viewKey,
|
||||
address: address,
|
||||
password: password,
|
||||
language: 'English');
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -2,12 +2,28 @@ import 'package:cw_core/wallet_type.dart';
|
||||
import 'package:cake_wallet/wallet_types.g.dart';
|
||||
|
||||
bool get isMoneroOnly {
|
||||
return availableWalletTypes.length == 1
|
||||
&& availableWalletTypes.first == WalletType.monero;
|
||||
return availableWalletTypes.length == 1
|
||||
&& availableWalletTypes.first == WalletType.monero;
|
||||
}
|
||||
|
||||
bool get isHaven {
|
||||
return availableWalletTypes.length == 1
|
||||
&& availableWalletTypes.first == WalletType.haven;
|
||||
}
|
||||
|
||||
|
||||
bool get isSingleCoin {
|
||||
return availableWalletTypes.length == 1;
|
||||
}
|
||||
|
||||
String get approximatedAppName {
|
||||
return isMoneroOnly
|
||||
? 'Monero.com'
|
||||
: 'Cake Wallet';
|
||||
if (isMoneroOnly) {
|
||||
return 'Monero.com';
|
||||
}
|
||||
|
||||
if (isHaven) {
|
||||
return 'Haven';
|
||||
}
|
||||
|
||||
return 'Cake Wallet';
|
||||
}
|
||||
Reference in New Issue
Block a user