Merge redesign part 7.

This commit is contained in:
M 2020-09-15 23:35:49 +03:00
parent d67ab4934d
commit 95917b2cdb
31 changed files with 373 additions and 267 deletions

View file

@ -1,5 +1,3 @@
include: package:pedantic/analysis_options.yaml
analyzer: analyzer:
strong-mode: strong-mode:
implicit-casts: false implicit-casts: false

View file

@ -180,7 +180,7 @@ extern "C"
void change_current_wallet(Monero::Wallet *wallet) void change_current_wallet(Monero::Wallet *wallet)
{ {
m_wallet = wallet; m_wallet = wallet;
// m_listener = nullptr; m_listener = nullptr;
if (wallet != nullptr) if (wallet != nullptr)
@ -553,7 +553,7 @@ extern "C"
if (m_listener != nullptr) if (m_listener != nullptr)
{ {
free(m_listener); // free(m_listener);
} }
m_listener = new MoneroWalletListener(); m_listener = new MoneroWalletListener();

View file

@ -254,12 +254,12 @@ class SyncListner {
onNewBlock(syncHeight, left, ptc); onNewBlock(syncHeight, left, ptc);
} }
if (newTransactionExist && onNewTransaction != null) { if (newTransactionExist) {
onNewTransaction(); onNewTransaction?.call();
} }
if (needToRefresh && onNeedToRefresh != null) { if (needToRefresh) {
onNeedToRefresh(); onNeedToRefresh?.call();
} }
}); });
} }

View file

