From b8e435ea8e9a214804e18e7c436abab7fa948d67 Mon Sep 17 00:00:00 2001 From: M Date: Thu, 29 Oct 2020 12:49:07 +0200 Subject: [PATCH] Fixes. --- cw_monero/ios/Classes/monero_api.cpp | 28 ++++--- cw_monero/lib/account_list.dart | 15 +++- cw_monero/lib/subaddress_list.dart | 17 +++- cw_monero/lib/wallet.dart | 29 +++++-- ios/Flutter/AppFrameworkInfo.plist | 40 +++++----- ios/Runner.xcodeproj/project.pbxproj | 9 ++- lib/monero/get_height_by_date.dart | 18 ++++- lib/monero/monero_wallet.dart | 46 +++++++++-- lib/monero/monero_wallet_service.dart | 39 ++++++++-- lib/src/widgets/annotated_editable_text.dart | 77 +++++++++---------- lib/src/widgets/seed_widget.dart | 26 ++++--- lib/view_model/wallet_creation_vm.dart | 2 +- lib/view_model/wallet_restore_view_model.dart | 3 +- pubspec.lock | 20 ++--- 14 files changed, 250 insertions(+), 119 deletions(-) diff --git a/cw_monero/ios/Classes/monero_api.cpp b/cw_monero/ios/Classes/monero_api.cpp index aa96d7656..bc653da10 100644 --- a/cw_monero/ios/Classes/monero_api.cpp +++ b/cw_monero/ios/Classes/monero_api.cpp @@ -87,7 +87,7 @@ extern "C" void updated() { - m_need_to_refresh = true; + m_new_transaction = true; } void refreshed() @@ -472,7 +472,9 @@ extern "C" return false; } - m_listener->m_new_transaction = true; + if (m_listener != nullptr) { + m_listener->m_new_transaction = true; + } pendingTransaction = PendingTransactionRaw(transaction); return true; @@ -485,7 +487,7 @@ extern "C" if (!committed) { error = Utf8Box(strdup(transaction->transaction->errorString().c_str())); - } else { + } else if (m_listener != nullptr) { m_listener->m_new_transaction = true; } @@ -508,9 +510,13 @@ extern "C" } uint64_t height = m_listener->height(); - uint64_t node_height = get_node_height_or_update(height); +// uint64_t node_height = get_node_height_or_update(height); +// +// if (height <= 1 || node_height <= 0) { +// return 0; +// } - if (height <= 1 || node_height <= 0) { + if (height <= 1) { return 0; } @@ -529,10 +535,14 @@ extern "C" } bool should_refresh = m_listener->isNeedToRefresh(); - uint64_t node_height = get_node_height_or_update(m_last_known_wallet_height); +// uint64_t node_height = get_node_height_or_update(m_last_known_wallet_height); +// +// if (should_refresh || (node_height - m_last_known_wallet_height < MONERO_BLOCK_SIZE)) +// { +// m_listener->resetNeedToRefresh(); +// } - if (should_refresh || (node_height - m_last_known_wallet_height < MONERO_BLOCK_SIZE)) - { + if (should_refresh) { m_listener->resetNeedToRefresh(); } @@ -561,7 +571,7 @@ extern "C" if (m_listener != nullptr) { - // free(m_listener); + free(m_listener); } m_listener = new MoneroWalletListener(); diff --git a/cw_monero/lib/account_list.dart b/cw_monero/lib/account_list.dart index bf5618a1b..6e84f5931 100644 --- a/cw_monero/lib/account_list.dart +++ b/cw_monero/lib/account_list.dart @@ -26,7 +26,18 @@ final accountSetLabelNative = moneroApi .lookup>('account_set_label_row') .asFunction(); -void refreshAccounts() => accountRefreshNative(); +bool isUpdating = false; + +void refreshAccounts() { + try { + isUpdating = true; + accountRefreshNative(); + isUpdating = false; + } catch (e) { + isUpdating = false; + rethrow; + } +} List getAllAccount() { final size = accountSizeNative(); @@ -63,4 +74,4 @@ Future addAccount({String label}) async => compute(_addAccount, label); Future setLabelForAccount({int accountIndex, String label}) async => compute( - _setLabelForAccount, {'accountIndex': accountIndex, 'label': label}); + _setLabelForAccount, {'accountIndex': accountIndex, 'label': label}); \ No newline at end of file diff --git a/cw_monero/lib/subaddress_list.dart b/cw_monero/lib/subaddress_list.dart index 933899e0c..97a307040 100644 --- a/cw_monero/lib/subaddress_list.dart +++ b/cw_monero/lib/subaddress_list.dart @@ -26,8 +26,18 @@ final subaddrressSetLabelNative = moneroApi .lookup>('subaddress_set_label') .asFunction(); -void refreshSubaddresses({int accountIndex}) => +bool isUpdating = false; + +void refreshSubaddresses({@required int accountIndex}) { + try { + isUpdating = true; subaddressRefreshNative(accountIndex); + isUpdating = false; + } catch (e) { + isUpdating = false; + rethrow; + } +} List getAllSubaddresses() { final size = subaddressSizeNative(); @@ -48,7 +58,7 @@ void addSubaddressSync({int accountIndex, String label}) { void setLabelForSubaddressSync( {int accountIndex, int addressIndex, String label}) { final labelPointer = Utf8.toUtf8(label); - + subaddrressSetLabelNative(accountIndex, addressIndex, labelPointer); free(labelPointer); } @@ -70,7 +80,8 @@ void _setLabelForSubaddress(Map args) { } Future addSubaddress({int accountIndex, String label}) async => - compute, void>(_addSubaddress, {'accountIndex': accountIndex, 'label': label}); + compute, void>( + _addSubaddress, {'accountIndex': accountIndex, 'label': label}); Future setLabelForSubaddress( {int accountIndex, int addressIndex, String label}) => diff --git a/cw_monero/lib/wallet.dart b/cw_monero/lib/wallet.dart index c42cd3523..8a8731d9e 100644 --- a/cw_monero/lib/wallet.dart +++ b/cw_monero/lib/wallet.dart @@ -114,6 +114,8 @@ final rescanBlockchainAsyncNative = moneroApi .lookup>('rescan_blockchain') .asFunction(); +bool isStoring = false; + int getSyncingHeight() => getSyncingHeightNative(); bool isNeededToRefresh() => isNeededToRefreshNative() != 0; @@ -209,8 +211,8 @@ String getSecretSpendKey() => String getPublicSpendKey() => convertUTF8ToString(pointer: getPublicSpendKeyNative()); -class SyncListner { - SyncListner({this.onNewBlock, this.onNeedToRefresh, this.onNewTransaction}); +class SyncListener { + SyncListener({this.onNewBlock, this.onNeedToRefresh, this.onNewTransaction}); void Function(int, int, double) onNewBlock; void Function() onNeedToRefresh; @@ -234,7 +236,7 @@ class SyncListner { _lastKnownBlockHeight = 0; _initialSyncHeight = 0; _updateSyncInfoTimer ??= - Timer.periodic(Duration(milliseconds: 200), (_) async { + Timer.periodic(Duration(milliseconds: 1200), (_) async { final syncHeight = getSyncingHeight(); final needToRefresh = isNeededToRefresh(); final newTransactionExist = isNewTransactionExist(); @@ -251,7 +253,7 @@ class SyncListner { final ptc = diff <= 0 ? 0.0 : diff / line; final left = bchHeight - syncHeight; // 1. Actual new height; 2. Blocks left to finish; 3. Progress in percents; - onNewBlock(syncHeight, left, ptc); + onNewBlock?.call(syncHeight, left, ptc); } if (newTransactionExist) { @@ -267,9 +269,9 @@ class SyncListner { void stop() => _updateSyncInfoTimer?.cancel(); } -SyncListner setListeners(void Function(int, int, double) onNewBlock, +SyncListener setListeners(void Function(int, int, double) onNewBlock, void Function() onNeedToRefresh, void Function() onNewTransaction) { - final listener = SyncListner( + final listener = SyncListener( onNewBlock: onNewBlock, onNeedToRefresh: onNeedToRefresh, onNewTransaction: onNewTransaction); @@ -281,7 +283,20 @@ SyncListner setListeners(void Function(int, int, double) onNewBlock, void onStartup() => onStartupNative(); -void _storeSync(Object _) => storeSync(); +void _storeSync(Object _) { + if (isStoring) { + return; + } + + try { + isStoring = true; + storeSync(); + isStoring = false; + } catch (e) { + isStoring = false; + rethrow; + } +} bool _setupNodeSync(Map args) { final address = args['address'] as String; diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f78a..c5ff5d37e 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -2,25 +2,25 @@ - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - App - CFBundleIdentifier - io.flutter.flutter.app - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - App - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1.0 - MinimumOSVersion - 8.0 + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 13.0 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 97e09ec63..0c0c2cf23 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -354,7 +354,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 11; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -362,6 +362,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -493,7 +494,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 11; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -501,6 +502,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -526,7 +528,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 10; + CURRENT_PROJECT_VERSION = 11; DEVELOPMENT_TEAM = 32J6BB6VUS; ENABLE_BITCODE = NO; FRAMEWORK_SEARCH_PATHS = ( @@ -534,6 +536,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/lib/monero/get_height_by_date.dart b/lib/monero/get_height_by_date.dart index d6dff557e..3f5f87623 100644 --- a/lib/monero/get_height_by_date.dart +++ b/lib/monero/get_height_by_date.dart @@ -67,8 +67,22 @@ final dates = { "2019-5": 1824671, "2019-6": 1847005, "2019-7": 1868590, - "2019-8": 1888590, - "2019-9": 1898590, + "2019-8": 1890552, + "2019-9": 1912212, + "2019-10": 1932200, + "2019-11": 1957040, + "2019-12": 1978090, + "2020-1": 2001290, + "2020-2": 2022688, + "2020-3": 2043987, + "2020-4": 2066536, + "2020-5": 2090797, + "2020-6": 2111633, + "2020-7": 2131433, + "2020-8": 2153983, + "2020-9": 2176466, + "2020-10": 2198453, + "2020-11": 2221803 }; int getHeigthByDate({DateTime date}) { diff --git a/lib/monero/monero_wallet.dart b/lib/monero/monero_wallet.dart index 59ac8702a..9840eb2c5 100644 --- a/lib/monero/monero_wallet.dart +++ b/lib/monero/monero_wallet.dart @@ -19,7 +19,6 @@ import 'package:cake_wallet/entities/wallet_info.dart'; import 'package:cake_wallet/entities/node.dart'; import 'package:cake_wallet/entities/transaction_priority.dart'; - part 'monero_wallet.g.dart'; const moneroBlockSize = 1000; @@ -80,7 +79,7 @@ abstract class MoneroWalletBase extends WalletBase with Store { final MoneroAccountList accountList; String _filename; - SyncListner _listener; + SyncListener _listener; ReactionDisposer _onAccountChangeReaction; int _cachedRefreshHeight; @@ -96,6 +95,15 @@ abstract class MoneroWalletBase extends WalletBase with Store { address = subaddress.address; _setListeners(); await transactionHistory.update(); + + if (walletInfo.isRecovery) { + monero_wallet.setRecoveringFromSeed(isRecovery: walletInfo.isRecovery); + + if (monero_wallet.getCurrentHeight() <= 1) { + monero_wallet.setRefreshFromBlockHeight( + height: walletInfo.restoreHeight); + } + } } void close() { @@ -103,6 +111,24 @@ abstract class MoneroWalletBase extends WalletBase with Store { _onAccountChangeReaction?.reaction?.dispose(); } + Future validate() async { + await accountList.update(); + final accountListLength = accountList.accounts?.length ?? 0; + + if (accountListLength <= 0) { + return false; + } + + subaddressList.update(accountIndex: accountList.accounts.first.id); + final subaddressListLength = subaddressList.subaddresses?.length ?? 0; + + if (subaddressListLength <= 0) { + return false; + } + + return true; + } + @override Future connectToNode({@required Node node}) async { try { @@ -275,8 +301,6 @@ abstract class MoneroWalletBase extends WalletBase with Store { return; } - syncStatus = SyncedSyncStatus(); - if (walletInfo.isRecovery) { _askForUpdateTransactionHistory(); _askForUpdateBalance(); @@ -285,11 +309,19 @@ abstract class MoneroWalletBase extends WalletBase with Store { final currentHeight = getCurrentHeight(); final nodeHeight = monero_wallet.getNodeHeightSync(); - if (walletInfo.isRecovery && - (nodeHeight - currentHeight < moneroBlockSize)) { - await setAsRecovered(); + if (nodeHeight - currentHeight < moneroBlockSize) { + syncStatus = SyncedSyncStatus(); + + if (walletInfo.isRecovery) { + await setAsRecovered(); + } } + // if (walletInfo.isRecovery && + // (nodeHeight - currentHeight < moneroBlockSize)) { + // await setAsRecovered(); + // } + if (currentHeight - _cachedRefreshHeight > moneroBlockSize) { _cachedRefreshHeight = currentHeight; await save(); diff --git a/lib/monero/monero_wallet_service.dart b/lib/monero/monero_wallet_service.dart index 5461d94d4..ac44147a4 100644 --- a/lib/monero/monero_wallet_service.dart +++ b/lib/monero/monero_wallet_service.dart @@ -25,6 +25,11 @@ class MoneroRestoreWalletFromSeedCredentials extends WalletCredentials { final String mnemonic; } +class MoneroWalletLoadingException implements Exception { + @override + String toString() => 'The wallet is damaged.'; +} + class MoneroRestoreWalletFromKeysCredentials extends WalletCredentials { MoneroRestoreWalletFromKeysCredentials( {String name, @@ -88,11 +93,29 @@ class MoneroWalletService extends WalletService< Future openWallet(String name, String password) async { try { final path = await pathForWallet(name: name, type: WalletType.monero); - await monero_wallet_manager.openWalletAsync({'path': path, 'password': password}); + await monero_wallet_manager + .openWalletAsync({'path': path, 'password': password}); final walletInfo = walletInfoSource.values.firstWhere( - (info) => info.id == WalletBase.idFor(name, WalletType.monero), orElse: () => null); + (info) => info.id == WalletBase.idFor(name, WalletType.monero), + orElse: () => null); final wallet = MoneroWallet( filename: monero_wallet.getFilename(), walletInfo: walletInfo); + final isValid = await wallet.validate(); + + if (!isValid) { + if (wallet.seed?.isNotEmpty ?? false) { + // let restore from seed in this case; + final seed = wallet.seed; + final credentials = MoneroRestoreWalletFromSeedCredentials( + name: name, password: password, mnemonic: seed, height: 2000000) + ..walletInfo = walletInfo; + await remove(name); + return restoreFromSeed(credentials); + } + + throw MoneroWalletLoadingException(); + } + await wallet.init(); return wallet; @@ -104,9 +127,15 @@ class MoneroWalletService extends WalletService< } @override - Future remove(String wallet) async => - File(await pathForWalletDir(name: wallet, type: WalletType.bitcoin)) - .delete(recursive: true); + Future remove(String wallet) async { + final path = await pathForWalletDir(name: wallet, type: WalletType.monero); + final file = Directory(path); + final isExist = file.existsSync(); + + if (isExist) { + await file.delete(recursive: true); + } + } @override Future restoreFromKeys( diff --git a/lib/src/widgets/annotated_editable_text.dart b/lib/src/widgets/annotated_editable_text.dart index 1d2ada1fb..cc42d9b35 100644 --- a/lib/src/widgets/annotated_editable_text.dart +++ b/lib/src/widgets/annotated_editable_text.dart @@ -32,42 +32,41 @@ class AnnotatedEditableText extends EditableText { Color selectionColor, Color backgroundCursorColor, TextSelectionControls selectionControls, + TextStyle textStyle = const TextStyle( + color: Colors.black, + backgroundColor: Colors.transparent, + fontWeight: FontWeight.normal, + fontSize: 16), @required this.words, }) : textAnnotations = words - .map((word) => TextAnnotation( - text: word, - style: TextStyle( - color: Colors.black, - backgroundColor: Colors.transparent, - fontWeight: FontWeight.normal, - fontSize: 16))) - .toList(), + .map((word) => TextAnnotation(text: word, style: textStyle)) + .toList(), super( - maxLines: null, - key: key, - focusNode: focusNode, - controller: controller, - cursorColor: cursorColor, - style: style, - keyboardType: TextInputType.text, - autocorrect: false, - autofocus: false, - selectionColor: selectionColor, - selectionControls: selectionControls, - backgroundCursorColor: backgroundCursorColor, - onChanged: onChanged, - onSubmitted: onSubmitted, - toolbarOptions: const ToolbarOptions( - copy: true, - cut: true, - paste: true, - selectAll: true, - ), - enableSuggestions: false, - enableInteractiveSelection: true, - showSelectionHandles: true, - showCursor: true, - ) { + maxLines: null, + key: key, + focusNode: focusNode, + controller: controller, + cursorColor: cursorColor, + style: style, + keyboardType: TextInputType.text, + autocorrect: false, + autofocus: false, + selectionColor: selectionColor, + selectionControls: selectionControls, + backgroundCursorColor: backgroundCursorColor, + onChanged: onChanged, + onSubmitted: onSubmitted, + toolbarOptions: const ToolbarOptions( + copy: true, + cut: true, + paste: true, + selectAll: true, + ), + enableSuggestions: false, + enableInteractiveSelection: true, + showSelectionHandles: true, + showCursor: true, + ) { textAnnotations.add(TextAnnotation( text: ' ', style: TextStyle(backgroundColor: Colors.transparent))); } @@ -86,7 +85,7 @@ class AnnotatedEditableTextState extends EditableTextState { List getRanges() { final source = widget.textAnnotations .map((item) => range(item.text, textEditingValue.text) - .map((range) => Annotation(style: item.style, range: range))) + .map((range) => Annotation(style: item.style, range: range))) .expand((e) => e) .toList(); final result = List(); @@ -123,7 +122,7 @@ class AnnotatedEditableTextState extends EditableTextState { if (result.length > 0 && result.last.range.end < text.length) { result.add(Annotation( range: TextRange(start: result.last.range.end, end: text.length), - style: TextStyle( backgroundColor: Colors.transparent))); + style: TextStyle(backgroundColor: Colors.transparent))); } return result; } @@ -132,8 +131,8 @@ class AnnotatedEditableTextState extends EditableTextState { final result = List(); for (int index = source.indexOf(pattern); - index >= 0; - index = source.indexOf(pattern, index + 1)) { + index >= 0; + index = source.indexOf(pattern, index + 1)) { final start = index; final end = start + pattern.length; result.add(TextRange(start: start, end: end)); @@ -152,10 +151,10 @@ class AnnotatedEditableTextState extends EditableTextState { style: widget.style, children: ranges .map((item) => TextSpan( - style: item.style, text: item.range.textInside(text))) + style: item.style, text: item.range.textInside(text))) .toList()); } return TextSpan(style: widget.style, text: text); } -} \ No newline at end of file +} diff --git a/lib/src/widgets/seed_widget.dart b/lib/src/widgets/seed_widget.dart index d77828d73..05589cdad 100644 --- a/lib/src/widgets/seed_widget.dart +++ b/lib/src/widgets/seed_widget.dart @@ -78,16 +78,22 @@ class SeedWidgetState extends State { Padding( padding: EdgeInsets.only(right: 40, top: 10), child: AnnotatedEditableText( - cursorColor: Colors.green, - backgroundCursorColor: Colors.blue, - style: TextStyle( - fontSize: 20, - color: Colors.red, - fontWeight: FontWeight.normal, - backgroundColor: Colors.transparent), - focusNode: focusNode, - controller: controller, - words: words)), + cursorColor: Colors.blue, + backgroundCursorColor: Colors.blue, + style: TextStyle( + fontSize: 16, + color: Colors.red, + fontWeight: FontWeight.normal, + backgroundColor: Colors.transparent), + focusNode: focusNode, + controller: controller, + words: words, + textStyle: TextStyle( + color: Theme.of(context).primaryTextTheme.title.color, + backgroundColor: Colors.transparent, + fontWeight: FontWeight.normal, + fontSize: 16), + )), Positioned( top: 0, right: 0, diff --git a/lib/view_model/wallet_creation_vm.dart b/lib/view_model/wallet_creation_vm.dart index 01893c954..d29002f2b 100644 --- a/lib/view_model/wallet_creation_vm.dart +++ b/lib/view_model/wallet_creation_vm.dart @@ -34,8 +34,8 @@ abstract class WalletCreationVMBase with Store { Future create({dynamic options}) async { try { - name = await generateName(); state = IsExecutingState(); + name = await generateName(); final dirPath = await pathForWalletDir(name: name, type: type); final path = await pathForWallet(name: name, type: type); final credentials = getCredentials(options); diff --git a/lib/view_model/wallet_restore_view_model.dart b/lib/view_model/wallet_restore_view_model.dart index 52e95b818..4c2411a23 100644 --- a/lib/view_model/wallet_restore_view_model.dart +++ b/lib/view_model/wallet_restore_view_model.dart @@ -55,7 +55,8 @@ abstract class WalletRestoreViewModelBase extends WalletCreationVM with Store { spendKey: spendKey, viewKey: viewKey, address: address, - password: password); + password: password, + language: 'English'); } return null; diff --git a/pubspec.lock b/pubspec.lock index f4bf8a412..6a626d9cf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "11.0.0" + version: "12.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "0.40.4" + version: "0.40.5" archive: dependency: transitive description: @@ -140,7 +140,7 @@ packages: name: build_runner url: "https://pub.dartlang.org" source: hosted - version: "1.10.3" + version: "1.10.4" build_runner_core: dependency: transitive description: @@ -575,14 +575,14 @@ packages: name: mobx url: "https://pub.dartlang.org" source: hosted - version: "1.2.1+3" + version: "1.2.1+4" mobx_codegen: dependency: "direct dev" description: name: mobx_codegen url: "https://pub.dartlang.org" source: hosted - version: "1.1.1+1" + version: "1.1.1+3" node_interop: dependency: transitive description: @@ -729,7 +729,7 @@ packages: name: protobuf url: "https://pub.dartlang.org" source: hosted - version: "1.0.1" + version: "1.1.0" provider: dependency: "direct main" description: @@ -764,7 +764,7 @@ packages: name: quiver url: "https://pub.dartlang.org" source: hosted - version: "2.1.3" + version: "2.1.4+1" rxdart: dependency: "direct main" description: @@ -778,7 +778,7 @@ packages: name: share url: "https://pub.dartlang.org" source: hosted - version: "0.6.5+3" + version: "0.6.5+4" shared_preferences: dependency: "direct main" description: @@ -853,7 +853,7 @@ packages: name: source_gen url: "https://pub.dartlang.org" source: hosted - version: "0.9.7+1" + version: "0.9.8" source_span: dependency: transitive description: @@ -1023,5 +1023,5 @@ packages: source: hosted version: "2.2.1" sdks: - dart: ">=2.10.0-110 <2.11.0" + dart: ">=2.10.0 <2.11.0" flutter: ">=1.22.0 <2.0.0"