Merge branch 'main' of https://github.com/cake-tech/cake_wallet into MrCyjaneK-cyjan-monerodart

 Conflicts:
	cw_monero/example/pubspec.lock
	lib/main.dart
This commit is contained in:
OmarHatem 2024-05-14 02:57:11 +03:00
commit 2c978fc693
10 changed files with 220 additions and 93 deletions

View file

@ -1 +1 @@
Generic bug fixes and enhancements Bug fixes and generic enhancements

View file

@ -1,3 +1 @@
Hardware wallets support for Bitcoin, Ethereum and Polygon
Security enhancements
Bug fixes and generic enhancements Bug fixes and generic enhancements

View file

@ -5,9 +5,6 @@ import 'package:cw_core/format_amount.dart';
import 'package:cw_core/hive_type_ids.dart'; import 'package:cw_core/hive_type_ids.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
part 'trade.g.dart';
@HiveType(typeId: Trade.typeId)
class Trade extends HiveObject { class Trade extends HiveObject {
Trade({ Trade({
required this.id, required this.id,
@ -32,6 +29,7 @@ class Trade extends HiveObject {
this.txId, this.txId,
this.isRefund, this.isRefund,
this.isSendAll, this.isSendAll,
this.router,
}) { }) {
if (provider != null) providerRaw = provider.raw; if (provider != null) providerRaw = provider.raw;
@ -121,21 +119,26 @@ class Trade extends HiveObject {
@HiveField(21) @HiveField(21)
bool? isSendAll; bool? isSendAll;
@HiveField(22)
String? router;
static Trade fromMap(Map<String, Object?> map) { static Trade fromMap(Map<String, Object?> map) {
return Trade( return Trade(
id: map['id'] as String, id: map['id'] as String,
provider: ExchangeProviderDescription.deserialize(raw: map['provider'] as int), provider: ExchangeProviderDescription.deserialize(raw: map['provider'] as int),
from: CryptoCurrency.deserialize(raw: map['input'] as int), from: CryptoCurrency.deserialize(raw: map['input'] as int),
to: CryptoCurrency.deserialize(raw: map['output'] as int), to: CryptoCurrency.deserialize(raw: map['output'] as int),
createdAt: createdAt:
map['date'] != null ? DateTime.fromMillisecondsSinceEpoch(map['date'] as int) : null, map['date'] != null ? DateTime.fromMillisecondsSinceEpoch(map['date'] as int) : null,
amount: map['amount'] as String, amount: map['amount'] as String,
walletId: map['wallet_id'] as String, walletId: map['wallet_id'] as String,
fromWalletAddress: map['from_wallet_address'] as String?, fromWalletAddress: map['from_wallet_address'] as String?,
memo: map['memo'] as String?, memo: map['memo'] as String?,
txId: map['tx_id'] as String?, txId: map['tx_id'] as String?,
isRefund: map['isRefund'] as bool?, isRefund: map['isRefund'] as bool?,
isSendAll: map['isSendAll'] as bool?); isSendAll: map['isSendAll'] as bool?,
router: map['router'] as String?,
);
} }
Map<String, dynamic> toMap() { Map<String, dynamic> toMap() {
@ -152,8 +155,111 @@ class Trade extends HiveObject {
'tx_id': txId, 'tx_id': txId,
'isRefund': isRefund, 'isRefund': isRefund,
'isSendAll': isSendAll, 'isSendAll': isSendAll,
'router': router,
}; };
} }
String amountFormatted() => formatAmount(amount); String amountFormatted() => formatAmount(amount);
} }
class TradeAdapter extends TypeAdapter<Trade> {
@override
final int typeId = Trade.typeId;
@override
Trade read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{};
for (int i = 0; i < numOfFields; i++) {
try {
fields[reader.readByte()] = reader.read();
} catch (_) {}
}
return Trade(
id: fields[0] == null ? '' : fields[0] as String,
amount: fields[7] == null ? '' : fields[7] as String,
createdAt: fields[5] as DateTime?,
expiredAt: fields[6] as DateTime?,
inputAddress: fields[8] as String?,
extraId: fields[9] as String?,
outputTransaction: fields[10] as String?,
refundAddress: fields[11] as String?,
walletId: fields[12] as String?,
payoutAddress: fields[13] as String?,
password: fields[14] as String?,
providerId: fields[15] as String?,
providerName: fields[16] as String?,
fromWalletAddress: fields[17] as String?,
memo: fields[18] as String?,
txId: fields[19] as String?,
isRefund: fields[20] as bool?,
isSendAll: fields[21] as bool?,
router: fields[22] as String?,
)
..providerRaw = fields[1] == null ? 0 : fields[1] as int
..fromRaw = fields[2] == null ? 0 : fields[2] as int
..toRaw = fields[3] == null ? 0 : fields[3] as int
..stateRaw = fields[4] == null ? '' : fields[4] as String;
}
@override
void write(BinaryWriter writer, Trade obj) {
writer
..writeByte(23)
..writeByte(0)
..write(obj.id)
..writeByte(1)
..write(obj.providerRaw)
..writeByte(2)
..write(obj.fromRaw)
..writeByte(3)
..write(obj.toRaw)
..writeByte(4)
..write(obj.stateRaw)
..writeByte(5)
..write(obj.createdAt)
..writeByte(6)
..write(obj.expiredAt)
..writeByte(7)
..write(obj.amount)
..writeByte(8)
..write(obj.inputAddress)
..writeByte(9)
..write(obj.extraId)
..writeByte(10)
..write(obj.outputTransaction)
..writeByte(11)
..write(obj.refundAddress)
..writeByte(12)
..write(obj.walletId)
..writeByte(13)
..write(obj.payoutAddress)
..writeByte(14)
..write(obj.password)
..writeByte(15)
..write(obj.providerId)
..writeByte(16)
..write(obj.providerName)
..writeByte(17)
..write(obj.fromWalletAddress)
..writeByte(18)
..write(obj.memo)
..writeByte(19)
..write(obj.txId)
..writeByte(20)
..write(obj.isRefund)
..writeByte(21)
..write(obj.isSendAll)
..writeByte(22)
..write(obj.router);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is TradeAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
}

View file

@ -42,12 +42,34 @@ import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';
import 'package:cw_core/root_dir.dart'; import 'package:cw_core/root_dir.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/router.dart' as Router;
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/reactions/bootstrap.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/entities/transaction_description.dart';
import 'package:cake_wallet/entities/get_encryption_key.dart';
import 'package:cake_wallet/entities/contact.dart';
import 'package:cw_core/node.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/entities/default_settings_migration.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cake_wallet/entities/template.dart';
import 'package:cake_wallet/exchange/trade.dart';
import 'package:cake_wallet/exchange/exchange_template.dart';
import 'package:cake_wallet/src/screens/root/root.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:cake_wallet/monero/monero.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:uni_links/uni_links.dart'; import 'package:uni_links/uni_links.dart';
import 'package:cw_core/window_size.dart'; import 'package:cw_core/window_size.dart';
final navigatorKey = GlobalKey<NavigatorState>(); final navigatorKey = GlobalKey<NavigatorState>();
final rootKey = GlobalKey<RootState>(); final rootKey = GlobalKey<RootState>();
final RouteObserver<PageRoute> routeObserver = RouteObserver<PageRoute>(); final RouteObserver<PageRoute<dynamic>> routeObserver = RouteObserver<PageRoute<dynamic>>();
Future<void> main() async { Future<void> main() async {
await runZonedGuarded(() async { await runZonedGuarded(() async {
@ -71,6 +93,31 @@ Future<void> main() async {
runApp(App()); runApp(App());
}, (error, stackTrace) async { }, (error, stackTrace) async {
runApp(
MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
body: SingleChildScrollView(
child: Container(
margin: EdgeInsets.only(top: 50, left: 20, right: 20, bottom: 20),
child: Column(
children: [
Text(
'Error:\n${error.toString()}',
style: TextStyle(fontSize: 22),
),
Text(
'Stack trace:\n${stackTrace.toString()}',
style: TextStyle(fontSize: 16),
),
],
),
),
),
),
),
);
ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace)); ExceptionHandler.onError(FlutterErrorDetails(exception: error, stack: stackTrace));
}); });
} }
@ -231,61 +278,6 @@ class App extends StatefulWidget {
} }
class AppState extends State<App> with SingleTickerProviderStateMixin { class AppState extends State<App> with SingleTickerProviderStateMixin {
AppState() : yatStore = getIt.get<YatStore>();
YatStore yatStore;
StreamSubscription? stream;
@override
void initState() {
super.initState();
//_handleIncomingLinks();
//_handleInitialUri();
}
Future<void> _handleInitialUri() async {
try {
final uri = await getInitialUri();
print('uri: $uri');
if (uri == null) {
return;
}
if (!mounted) return;
//_fetchEmojiFromUri(uri);
} catch (e) {
if (!mounted) return;
print(e.toString());
}
}
void _handleIncomingLinks() {
if (!kIsWeb) {
stream = getUriLinksStream().listen((Uri? uri) {
print('uri: $uri');
if (!mounted) return;
//_fetchEmojiFromUri(uri);
}, onError: (Object error) {
if (!mounted) return;
print('Error: $error');
});
}
}
void _fetchEmojiFromUri(Uri uri) {
//final queryParameters = uri.queryParameters;
//if (queryParameters?.isEmpty ?? true) {
// return;
//}
//final emoji = queryParameters['eid'];
//final refreshToken = queryParameters['refresh_token'];
//if ((emoji?.isEmpty ?? true)||(refreshToken?.isEmpty ?? true)) {
// return;
//}
//yatStore.emoji = emoji;
//yatStore.refreshToken = refreshToken;
//yatStore.emojiIncommingSC.add(emoji);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Observer(builder: (BuildContext context) { return Observer(builder: (BuildContext context) {

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:cake_wallet/core/execution_state.dart'; import 'package:cake_wallet/core/execution_state.dart';
import 'package:cake_wallet/di.dart'; import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
@ -13,6 +15,9 @@ import 'package:cake_wallet/utils/responsive_layout_util.dart';
import 'package:cake_wallet/utils/show_pop_up.dart'; import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart'; import 'package:cake_wallet/view_model/restore/restore_from_qr_vm.dart';
import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart'; import 'package:cake_wallet/view_model/restore/wallet_restore_from_qr_code.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cw_core/hardware/device_connection_type.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@ -24,6 +29,19 @@ class RestoreOptionsPage extends BasePage {
final bool isNewInstall; final bool isNewInstall;
bool get _doesSupportHardwareWallets {
if (!DeviceInfo.instance.isMobile) {
return false;
}
if (isMoneroOnly) {
return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS)
.isNotEmpty;
}
return true;
}
@override @override
Widget body(BuildContext context) { Widget body(BuildContext context) {
final imageColor = Theme.of(context).extension<OptionTileTheme>()!.titleColor; final imageColor = Theme.of(context).extension<OptionTileTheme>()!.titleColor;
@ -57,7 +75,7 @@ class RestoreOptionsPage extends BasePage {
description: S.of(context).restore_description_from_backup, description: S.of(context).restore_description_from_backup,
), ),
), ),
if (DeviceInfo.instance.isMobile) if (_doesSupportHardwareWallets)
Padding( Padding(
padding: EdgeInsets.only(top: 24), padding: EdgeInsets.only(top: 24),
child: OptionTile( child: OptionTile(

View file

@ -1,10 +1,7 @@
import 'dart:async'; import 'dart:async';
import 'package:cake_wallet/core/auth_service.dart'; import 'package:cake_wallet/core/auth_service.dart';
import 'package:cake_wallet/core/totp_request_details.dart'; import 'package:cake_wallet/core/totp_request_details.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/payment_request.dart';
import 'package:cake_wallet/view_model/link_view_model.dart'; import 'package:cake_wallet/view_model/link_view_model.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -13,7 +10,6 @@ import 'package:cake_wallet/src/screens/auth/auth_page.dart';
import 'package:cake_wallet/store/app_store.dart'; import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/authentication_store.dart'; import 'package:cake_wallet/store/authentication_store.dart';
import 'package:cake_wallet/entities/qr_scanner.dart'; import 'package:cake_wallet/entities/qr_scanner.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:mobx/mobx.dart'; import 'package:mobx/mobx.dart';
import 'package:uni_links/uni_links.dart'; import 'package:uni_links/uni_links.dart';
import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart'; import 'package:cake_wallet/src/screens/setup_2fa/setup_2fa_enter_code_page.dart';

View file

@ -1,8 +1,12 @@
import 'dart:io';
import 'package:cake_wallet/bitcoin/bitcoin.dart'; import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/ethereum/ethereum.dart'; import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/generated/i18n.dart'; import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/polygon/polygon.dart'; import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/utils/device_info.dart'; import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/wallet_type_utils.dart';
import 'package:cw_core/hardware/device_connection_type.dart';
import 'package:cw_core/wallet_base.dart'; import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart'; import 'package:cw_core/wallet_type.dart';
import 'package:ledger_flutter/ledger_flutter.dart'; import 'package:ledger_flutter/ledger_flutter.dart';
@ -11,8 +15,21 @@ import 'package:permission_handler/permission_handler.dart';
class LedgerViewModel { class LedgerViewModel {
late final Ledger ledger; late final Ledger ledger;
bool get _doesSupportHardwareWallets {
if (!DeviceInfo.instance.isMobile) {
return false;
}
if (isMoneroOnly) {
return DeviceConnectionType.supportedConnectionTypes(WalletType.monero, Platform.isIOS)
.isNotEmpty;
}
return true;
}
LedgerViewModel() { LedgerViewModel() {
if (DeviceInfo.instance.isMobile) { if (_doesSupportHardwareWallets) {
ledger = Ledger( ledger = Ledger(
options: LedgerOptions( options: LedgerOptions(
scanMode: ScanMode.balanced, scanMode: ScanMode.balanced,

View file

@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_ANDROID_TYPE=$1 APP_ANDROID_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.13.0" MONERO_COM_VERSION="1.13.1"
MONERO_COM_BUILD_NUMBER=86 MONERO_COM_BUILD_NUMBER=87
MONERO_COM_BUNDLE_ID="com.monero.app" MONERO_COM_BUNDLE_ID="com.monero.app"
MONERO_COM_PACKAGE="com.monero.app" MONERO_COM_PACKAGE="com.monero.app"
MONERO_COM_SCHEME="monero.com" MONERO_COM_SCHEME="monero.com"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.16.0" CAKEWALLET_VERSION="4.16.1"
CAKEWALLET_BUILD_NUMBER=210 CAKEWALLET_BUILD_NUMBER=211
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet" CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet" CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
CAKEWALLET_SCHEME="cakewallet" CAKEWALLET_SCHEME="cakewallet"

View file

@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
APP_IOS_TYPE=$1 APP_IOS_TYPE=$1
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.13.0" MONERO_COM_VERSION="1.13.1"
MONERO_COM_BUILD_NUMBER=84 MONERO_COM_BUILD_NUMBER=85
MONERO_COM_BUNDLE_ID="com.cakewallet.monero" MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="4.16.0" CAKEWALLET_VERSION="4.16.1"
CAKEWALLET_BUILD_NUMBER=236 CAKEWALLET_BUILD_NUMBER=239
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
HAVEN_NAME="Haven" HAVEN_NAME="Haven"

View file

@ -16,13 +16,13 @@ if [ -n "$1" ]; then
fi fi
MONERO_COM_NAME="Monero.com" MONERO_COM_NAME="Monero.com"
MONERO_COM_VERSION="1.3.0" MONERO_COM_VERSION="1.3.1"
MONERO_COM_BUILD_NUMBER=17 MONERO_COM_BUILD_NUMBER=18
MONERO_COM_BUNDLE_ID="com.cakewallet.monero" MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
CAKEWALLET_NAME="Cake Wallet" CAKEWALLET_NAME="Cake Wallet"
CAKEWALLET_VERSION="1.9.0" CAKEWALLET_VERSION="1.9.1"
CAKEWALLET_BUILD_NUMBER=71 CAKEWALLET_BUILD_NUMBER=72
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet" CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then