@ -3,6 +3,13 @@ PODS:
- Flutter - Flutter
- MTBBarcodeScanner - MTBBarcodeScanner
- SwiftProtobuf - SwiftProtobuf
- connectivity (0.0.1):
- Flutter
- Reachability
- connectivity_for_web (0.1.0):
- Flutter
- connectivity_macos (0.0.1):
- Flutter
- cw_monero (0.0.2): - cw_monero (0.0.2):
- cw_monero/Boost (= 0.0.2) - cw_monero/Boost (= 0.0.2)
- cw_monero/lmdb (= 0.0.2) - cw_monero/lmdb (= 0.0.2)
@ -40,6 +47,7 @@ PODS:
- Flutter - Flutter
- path_provider_macos (0.0.1): - path_provider_macos (0.0.1):
- Flutter - Flutter
- Reachability (3.2)
- share (0.0.1): - share (0.0.1):
- Flutter - Flutter
- shared_preferences (0.0.1): - shared_preferences (0.0.1):
@ -62,6 +70,9 @@ PODS:
DEPENDENCIES: DEPENDENCIES:
- barcode_scan (from `.symlinks/plugins/barcode_scan/ios`) - barcode_scan (from `.symlinks/plugins/barcode_scan/ios`)
- connectivity (from `.symlinks/plugins/connectivity/ios`)
- connectivity_for_web (from `.symlinks/plugins/connectivity_for_web/ios`)
- connectivity_macos (from `.symlinks/plugins/connectivity_macos/ios`)
- cw_monero (from `.symlinks/plugins/cw_monero/ios`) - cw_monero (from `.symlinks/plugins/cw_monero/ios`)
- devicelocale (from `.symlinks/plugins/devicelocale/ios`) - devicelocale (from `.symlinks/plugins/devicelocale/ios`)
- esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`) - esys_flutter_share (from `.symlinks/plugins/esys_flutter_share/ios`)
@ -86,11 +97,18 @@ DEPENDENCIES:
SPEC REPOS: SPEC REPOS:
trunk: trunk:
- MTBBarcodeScanner - MTBBarcodeScanner
- Reachability
- SwiftProtobuf - SwiftProtobuf
EXTERNAL SOURCES: EXTERNAL SOURCES:
barcode_scan: barcode_scan:
:path: ".symlinks/plugins/barcode_scan/ios" :path: ".symlinks/plugins/barcode_scan/ios"
connectivity:
:path: ".symlinks/plugins/connectivity/ios"
connectivity_for_web:
:path: ".symlinks/plugins/connectivity_for_web/ios"
connectivity_macos:
:path: ".symlinks/plugins/connectivity_macos/ios"
cw_monero: cw_monero:
:path: ".symlinks/plugins/cw_monero/ios" :path: ".symlinks/plugins/cw_monero/ios"
devicelocale: devicelocale:
@ -134,6 +152,9 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479 barcode_scan: a5c27959edfafaa0c771905bad0b29d6d39e4479
connectivity: c4130b2985d4ef6fd26f9702e886bd5260681467
connectivity_for_web: 2b8584556930d4bd490d82b836bcf45067ce345b
connectivity_macos: e2e9731b6b22dda39eb1b128f6969d574460e191
cw_monero: 2e1f79929880cc2293b5bc1b25e28152e4d84649 cw_monero: 2e1f79929880cc2293b5bc1b25e28152e4d84649
devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00 devicelocale: feebbe5e7a30adb8c4f83185de1b50ff19b44f00
esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4 esys_flutter_share: 403498dab005b36ce1f8d7aff377e81f0621b0b4
@ -146,6 +167,7 @@ SPEC CHECKSUMS:
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0 path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
Reachability: 33e18b67625424e47b6cde6d202dce689ad7af96
share: 0b2c3e82132f5888bccca3351c504d0003b3b410 share: 0b2c3e82132f5888bccca3351c504d0003b3b410
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78 shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78

View file

@ -275,8 +275,10 @@
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../Flutter/Flutter.framework", "${PODS_ROOT}/../Flutter/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework", "${BUILT_PRODUCTS_DIR}/MTBBarcodeScanner/MTBBarcodeScanner.framework",
"${BUILT_PRODUCTS_DIR}/Reachability/Reachability.framework",
"${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework", "${BUILT_PRODUCTS_DIR}/SwiftProtobuf/SwiftProtobuf.framework",
"${BUILT_PRODUCTS_DIR}/barcode_scan/barcode_scan.framework", "${BUILT_PRODUCTS_DIR}/barcode_scan/barcode_scan.framework",
"${BUILT_PRODUCTS_DIR}/connectivity/connectivity.framework",
"${BUILT_PRODUCTS_DIR}/cw_monero/cw_monero.framework", "${BUILT_PRODUCTS_DIR}/cw_monero/cw_monero.framework",
"${BUILT_PRODUCTS_DIR}/devicelocale/devicelocale.framework", "${BUILT_PRODUCTS_DIR}/devicelocale/devicelocale.framework",
"${BUILT_PRODUCTS_DIR}/esys_flutter_share/esys_flutter_share.framework", "${BUILT_PRODUCTS_DIR}/esys_flutter_share/esys_flutter_share.framework",
@ -293,8 +295,10 @@
outputPaths = ( outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MTBBarcodeScanner.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Reachability.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftProtobuf.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/barcode_scan.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/connectivity.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cw_monero.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/cw_monero.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/devicelocale.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/devicelocale.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/esys_flutter_share.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/esys_flutter_share.framework",

View file

@ -9,8 +9,6 @@ import 'package:cake_wallet/bitcoin/electrum.dart';
part 'bitcoin_transaction_history.g.dart'; part 'bitcoin_transaction_history.g.dart';
// TODO: Think about another transaction store for bitcoin transaction history..
const _transactionsHistoryFileName = 'transactions.json'; const _transactionsHistoryFileName = 'transactions.json';
class BitcoinTransactionHistory = BitcoinTransactionHistoryBase class BitcoinTransactionHistory = BitcoinTransactionHistoryBase

View file

@ -1,39 +1,29 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data';
import 'dart:convert'; import 'dart:convert';
import 'package:mobx/mobx.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:flutter/foundation.dart';
import 'package:rxdart/rxdart.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:cake_wallet/bitcoin/bitcoin_transaction_credentials.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cake_wallet/bitcoin/bitcoin_transaction_info.dart';
import 'package:cake_wallet/bitcoin/bitcoin_transaction_no_inputs_exception.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_no_inputs_exception.dart';
import 'package:cake_wallet/bitcoin/bitcoin_transaction_wrong_balance_exception.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_wrong_balance_exception.dart';
import 'package:cake_wallet/bitcoin/bitcoin_unspent.dart'; import 'package:cake_wallet/bitcoin/bitcoin_unspent.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_keys.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet_keys.dart';
import 'package:cake_wallet/bitcoin/electrum.dart';
import 'package:cake_wallet/bitcoin/pending_bitcoin_transaction.dart'; import 'package:cake_wallet/bitcoin/pending_bitcoin_transaction.dart';
import 'package:cake_wallet/bitcoin/script_hash.dart'; import 'package:cake_wallet/bitcoin/script_hash.dart';
import 'package:cake_wallet/bitcoin/utils.dart'; import 'package:cake_wallet/bitcoin/utils.dart';
import 'package:cake_wallet/src/domain/bitcoin/bitcoin_amount_format.dart'; import 'package:cake_wallet/src/domain/bitcoin/bitcoin_amount_format.dart';
import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
import 'package:cake_wallet/src/domain/common/sync_status.dart'; import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/src/domain/common/transaction_direction.dart';
import 'package:cake_wallet/src/domain/common/transaction_priority.dart'; import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
import 'package:cw_monero/transaction_history.dart'; import 'package:cake_wallet/src/domain/common/wallet_info.dart';
import 'package:flutter/cupertino.dart';
import 'package:mobx/mobx.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:flutter/foundation.dart';
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
import 'package:bitcoin_flutter/src/payments/index.dart' show PaymentData;
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/bitcoin/bitcoin_transaction_history.dart'; import 'package:cake_wallet/bitcoin/bitcoin_transaction_history.dart';
import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart'; import 'package:cake_wallet/bitcoin/bitcoin_address_record.dart';
import 'package:cake_wallet/bitcoin/file.dart'; import 'package:cake_wallet/bitcoin/file.dart';
import 'package:cake_wallet/bitcoin/electrum.dart';
import 'package:cake_wallet/bitcoin/bitcoin_balance.dart'; import 'package:cake_wallet/bitcoin/bitcoin_balance.dart';
import 'package:cake_wallet/src/domain/common/node.dart'; import 'package:cake_wallet/src/domain/common/node.dart';
import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/core/wallet_base.dart';
import 'package:rxdart/rxdart.dart';
import 'package:hex/hex.dart';
import 'package:cake_wallet/di.dart';
import 'package:shared_preferences/shared_preferences.dart';
part 'bitcoin_wallet.g.dart'; part 'bitcoin_wallet.g.dart';
@ -44,8 +34,8 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
{@required this.eclient, {@required this.eclient,
@required this.path, @required this.path,
@required String password, @required String password,
@required this.name, @required WalletInfo walletInfo,
List<BitcoinAddressRecord> initialAddresses, @required List<BitcoinAddressRecord> initialAddresses,
int accountIndex = 0, int accountIndex = 0,
this.transactionHistory, this.transactionHistory,
this.mnemonic, this.mnemonic,
@ -60,9 +50,7 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
syncStatus = NotConnectedSyncStatus(), syncStatus = NotConnectedSyncStatus(),
_password = password, _password = password,
_accountIndex = accountIndex, _accountIndex = accountIndex,
_addressesKeys = {} { super(walletInfo) {
type = WalletType.bitcoin;
currency = CryptoCurrency.btc;
_scripthashesUpdateSubject = {}; _scripthashesUpdateSubject = {};
} }
@ -114,7 +102,6 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
return BitcoinWallet._internal( return BitcoinWallet._internal(
eclient: eclient, eclient: eclient,
path: walletPath, path: walletPath,
name: name,
mnemonic: mnemonic, mnemonic: mnemonic,
password: password, password: password,
accountIndex: accountIndex, accountIndex: accountIndex,
@ -130,9 +117,6 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
final ElectrumClient eclient; final ElectrumClient eclient;
final String mnemonic; final String mnemonic;
@override
String name;
@override @override
@observable @observable
String address; String address;
@ -147,8 +131,6 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
ObservableList<BitcoinAddressRecord> addresses; ObservableList<BitcoinAddressRecord> addresses;
Map<String, bitcoin.ECPair> _addressesKeys;
List<String> get scriptHashes => List<String> get scriptHashes =>
addresses.map((addr) => scriptHash(addr.address)).toList(); addresses.map((addr) => scriptHash(addr.address)).toList();
@ -161,8 +143,8 @@ abstract class BitcoinWalletBase extends WalletBase<BitcoinBalance> with Store {
BitcoinWalletKeys get keys => BitcoinWalletKeys( BitcoinWalletKeys get keys => BitcoinWalletKeys(
wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey); wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey);
final String _password;
int _accountIndex; int _accountIndex;
String _password;
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject; Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
Future<void> init() async { Future<void> init() async {

View file

@ -1,5 +1,4 @@
import 'dart:io'; import 'dart:io';
import 'dart:convert';
import 'package:cake_wallet/bitcoin/key.dart'; import 'package:cake_wallet/bitcoin/key.dart';
import 'package:encrypt/encrypt.dart' as encrypt; import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
@ -28,8 +27,7 @@ Future<void> writeData(
f.writeAsStringSync(encrypted); f.writeAsStringSync(encrypted);
} }
Future<String> read( Future<String> read({@required String path, @required String password}) async {
{@required String path, @required String password}) async {
final file = File(path); final file = File(path);
if (!file.existsSync()) { if (!file.existsSync()) {

View file

@ -1,4 +1,3 @@
import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';

View file

@ -1,4 +1,5 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:cake_wallet/src/domain/common/wallet_info.dart';
import 'package:cake_wallet/core/pending_transaction.dart'; import 'package:cake_wallet/core/pending_transaction.dart';
import 'package:cake_wallet/core/transaction_history.dart'; import 'package:cake_wallet/core/transaction_history.dart';
import 'package:cake_wallet/src/domain/common/transaction_priority.dart'; import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
@ -7,18 +8,43 @@ import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/src/domain/common/node.dart'; import 'package:cake_wallet/src/domain/common/node.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart';
// FIXME: Move me.
CryptoCurrency currencyForWalletType(WalletType type) {
switch (type) {
case WalletType.bitcoin:
return CryptoCurrency.btc;
case WalletType.monero:
return CryptoCurrency.xmr;
default:
return null;
}
}
abstract class WalletBase<BalaceType> { abstract class WalletBase<BalaceType> {
WalletType type; WalletBase(this.walletInfo);
CryptoCurrency currency; static String idFor(String name, WalletType type) =>
walletTypeToString(type).toLowerCase() + '_' + name;
String get name; WalletInfo walletInfo;
String address; WalletType get type => walletInfo.type;
BalaceType balance; CryptoCurrency get currency => currencyForWalletType(type);
SyncStatus syncStatus; String get id => walletInfo.id;
String get name => walletInfo.name;
String get address;
set address(String address);
BalaceType get balance;
SyncStatus get syncStatus;
set syncStatus(SyncStatus status);
String get seed; String get seed;
@ -26,8 +52,6 @@ abstract class WalletBase<BalaceType> {
TransactionHistoryBase transactionHistory; TransactionHistoryBase transactionHistory;
String get id => walletTypeToString(type).toLowerCase() + '_' + name;
Future<void> connectToNode({@required Node node}); Future<void> connectToNode({@required Node node});
Future<void> startSync(); Future<void> startSync();

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/di.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -32,17 +33,7 @@ class WalletCreationService {
void changeWalletType({@required WalletType type}) { void changeWalletType({@required WalletType type}) {
this.type = type; this.type = type;
_service = getIt.get<WalletService>(param1: type);
switch (type) {
case WalletType.monero:
_service = MoneroWalletService();
break;
case WalletType.bitcoin:
_service = BitcoinWalletService();
break;
default:
break;
}
} }
Future<void> create(WalletCredentials credentials) async { Future<void> create(WalletCredentials credentials) async {

View file

@ -1,6 +1,10 @@
import 'package:cake_wallet/src/domain/common/wallet_info.dart';
abstract class WalletCredentials { abstract class WalletCredentials {
WalletCredentials({this.name, this.password}); WalletCredentials({this.name, this.password, this.height});
final String name; final String name;
final int height;
String password; String password;
WalletInfo walletInfo;
} }

View file

@ -1,7 +1,11 @@
import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart';
import 'package:cake_wallet/core/contact_service.dart'; import 'package:cake_wallet/core/contact_service.dart';
import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/monero/monero_wallet_service.dart';
import 'package:cake_wallet/src/domain/common/contact.dart'; import 'package:cake_wallet/src/domain/common/contact.dart';
import 'package:cake_wallet/src/domain/common/node.dart'; import 'package:cake_wallet/src/domain/common/node.dart';
import 'package:cake_wallet/src/domain/exchange/trade.dart'; import 'package:cake_wallet/src/domain/exchange/trade.dart';
// import 'package:cake_wallet/src/domain/services/wallet_service.dart';
import 'package:cake_wallet/src/screens/contact/contact_list_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_list_page.dart';
import 'package:cake_wallet/src/screens/contact/contact_page.dart'; import 'package:cake_wallet/src/screens/contact/contact_page.dart';
import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart'; import 'package:cake_wallet/src/screens/exchange_trade/exchange_confirm_page.dart';
@ -367,6 +371,22 @@ Future setup(
getIt.registerFactory( getIt.registerFactory(
() => ExchangeTemplatePage(getIt.get<ExchangeViewModel>())); () => ExchangeTemplatePage(getIt.get<ExchangeViewModel>()));
getIt.registerFactory(() => MoneroWalletService(walletInfoSource));
getIt.registerFactory(() => BitcoinWalletService());
getIt.registerFactoryParam<WalletService, WalletType, void>(
(WalletType param1, __) {
switch (param1) {
case WalletType.monero:
return getIt.get<MoneroWalletService>();
case WalletType.bitcoin:
return getIt.get<BitcoinWalletService>();
default:
return null;
}
});
} }
void setupThemeChangerStore(ThemeChanger themeChanger) { void setupThemeChangerStore(ThemeChanger themeChanger) {

View file

@ -251,6 +251,17 @@ class MaterialAppWithTheme extends StatelessWidget {
_settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
final statusBarIconBrightness = final statusBarIconBrightness =
_settingsStore.isDarkTheme ? Brightness.light : Brightness.dark; _settingsStore.isDarkTheme ? Brightness.light : Brightness.dark;
final authenticationStore = getIt.get<AuthenticationStore>();
String initialRoute;
switch (authenticationStore.state) {
case AuthenticationState.denied:
initialRoute = Routes.welcome;
break;
default:
initialRoute = Routes.login;
break;
}
SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle( SystemChrome.setSystemUIOverlayStyle(SystemUiOverlayStyle(
statusBarColor: statusBarColor, statusBarColor: statusBarColor,
@ -258,7 +269,7 @@ class MaterialAppWithTheme extends StatelessWidget {
statusBarIconBrightness: statusBarIconBrightness)); statusBarIconBrightness: statusBarIconBrightness));
return Root( return Root(
authenticationStore: getIt.get<AuthenticationStore>(), authenticationStore: authenticationStore,
child: MaterialApp( child: MaterialApp(
navigatorKey: navigatorKey, navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
@ -286,8 +297,7 @@ class MaterialAppWithTheme extends StatelessWidget {
nodes: nodes, nodes: nodes,
trades: trades, trades: trades,
transactionDescriptions: transactionDescriptions), transactionDescriptions: transactionDescriptions),
initialRoute: Routes.login, // FIXME: get initial route! initialRoute: initialRoute,
// home: Container(color: Colors.blue),
)); ));
} }
} }

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/src/domain/common/wallet_info.dart';
import 'package:cake_wallet/src/domain/monero/monero_transaction_creation_credentials.dart'; import 'package:cake_wallet/src/domain/monero/monero_transaction_creation_credentials.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
@ -9,36 +10,29 @@ import 'package:cake_wallet/monero/monero_transaction_history.dart';
import 'package:cake_wallet/monero/monero_subaddress_list.dart'; import 'package:cake_wallet/monero/monero_subaddress_list.dart';
import 'package:cake_wallet/monero/monero_account_list.dart'; import 'package:cake_wallet/monero/monero_account_list.dart';
import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/core/transaction_history.dart';
import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/src/domain/common/sync_status.dart'; import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/src/domain/monero/account.dart'; import 'package:cake_wallet/src/domain/monero/account.dart';
import 'package:cake_wallet/src/domain/monero/account_list.dart';
import 'package:cake_wallet/src/domain/monero/subaddress.dart'; import 'package:cake_wallet/src/domain/monero/subaddress.dart';
import 'package:cake_wallet/src/domain/common/node.dart'; import 'package:cake_wallet/src/domain/common/node.dart';
import 'package:cake_wallet/core/pending_transaction.dart'; import 'package:cake_wallet/core/pending_transaction.dart';
import 'package:cake_wallet/src/domain/common/transaction_priority.dart'; import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
import 'package:cake_wallet/src/domain/common/calculate_fiat_amount.dart'
as cfa;
part 'monero_wallet.g.dart'; part 'monero_wallet.g.dart';
const moneroBlockSize = 1000;
class MoneroWallet = MoneroWalletBase with _$MoneroWallet; class MoneroWallet = MoneroWalletBase with _$MoneroWallet;
abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store { abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
MoneroWalletBase({String filename, this.isRecovery = false}) MoneroWalletBase({String filename, WalletInfo walletInfo})
: transactionHistory = MoneroTransactionHistory(), : transactionHistory = MoneroTransactionHistory(),
accountList = MoneroAccountList(), accountList = MoneroAccountList(),
subaddressList = MoneroSubaddressList() { subaddressList = MoneroSubaddressList(),
super(walletInfo) {
_filename = filename; _filename = filename;
balance = MoneroBalance( balance = MoneroBalance(
fullBalance: monero_wallet.getFullBalance(accountIndex: 0), fullBalance: monero_wallet.getFullBalance(accountIndex: 0),
unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0)); unlockedBalance: monero_wallet.getFullBalance(accountIndex: 0));
currency = CryptoCurrency.xmr;
type = WalletType.monero;
_rct = reaction(
(_) => syncStatus, (SyncStatus status) => print(status.toString()));
_onAccountChangeReaction = reaction((_) => account, (Account account) { _onAccountChangeReaction = reaction((_) => account, (Account account) {
subaddressList.update(accountIndex: account.id); subaddressList.update(accountIndex: account.id);
subaddress = subaddressList.subaddresses.first; subaddress = subaddressList.subaddresses.first;
@ -46,8 +40,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
}); });
} }
ReactionDisposer _rct;
@override @override
final MoneroTransactionHistory transactionHistory; final MoneroTransactionHistory transactionHistory;
@ -57,15 +49,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
@observable @observable
Subaddress subaddress; Subaddress subaddress;
@override
@observable @observable
SyncStatus syncStatus; SyncStatus syncStatus;
@override @override
String get name => _filename.split('/').last; @observable
String address;
@override @override
@observable @observable
String address; MoneroBalance balance;
@override @override
String get seed => monero_wallet.getSeed(); String get seed => monero_wallet.getSeed();
@ -81,8 +75,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
final MoneroAccountList accountList; final MoneroAccountList accountList;
bool isRecovery;
String _filename; String _filename;
SyncListner _listener; SyncListner _listener;
ReactionDisposer _onAccountChangeReaction; ReactionDisposer _onAccountChangeReaction;
@ -107,8 +99,6 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
@override @override
Future<void> connectToNode({@required Node node}) async { Future<void> connectToNode({@required Node node}) async {
final node = Node(uri: 'xmr-node-uk.cakewallet.com:18081');
try { try {
syncStatus = ConnectingSyncStatus(); syncStatus = ConnectingSyncStatus();
await monero_wallet.setupNode( await monero_wallet.setupNode(
@ -127,6 +117,10 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
@override @override
Future<void> startSync() async { Future<void> startSync() async {
try {
_setInitialHeight();
} catch (_) {}
try { try {
syncStatus = StartingSyncStatus(); syncStatus = StartingSyncStatus();
monero_wallet.startRefresh(); monero_wallet.startRefresh();
@ -180,25 +174,18 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
@override @override
Future<void> save() async { Future<void> save() async {
// if (_isSaving) {
// return;
// }
try {
// _isSaving = true;
await monero_wallet.store(); await monero_wallet.store();
// _isSaving = false;
} catch (e) {
print(e);
// _isSaving = false;
rethrow;
}
} }
Future<int> getNodeHeight() async => monero_wallet.getNodeHeight(); Future<int> getNodeHeight() async => monero_wallet.getNodeHeight();
Future<bool> isConnected() async => monero_wallet.isConnected(); Future<bool> isConnected() async => monero_wallet.isConnected();
Future<void> setAsRecovered() async {
walletInfo.isRecovery = false;
await walletInfo.save();
}
void _setListeners() { void _setListeners() {
_listener?.stop(); _listener?.stop();
_listener = monero_wallet.setListeners( _listener = monero_wallet.setListeners(
@ -206,6 +193,41 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
_listener.start(); _listener.start();
} }
void _setInitialHeight() {
if (walletInfo.isRecovery) {
return;
}
final currentHeight = getCurrentHeight();
print('currentHeight $currentHeight');
if (currentHeight <= 1) {
final height = _getHeightByDate(walletInfo.date);
monero_wallet.setRecoveringFromSeed(isRecovery: true);
monero_wallet.setRefreshFromBlockHeight(height: height);
}
}
int _getHeightDistance(DateTime date) {
final distance =
DateTime.now().millisecondsSinceEpoch - date.millisecondsSinceEpoch;
final daysTmp = (distance / 86400).round();
final days = daysTmp < 1 ? 1 : daysTmp;
return days * 1000;
}
int _getHeightByDate(DateTime date) {
final nodeHeight = monero_wallet.getNodeHeightSync();
final heightDistance = _getHeightDistance(date);
if (nodeHeight <= 0) {
return 0;
}
return nodeHeight - heightDistance;
}
void _askForUpdateBalance() { void _askForUpdateBalance() {
final fullBalance = _getFullBalance(); final fullBalance = _getFullBalance();
final unlockedBalance = _getUnlockedBalance(); final unlockedBalance = _getUnlockedBalance();
@ -236,13 +258,17 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance> with Store {
syncStatus = SyncedSyncStatus(); syncStatus = SyncedSyncStatus();
if (isRecovery) { if (walletInfo.isRecovery) {
_askForUpdateTransactionHistory(); _askForUpdateTransactionHistory();
} }
// if (isRecovery && (nodeHeight - currentHeight < moneroBlockSize)) { final currentHeight = getCurrentHeight();
// await setAsRecovered(); final nodeHeight = monero_wallet.getNodeHeightSync();
// }
if (walletInfo.isRecovery &&
(nodeHeight - currentHeight < moneroBlockSize)) {
await setAsRecovered();
}
await save(); await save();
} }

View file

@ -1,12 +1,14 @@
import 'dart:io'; import 'dart:io';
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:hive/hive.dart';
import 'package:cw_monero/wallet_manager.dart' as monero_wallet_manager;
import 'package:cw_monero/wallet.dart' as monero_wallet;
import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/monero/monero_wallet.dart';
import 'package:cake_wallet/core/wallet_credentials.dart'; import 'package:cake_wallet/core/wallet_credentials.dart';
import 'package:cake_wallet/core/wallet_service.dart'; import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/src/domain/common/pathForWallet.dart'; import 'package:cake_wallet/src/domain/common/pathForWallet.dart';
import 'package:cake_wallet/src/domain/common/wallet_info.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cw_monero/wallet_manager.dart' as monero_wallet_manager;
import 'package:cw_monero/wallet.dart' as monero_wallet;
class MoneroNewWalletCredentials extends WalletCredentials { class MoneroNewWalletCredentials extends WalletCredentials {
MoneroNewWalletCredentials({String name, String password, this.language}) MoneroNewWalletCredentials({String name, String password, this.language})
@ -17,11 +19,10 @@ class MoneroNewWalletCredentials extends WalletCredentials {
class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials { class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials {
MoneroRestoreWalletFromSeedCredentials( MoneroRestoreWalletFromSeedCredentials(
{String name, String password, this.mnemonic, this.height}) {String name, String password, int height, this.mnemonic})
: super(name: name, password: password); : super(name: name, password: password, height: height);
final String mnemonic; final String mnemonic;
final int height;
} }
class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials { class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
@ -32,32 +33,35 @@ class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials {
this.address, this.address,
this.viewKey, this.viewKey,
this.spendKey, this.spendKey,
this.height}) int height})
: super(name: name, password: password); : super(name: name, password: password, height: height);
final String language; final String language;
final String address; final String address;
final String viewKey; final String viewKey;
final String spendKey; final String spendKey;
final int height;
} }
class MoneroWalletService extends WalletService< class MoneroWalletService extends WalletService<
MoneroNewWalletCredentials, MoneroNewWalletCredentials,
MoneroRestoreWalletFromSeedCredentials, MoneroRestoreWalletFromSeedCredentials,
MoneroRestoreWalletFromKeysCredentials> { MoneroRestoreWalletFromKeysCredentials> {
MoneroWalletService(this.walletInfoSource);
final Box<WalletInfo> walletInfoSource;
@override @override
Future<MoneroWallet> create(MoneroNewWalletCredentials credentials) async { Future<MoneroWallet> create(MoneroNewWalletCredentials credentials) async {
try { try {
final path = final path =
await pathForWallet(name: credentials.name, type: WalletType.monero); await pathForWallet(name: credentials.name, type: WalletType.monero);
await monero_wallet_manager.createWallet( await monero_wallet_manager.createWallet(
path: path, path: path,
password: credentials.password, password: credentials.password,
language: credentials.language); language: credentials.language);
final wallet = MoneroWallet(
final wallet = MoneroWallet(filename: monero_wallet.getFilename()); filename: monero_wallet.getFilename(),
walletInfo: credentials.walletInfo);
await wallet.init(); await wallet.init();
return wallet; return wallet;
@ -84,8 +88,16 @@ class MoneroWalletService extends WalletService<
Future<MoneroWallet> openWallet(String name, String password) async { Future<MoneroWallet> openWallet(String name, String password) async {
try { try {
final path = await pathForWallet(name: name, type: WalletType.monero); final path = await pathForWallet(name: name, type: WalletType.monero);
final file = File(path);
final stat = await file.stat();
print(stat.changed);
print(stat.modified);
print(stat.accessed);
monero_wallet_manager.openWallet(path: path, password: password); monero_wallet_manager.openWallet(path: path, password: password);
final wallet = MoneroWallet(filename: monero_wallet.getFilename()); final walletInfo = walletInfoSource.values.firstWhere(
(info) => info.id == WalletBase.idFor(name, WalletType.monero));
final wallet = MoneroWallet(
filename: monero_wallet.getFilename(), walletInfo: walletInfo);
await wallet.init(); await wallet.init();
return wallet; return wallet;
@ -107,7 +119,6 @@ class MoneroWalletService extends WalletService<
try { try {
final path = final path =
await pathForWallet(name: credentials.name, type: WalletType.monero); await pathForWallet(name: credentials.name, type: WalletType.monero);
await monero_wallet_manager.restoreFromKeys( await monero_wallet_manager.restoreFromKeys(
path: path, path: path,
password: credentials.password, password: credentials.password,
@ -116,8 +127,9 @@ class MoneroWalletService extends WalletService<
address: credentials.address, address: credentials.address,
viewKey: credentials.viewKey, viewKey: credentials.viewKey,
spendKey: credentials.spendKey); spendKey: credentials.spendKey);
final wallet = MoneroWallet(
final wallet = MoneroWallet(filename: monero_wallet.getFilename()); filename: monero_wallet.getFilename(),
walletInfo: credentials.walletInfo);
await wallet.init(); await wallet.init();
return wallet; return wallet;
@ -134,14 +146,14 @@ class MoneroWalletService extends WalletService<
try { try {
final path = final path =
await pathForWallet(name: credentials.name, type: WalletType.monero); await pathForWallet(name: credentials.name, type: WalletType.monero);
await monero_wallet_manager.restoreFromSeed( await monero_wallet_manager.restoreFromSeed(
path: path, path: path,
password: credentials.password, password: credentials.password,
seed: credentials.mnemonic, seed: credentials.mnemonic,
restoreHeight: credentials.height); restoreHeight: credentials.height);
final wallet = MoneroWallet(
final wallet = MoneroWallet(filename: monero_wallet.getFilename()); filename: monero_wallet.getFilename(),
walletInfo: credentials.walletInfo);
await wallet.init(); await wallet.init();
return wallet; return wallet;

View file

@ -1,28 +1,20 @@
import 'dart:async'; import 'dart:async';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/router.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:cake_wallet/src/screens/dashboard/dashboard_page.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart'; import 'package:connectivity/connectivity.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/monero/monero_wallet_service.dart'; import 'package:cake_wallet/router.dart';
import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/core/wallet_service.dart'; import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/src/domain/common/secret_store_key.dart';
import 'package:cake_wallet/src/domain/common/encrypt.dart';
import 'package:cake_wallet/src/domain/services/fiat_convertation_service.dart'; import 'package:cake_wallet/src/domain/services/fiat_convertation_service.dart';
import 'package:cake_wallet/src/domain/common/fiat_currency.dart'; import 'package:cake_wallet/src/domain/common/fiat_currency.dart';
import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart';
@ -36,19 +28,7 @@ Future<void> loadCurrentWallet() async {
final type = deserializeFromInt(typeRaw); final type = deserializeFromInt(typeRaw);
final password = final password =
await getIt.get<KeyService>().getWalletPassword(walletName: name); await getIt.get<KeyService>().getWalletPassword(walletName: name);
final _service = getIt.get<WalletService>(param1: type);
WalletService _service;
switch (type) {
case WalletType.monero:
_service = MoneroWalletService();
break;
case WalletType.bitcoin:
_service = BitcoinWalletService();
break;
default:
break;
}
final wallet = await _service.openWallet(name, password); final wallet = await _service.openWallet(name, password);
appStore.wallet = wallet; appStore.wallet = wallet;
} }
@ -79,9 +59,6 @@ Future<void> bootstrap(
if (state == AuthenticationState.installed) { if (state == AuthenticationState.installed) {
await loadCurrentWallet(); await loadCurrentWallet();
}
if (state == AuthenticationState.installed) {
await navigatorKey.currentState await navigatorKey.currentState
.pushAndRemoveUntil(createLoginRoute(), (_) => false); .pushAndRemoveUntil(createLoginRoute(), (_) => false);
} }
@ -101,16 +78,31 @@ Future<void> bootstrap(
reaction((_) => getIt.get<AppStore>().wallet, (WalletBase wallet) async { reaction((_) => getIt.get<AppStore>().wallet, (WalletBase wallet) async {
_onWalletSyncStatusChangeReaction?.reaction?.dispose(); _onWalletSyncStatusChangeReaction?.reaction?.dispose();
_reconnectionTimer?.cancel(); _reconnectionTimer?.cancel();
_onWalletSyncStatusChangeReaction = reaction( _onWalletSyncStatusChangeReaction =
(_) => wallet.syncStatus is ConnectedSyncStatus, reaction((_) => wallet.syncStatus, (SyncStatus status) async {
(Object _) async => await wallet.startSync()); if (status is ConnectedSyncStatus) {
await wallet.startSync();
}
});
_reconnectionTimer = Timer.periodic(Duration(seconds: 5), (_) async { _reconnectionTimer = Timer.periodic(Duration(seconds: 5), (_) async {
final connectivityResult = await (Connectivity().checkConnectivity());
if (connectivityResult == ConnectivityResult.none) {
wallet.syncStatus = FailedSyncStatus();
return;
}
if (wallet.syncStatus is LostConnectionSyncStatus || if (wallet.syncStatus is LostConnectionSyncStatus ||
wallet.syncStatus is FailedSyncStatus) { wallet.syncStatus is FailedSyncStatus) {
try { try {
final alive =
await settingsStore.getCurrentNode(wallet.type).requestNode();
if (alive) {
await wallet.connectToNode( await wallet.connectToNode(
node: settingsStore.getCurrentNode(wallet.type)); node: settingsStore.getCurrentNode(wallet.type));
}
} catch (_) {} } catch (_) {}
} }
}); });

View file

@ -82,28 +82,28 @@ Future<void> migrate_wallets({Directory appDocDir}) async {
Future<void> migrate_ios_wallet_info( Future<void> migrate_ios_wallet_info(
{@required Directory appDocDir, {@required Directory appDocDir,
@required Box<WalletInfo> walletsInfo}) async { @required Box<WalletInfo> walletsInfo}) async {
final walletsDir = Directory('${appDocDir.path}/wallets'); // final walletsDir = Directory('${appDocDir.path}/wallets');
final moneroWalletsDir = Directory('${walletsDir.path}/monero'); // final moneroWalletsDir = Directory('${walletsDir.path}/monero');
moneroWalletsDir.listSync().forEach((item) async { // moneroWalletsDir.listSync().forEach((item) async {
try { // try {
if (item is Directory) { // if (item is Directory) {
final name = item.path.split('/').last; // final name = item.path.split('/').last;
final configFile = File('${item.path}/$name.json'); // final configFile = File('${item.path}/$name.json');
final config = // final config =
json.decode(configFile.readAsStringSync()) as Map<String, dynamic>; // json.decode(configFile.readAsStringSync()) as Map<String, dynamic>;
final isRecovery = config["isRecovery"] as bool ?? false; // final isRecovery = config["isRecovery"] as bool ?? false;
final id = // final id =
walletTypeToString(WalletType.monero).toLowerCase() + '_' + name; // walletTypeToString(WalletType.monero).toLowerCase() + '_' + name;
final walletInfo = // final walletInfo =
WalletInfo(id: id, name: name, isRecovery: isRecovery); // WalletInfo(id: id, name: name, isRecovery: isRecovery);
await walletsInfo.add(walletInfo); // await walletsInfo.add(walletInfo);
} // }
} catch (e) { // } catch (e) {
print(e.toString()); // print(e.toString());
} // }
}); // });
} }
Future<void> migrate_ios_trades_list( Future<void> migrate_ios_trades_list(

View file

@ -1,12 +1,26 @@
import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
part 'wallet_info.g.dart'; part 'wallet_info.g.dart';
@HiveType(typeId: 4) @HiveType(typeId: 4)
class WalletInfo extends HiveObject { class WalletInfo extends HiveObject {
WalletInfo( WalletInfo(this.id, this.name, this.type, this.isRecovery, this.restoreHeight,
{this.id, this.name, this.type, this.isRecovery, this.restoreHeight}); this.timestamp, this.dirPath, this.path);
factory WalletInfo.external(
{@required String id,
@required String name,
@required WalletType type,
@required bool isRecovery,
@required int restoreHeight,
@required DateTime date,
@required String dirPath,
@required String path}) {
return WalletInfo(id, name, type, isRecovery, restoreHeight,
date.millisecondsSinceEpoch ?? 0, dirPath, path);
}
static const boxName = 'WalletInfo'; static const boxName = 'WalletInfo';
@ -24,4 +38,15 @@ class WalletInfo extends HiveObject {
@HiveField(4) @HiveField(4)
int restoreHeight; int restoreHeight;
@HiveField(5)
int timestamp;
@HiveField(6)
String dirPath;
@HiveField(7)
String path;
DateTime get date => DateTime.fromMillisecondsSinceEpoch(timestamp);
} }

View file

@ -47,18 +47,19 @@ class MoneroWallet extends Wallet {
String name, String name,
bool isRecovery = false, bool isRecovery = false,
int restoreHeight = 0}) async { int restoreHeight = 0}) async {
const type = WalletType.monero; // const type = WalletType.monero;
final id = walletTypeToString(type).toLowerCase() + '_' + name; // final id = walletTypeToString(type).toLowerCase() + '_' + name;
final walletInfo = WalletInfo( // final walletInfo = WalletInfo(
id: id, // id: id,
name: name, // name: name,
type: type, // type: type,
isRecovery: isRecovery, // isRecovery: isRecovery,
restoreHeight: restoreHeight); // restoreHeight: restoreHeight);
await walletInfoSource.add(walletInfo); // await walletInfoSource.add(walletInfo);
return await configured( // return await configured(
walletInfo: walletInfo, walletInfoSource: walletInfoSource); // walletInfo: walletInfo, walletInfoSource: walletInfoSource);
return null;
} }
static Future<MoneroWallet> load( static Future<MoneroWallet> load(

View file

@ -12,8 +12,6 @@ import 'package:cake_wallet/src/domain/common/wallet.dart';
import 'package:cake_wallet/src/domain/monero/monero_wallet.dart'; import 'package:cake_wallet/src/domain/monero/monero_wallet.dart';
import 'package:cake_wallet/src/domain/common/wallet_description.dart'; import 'package:cake_wallet/src/domain/common/wallet_description.dart';
class MoneroWalletsManager extends WalletsManager { class MoneroWalletsManager extends WalletsManager {
MoneroWalletsManager({@required this.walletInfoSource}); MoneroWalletsManager({@required this.walletInfoSource});
@ -27,7 +25,8 @@ class MoneroWalletsManager extends WalletsManager {
const isRecovery = false; const isRecovery = false;
final path = await pathForWallet(name: name, type: WalletType.monero); final path = await pathForWallet(name: name, type: WalletType.monero);
await monero_wallet_manager.createWallet(path: path, password: password, language: language); await monero_wallet_manager.createWallet(
path: path, password: password, language: language);
final wallet = await MoneroWallet.createdWallet( final wallet = await MoneroWallet.createdWallet(
walletInfoSource: walletInfoSource, walletInfoSource: walletInfoSource,

View file

@ -65,18 +65,18 @@ void onSyncStatusChange(
{SyncStore syncStore, {SyncStore syncStore,
WalletStore walletStore, WalletStore walletStore,
SettingsStore settingsStore}) { SettingsStore settingsStore}) {
_onSyncStatusChangeDisposer?.call(); // _onSyncStatusChangeDisposer?.call();
reaction((_) => syncStore.status, (SyncStatus status) async { // reaction((_) => syncStore.status, (SyncStatus status) async {
if (status is ConnectedSyncStatus) { // if (status is ConnectedSyncStatus) {
await walletStore.startSync(); // await walletStore.startSync();
} // }
// Reconnect to the node if the app is not started sync after 30 seconds // // Reconnect to the node if the app is not started sync after 30 seconds
if (status is StartingSyncStatus) { // if (status is StartingSyncStatus) {
startReconnectionObserver(syncStore: syncStore, walletStore: walletStore); // startReconnectionObserver(syncStore: syncStore, walletStore: walletStore);
} // }
}); // });
} }
void startReconnectionObserver({SyncStore syncStore, WalletStore walletStore}) { void startReconnectionObserver({SyncStore syncStore, WalletStore walletStore}) {

View file

@ -14,7 +14,8 @@ import 'package:cake_wallet/generated/i18n.dart';
part 'exchange_trade_view_model.g.dart'; part 'exchange_trade_view_model.g.dart';
class ExchangeTradeViewModel = ExchangeTradeViewModelBase with _$ExchangeTradeViewModel; class ExchangeTradeViewModel = ExchangeTradeViewModelBase
with _$ExchangeTradeViewModel;
abstract class ExchangeTradeViewModelBase with Store { abstract class ExchangeTradeViewModelBase with Store {
ExchangeTradeViewModelBase({this.wallet, this.trades, this.tradesStore}) { ExchangeTradeViewModelBase({this.wallet, this.trades, this.tradesStore}) {
@ -38,17 +39,11 @@ abstract class ExchangeTradeViewModelBase with Store {
items = ObservableList<ExchangeTradeItem>(); items = ObservableList<ExchangeTradeItem>();
items.addAll([ items.addAll([
ExchangeTradeItem( ExchangeTradeItem(
title: S.current.id, title: S.current.id, data: '${trade.id}', isCopied: true),
data: '${trade.id}',
isCopied: true),
ExchangeTradeItem( ExchangeTradeItem(
title: S.current.amount, title: S.current.amount, data: '${trade.amount}', isCopied: false),
data: '${trade.amount}',
isCopied: false),
ExchangeTradeItem( ExchangeTradeItem(
title: S.current.status, title: S.current.status, data: '${trade.state}', isCopied: false),
data: '${trade.state}',
isCopied: false),
ExchangeTradeItem( ExchangeTradeItem(
title: S.current.widgets_address + ':', title: S.current.widgets_address + ':',
data: trade.inputAddress, data: trade.inputAddress,

View file

@ -1,5 +1,3 @@
import 'package:cake_wallet/utils/item_cell.dart';
import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/core/wallet_base.dart';
@ -10,6 +8,7 @@ import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/src/domain/common/default_settings_migration.dart'; import 'package:cake_wallet/src/domain/common/default_settings_migration.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart'; import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/utils/mobx.dart'; import 'package:cake_wallet/utils/mobx.dart';
import 'package:cake_wallet/utils/item_cell.dart';
part 'node_list_view_model.g.dart'; part 'node_list_view_model.g.dart';

View file

@ -1,3 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/core/address_validator.dart'; import 'package:cake_wallet/core/address_validator.dart';
import 'package:cake_wallet/core/amount_validator.dart'; import 'package:cake_wallet/core/amount_validator.dart';
import 'package:cake_wallet/core/template_validator.dart'; import 'package:cake_wallet/core/template_validator.dart';
@ -5,7 +8,6 @@ import 'package:cake_wallet/core/validator.dart';
import 'package:cake_wallet/core/wallet_base.dart'; import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart'; import 'package:cake_wallet/bitcoin/bitcoin_wallet.dart';
import 'package:cake_wallet/monero/monero_wallet.dart'; import 'package:cake_wallet/monero/monero_wallet.dart';
import 'package:cake_wallet/src/domain/common/balance.dart';
import 'package:cake_wallet/src/domain/common/balance_display_mode.dart'; import 'package:cake_wallet/src/domain/common/balance_display_mode.dart';
import 'package:cake_wallet/src/domain/common/calculate_estimated_fee.dart'; import 'package:cake_wallet/src/domain/common/calculate_estimated_fee.dart';
import 'package:cake_wallet/src/domain/common/crypto_currency.dart'; import 'package:cake_wallet/src/domain/common/crypto_currency.dart';
@ -14,15 +16,6 @@ import 'package:cake_wallet/src/domain/common/sync_status.dart';
import 'package:cake_wallet/src/domain/common/transaction_priority.dart'; import 'package:cake_wallet/src/domain/common/transaction_priority.dart';
import 'package:cake_wallet/store/settings_store.dart'; import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/store/templates/send_template_store.dart'; import 'package:cake_wallet/store/templates/send_template_store.dart';
import 'package:flutter/foundation.dart';
import 'package:intl/intl.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/monero/monero_wallet_service.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_creation_credentials.dart';
import 'package:cake_wallet/core/wallet_creation_service.dart';
import 'package:cake_wallet/core/wallet_credentials.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/view_model/wallet_creation_vm.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/domain/common/openalias_record.dart'; import 'package:cake_wallet/src/domain/common/openalias_record.dart';
import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart'; import 'package:cake_wallet/store/dashboard/fiat_convertation_store.dart';
@ -51,12 +44,8 @@ class SendingFailed extends SendViewModelState {
class SendViewModel = SendViewModelBase with _$SendViewModel; class SendViewModel = SendViewModelBase with _$SendViewModel;
abstract class SendViewModelBase with Store { abstract class SendViewModelBase with Store {
SendViewModelBase( SendViewModelBase(this._wallet, this._settingsStore,
this._wallet, this._fiatConvertationStore, this.sendTemplateStore) {
this._settingsStore,
this._fiatConvertationStore,
this.sendTemplateStore) {
state = InitialSendViewModelState(); state = InitialSendViewModelState();
_cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12; _cryptoNumberFormat = NumberFormat()..maximumFractionDigits = 12;
@ -116,9 +105,10 @@ abstract class SendViewModelBase with Store {
double get price => _fiatConvertationStore.price; double get price => _fiatConvertationStore.price;
@computed @computed
ObservableList<Template> get templates => ObservableList.of( ObservableList<Template> get templates =>
sendTemplateStore.templates.where((item) ObservableList.of(sendTemplateStore.templates
=> item.cryptoCurrency == _wallet.currency.title).toList()); .where((item) => item.cryptoCurrency == _wallet.currency.title)
.toList());
@computed @computed
String get balance { String get balance {
@ -211,8 +201,8 @@ abstract class SendViewModelBase with Store {
String recordAddress; String recordAddress;
Future<bool> isOpenaliasRecord(String name) async { Future<bool> isOpenaliasRecord(String name) async {
final _openaliasRecord = await OpenaliasRecord final _openaliasRecord = await OpenaliasRecord.fetchAddressAndName(
.fetchAddressAndName(OpenaliasRecord.formatDomainName(name)); OpenaliasRecord.formatDomainName(name));
recordAddress = _openaliasRecord.address; recordAddress = _openaliasRecord.address;
recordName = _openaliasRecord.name; recordName = _openaliasRecord.name;

View file

@ -24,15 +24,14 @@ class AddressEditOrCreateStateFailure extends AddressEditOrCreateState {
} }
abstract class WalletAddressEditOrCreateViewModelBase with Store { abstract class WalletAddressEditOrCreateViewModelBase with Store {
WalletAddressEditOrCreateViewModelBase({@required WalletBase wallet, dynamic item}) WalletAddressEditOrCreateViewModelBase(
{@required WalletBase wallet, dynamic item})
: isEdit = item != null, : isEdit = item != null,
state = AddressEditOrCreateStateInitial(), state = AddressEditOrCreateStateInitial(),
label = item?.name as String, label = item?.name as String,
_item = item, _item = item,
_wallet = wallet; _wallet = wallet;
dynamic _item;
@observable @observable
AddressEditOrCreateState state; AddressEditOrCreateState state;
@ -41,11 +40,10 @@ abstract class WalletAddressEditOrCreateViewModelBase with Store {
bool isEdit; bool isEdit;
final dynamic _item;
final WalletBase _wallet; final WalletBase _wallet;
Future<void> save() async { Future<void> save() async {
final wallet = _wallet;
try { try {
state = AddressIsSaving(); state = AddressIsSaving();

View file

@ -109,8 +109,8 @@ abstract class WalletAddressListViewModelBase with Store {
return addressList; return addressList;
} }
set address(WalletAddressListItem address) => set address(WalletAddressListItem address) => null;
_wallet.address = address.address; // _wallet.address = address.address;
bool hasAccounts; bool hasAccounts;

View file

@ -1,3 +1,4 @@
import 'package:cake_wallet/core/wallet_base.dart';
import 'package:cake_wallet/src/domain/common/wallet_info.dart'; import 'package:cake_wallet/src/domain/common/wallet_info.dart';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
@ -32,14 +33,16 @@ abstract class WalletCreationVMBase with Store {
Future<void> create({dynamic options}) async { Future<void> create({dynamic options}) async {
try { try {
state = WalletCreating(); state = WalletCreating();
await process(getCredentials(options)); final credentials = getCredentials(options);
final id = walletTypeToString(type).toLowerCase() + '_' + name; final walletInfo = WalletInfo.external(
final walletInfo = WalletInfo( id: WalletBase.idFor(name, type),
id: id,
name: name, name: name,
type: type, type: type,
isRecovery: isRecovery, isRecovery: isRecovery,
restoreHeight: 0); restoreHeight: credentials.height ?? 0,
date: DateTime.now());
credentials.walletInfo = walletInfo;
await process(credentials);
await _walletInfoSource.add(walletInfo); await _walletInfoSource.add(walletInfo);
state = WalletCreatedSuccessfully(); state = WalletCreatedSuccessfully();
} catch (e) { } catch (e) {

View file

@ -1,12 +1,10 @@
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/core/key_service.dart'; import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/core/wallet_service.dart'; import 'package:cake_wallet/core/wallet_service.dart';
import 'package:cake_wallet/bitcoin/bitcoin_wallet_service.dart';
import 'package:cake_wallet/monero/monero_wallet_service.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart'; import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
import 'package:cake_wallet/src/domain/common/wallet_type.dart';
import 'package:cake_wallet/src/domain/common/wallet_info.dart'; import 'package:cake_wallet/src/domain/common/wallet_info.dart';
part 'wallet_list_view_model.g.dart'; part 'wallet_list_view_model.g.dart';
@ -31,29 +29,18 @@ abstract class WalletListViewModelBase with Store {
Future<void> loadWallet(WalletListItem wallet) async { Future<void> loadWallet(WalletListItem wallet) async {
final password = final password =
await _keyService.getWalletPassword(walletName: wallet.name); await _keyService.getWalletPassword(walletName: wallet.name);
final walletService = _getWalletService(wallet.type); final walletService = getIt.get<WalletService>();
_appStore.wallet = await walletService.openWallet(wallet.name, password); _appStore.wallet = await walletService.openWallet(wallet.name, password);
} }
@action @action
Future<void> remove(WalletListItem wallet) async { Future<void> remove(WalletListItem wallet) async {
final walletService = _getWalletService(wallet.type); final walletService = getIt.get<WalletService>();
await walletService.remove(wallet.name); await walletService.remove(wallet.name);
await _walletInfoSource.delete(wallet.key); await _walletInfoSource.delete(wallet.key);
_updateList(); _updateList();
} }
WalletService _getWalletService(WalletType type) {
switch (type) {
case WalletType.monero:
return MoneroWalletService();
case WalletType.bitcoin:
return BitcoinWalletService();
default:
return null;
}
}
void _updateList() { void _updateList() {
wallets.clear(); wallets.clear();
wallets.addAll(_walletInfoSource.values.map((info) => WalletListItem( wallets.addAll(_walletInfoSource.values.map((info) => WalletListItem(

View file

@ -211,6 +211,34 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.14.13" version: "1.14.13"
connectivity:
dependency: "direct main"
description:
name: connectivity
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.9+2"
connectivity_for_web:
dependency: transitive
description:
name: connectivity_for_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.1+2"
connectivity_macos:
dependency: transitive
description:
name: connectivity_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.0+4"
connectivity_platform_interface:
dependency: transitive
description:
name: connectivity_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.6"
convert: convert:
dependency: transitive dependency: transitive
description: description:

View file

@ -60,6 +60,7 @@ dependencies:
basic_utils: ^1.0.8 basic_utils: ^1.0.8
bitcoin_flutter: ^2.0.0 bitcoin_flutter: ^2.0.0
get_it: ^4.0.2 get_it: ^4.0.2
connectivity: ^0.4.9+2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: