mirror of
https://github.com/cake-tech/cake_wallet.git
synced 2025-01-08 20:09:24 +00:00
Merge remote-tracking branch 'origin/main' into CW-453-silent-payments
This commit is contained in:
commit
dc86968022
15 changed files with 95 additions and 62 deletions
|
@ -1,2 +1,4 @@
|
|||
Bitcoin Silent Payments
|
||||
Add Tron wallet
|
||||
Add Tron wallet
|
||||
Hardware wallets enhancements
|
||||
Bug fixes
|
||||
|
|
|
@ -28,6 +28,12 @@ Map<DerivationType, List<DerivationInfo>> electrum_derivations = {
|
|||
description: "Standard BIP84 native segwit",
|
||||
scriptType: "p2wpkh",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/86'/0'/0'",
|
||||
description: "Standard BIP86 Taproot",
|
||||
scriptType: "p2tr",
|
||||
),
|
||||
DerivationInfo(
|
||||
derivationType: DerivationType.bip39,
|
||||
derivationPath: "m/0'",
|
||||
|
|
|
@ -14,7 +14,6 @@ import 'package:cw_bitcoin/electrum_wallet.dart';
|
|||
import 'package:cw_bitcoin/bitcoin_address_record.dart';
|
||||
import 'package:cw_bitcoin/electrum_balance.dart';
|
||||
import 'package:cw_bitcoin/litecoin_network.dart';
|
||||
import 'package:bitcoin_flutter/bitcoin_flutter.dart' as bitcoin;
|
||||
import 'package:bip39/bip39.dart' as bip39;
|
||||
|
||||
part 'litecoin_wallet.g.dart';
|
||||
|
|
|
@ -377,6 +377,9 @@ class CWBitcoin extends Bitcoin {
|
|||
case "p2wpkh-p2sh":
|
||||
address = generateP2SHAddress(hd: hd, network: network);
|
||||
break;
|
||||
case "p2tr":
|
||||
address = generateP2TRAddress(hd: hd, network: network);
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -281,17 +281,19 @@ class MoonPayProvider extends BuyProvider {
|
|||
throw Exception('Could not launch URL');
|
||||
}
|
||||
} catch (e) {
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: 'MoonPay',
|
||||
alertContent: 'The MoonPay service is currently unavailable: $e',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop(),
|
||||
);
|
||||
},
|
||||
);
|
||||
if (context.mounted) {
|
||||
await showDialog<void>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
return AlertWithOneAction(
|
||||
alertTitle: 'MoonPay',
|
||||
alertContent: 'The MoonPay service is currently unavailable: $e',
|
||||
buttonText: S.of(context).ok,
|
||||
buttonAction: () => Navigator.of(context).pop(),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
lib/di.dart
17
lib/di.dart
|
@ -313,7 +313,6 @@ Future<void> setup({
|
|||
getIt.registerFactory<Box<Node>>(() => _powNodeSource, instanceName: Node.boxName + "pow");
|
||||
|
||||
getIt.registerSingleton(AuthenticationStore());
|
||||
getIt.registerSingleton(LedgerViewModel());
|
||||
getIt.registerSingleton<WalletListStore>(WalletListStore());
|
||||
getIt.registerSingleton(NodeListStoreBase.instance);
|
||||
getIt.registerSingleton<SettingsStore>(settingsStore);
|
||||
|
@ -337,6 +336,8 @@ Future<void> setup({
|
|||
getIt.registerSingleton<AnonpayTransactionsStore>(
|
||||
AnonpayTransactionsStore(anonpayInvoiceInfoSource: _anonpayInvoiceInfoSource));
|
||||
|
||||
getIt.registerLazySingleton(() => LedgerViewModel());
|
||||
|
||||
final secretStore = await SecretStoreBase.load(getIt.get<SecureStorage>());
|
||||
|
||||
getIt.registerSingleton<SecretStore>(secretStore);
|
||||
|
@ -626,7 +627,7 @@ Future<void> setup({
|
|||
getIt.get<BalanceViewModel>(),
|
||||
getIt.get<ContactListViewModel>(),
|
||||
_transactionDescriptionBox,
|
||||
getIt.get<LedgerViewModel>(),
|
||||
getIt.get<AppStore>().wallet!.isHardwareWallet ? getIt.get<LedgerViewModel>() : null,
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -839,10 +840,14 @@ Future<void> setup({
|
|||
isSelected: isSelected));
|
||||
|
||||
getIt.registerFactory<RobinhoodBuyProvider>(() => RobinhoodBuyProvider(
|
||||
wallet: getIt.get<AppStore>().wallet!, ledgerVM: getIt.get<LedgerViewModel>()));
|
||||
wallet: getIt.get<AppStore>().wallet!,
|
||||
ledgerVM:
|
||||
getIt.get<AppStore>().wallet!.isHardwareWallet ? getIt.get<LedgerViewModel>() : null));
|
||||
|
||||
getIt.registerFactory<DFXBuyProvider>(() => DFXBuyProvider(
|
||||
wallet: getIt.get<AppStore>().wallet!, ledgerVM: getIt.get<LedgerViewModel>()));
|
||||
wallet: getIt.get<AppStore>().wallet!,
|
||||
ledgerVM:
|
||||
getIt.get<AppStore>().wallet!.isHardwareWallet ? getIt.get<LedgerViewModel>() : null));
|
||||
|
||||
getIt.registerFactory<MoonPayProvider>(() => MoonPayProvider(
|
||||
settingsStore: getIt.get<AppStore>().settingsStore,
|
||||
|
@ -948,9 +953,9 @@ Future<void> setup({
|
|||
(derivations, _) => WalletRestoreChooseDerivationViewModel(derivationInfos: derivations));
|
||||
|
||||
getIt.registerFactoryParam<WalletRestoreChooseDerivationPage, List<DerivationInfo>, void>(
|
||||
(credentials, _) =>
|
||||
(derivations, _) =>
|
||||
WalletRestoreChooseDerivationPage(getIt.get<WalletRestoreChooseDerivationViewModel>(
|
||||
param1: credentials,
|
||||
param1: derivations,
|
||||
)));
|
||||
|
||||
getIt.registerFactoryParam<TransactionDetailsViewModel, TransactionInfo, void>(
|
||||
|
|
|
@ -67,6 +67,7 @@ class PreferencesKey {
|
|||
static const lookupsUnstoppableDomains = 'looks_up_unstoppable_domain';
|
||||
static const lookupsOpenAlias = 'looks_up_open_alias';
|
||||
static const lookupsENS = 'looks_up_ens';
|
||||
static const showCameraConsent = 'show_camera_consent';
|
||||
|
||||
static String moneroWalletUpdateV1Key(String name) =>
|
||||
'${PreferencesKey.moneroWalletPasswordUpdateV1Base}_${name}';
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
import 'package:cake_wallet/di.dart';
|
||||
import 'package:cake_wallet/entities/preferences_key.dart';
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
|
||||
import 'package:cake_wallet/utils/permission_handler.dart';
|
||||
import 'package:cake_wallet/utils/show_pop_up.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class WebViewPage extends BasePage {
|
||||
WebViewPage(this._title, this._url);
|
||||
|
@ -42,8 +46,9 @@ class WebViewPageBodyState extends State<WebViewPageBody> {
|
|||
),
|
||||
initialUrlRequest: URLRequest(url: WebUri.uri(widget.uri)),
|
||||
onPermissionRequest: (controller, request) async {
|
||||
bool permissionGranted = await Permission.camera.status == PermissionStatus.granted;
|
||||
if (!permissionGranted) {
|
||||
final sharedPrefs = getIt.get<SharedPreferences>();
|
||||
|
||||
if (sharedPrefs.getBool(PreferencesKey.showCameraConsent) ?? true) {
|
||||
final bool userConsent = await showPopUp<bool>(
|
||||
context: context,
|
||||
builder: (BuildContext context) {
|
||||
|
@ -65,9 +70,12 @@ class WebViewPageBodyState extends State<WebViewPageBody> {
|
|||
);
|
||||
}
|
||||
|
||||
permissionGranted = await Permission.camera.request().isGranted;
|
||||
sharedPrefs.setBool(PreferencesKey.showCameraConsent, false);
|
||||
}
|
||||
|
||||
bool permissionGranted =
|
||||
await PermissionHandler.checkPermission(Permission.camera, context);
|
||||
|
||||
return PermissionResponse(
|
||||
resources: request.resources,
|
||||
action: permissionGranted
|
||||
|
|
|
@ -3,7 +3,7 @@ import 'dart:io';
|
|||
|
||||
import 'package:cake_wallet/generated/i18n.dart';
|
||||
import 'package:cake_wallet/src/screens/base_page.dart';
|
||||
// import 'package:cake_wallet/src/screens/connect_device/debug_device_page.dart';
|
||||
import 'package:cake_wallet/src/screens/connect_device/debug_device_page.dart';
|
||||
import 'package:cake_wallet/src/screens/connect_device/widgets/device_tile.dart';
|
||||
import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
|
||||
import 'package:cake_wallet/utils/responsive_layout_util.dart';
|
||||
|
@ -105,7 +105,7 @@ class ConnectDevicePageBodyState extends State<ConnectDevicePageBody> {
|
|||
try {
|
||||
_bleRefresh = ledger.scan().listen((device) => setState(() => bleDevices.add(device)))
|
||||
..onError((e) {
|
||||
throw e as Exception;
|
||||
throw e.toString();
|
||||
});
|
||||
setState(() => bleIsEnabled = true);
|
||||
_bleRefreshTimer?.cancel();
|
||||
|
|
|
@ -36,7 +36,6 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_mobx/flutter_mobx.dart';
|
||||
import 'package:mobx/mobx.dart';
|
||||
import 'package:smooth_page_indicator/smooth_page_indicator.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class SendPage extends BasePage {
|
||||
|
@ -374,17 +373,17 @@ class SendPage extends BasePage {
|
|||
}
|
||||
|
||||
if (sendViewModel.wallet.isHardwareWallet) {
|
||||
if (!sendViewModel.ledgerViewModel.isConnected) {
|
||||
if (!sendViewModel.ledgerViewModel!.isConnected) {
|
||||
await Navigator.of(context).pushNamed(Routes.connectDevices,
|
||||
arguments: ConnectDevicePageParams(
|
||||
walletType: sendViewModel.walletType,
|
||||
onConnectDevice: (BuildContext context, _) {
|
||||
sendViewModel.ledgerViewModel.setLedger(sendViewModel.wallet);
|
||||
sendViewModel.ledgerViewModel!.setLedger(sendViewModel.wallet);
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
));
|
||||
} else {
|
||||
sendViewModel.ledgerViewModel.setLedger(sendViewModel.wallet);
|
||||
sendViewModel.ledgerViewModel!.setLedger(sendViewModel.wallet);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -363,6 +363,8 @@ abstract class DashboardViewModelBase with Store {
|
|||
.toList();
|
||||
}
|
||||
|
||||
bool get hasBuyProviders => ProvidersHelper.getAvailableBuyProviderTypes(wallet.type).isNotEmpty;
|
||||
|
||||
List<BuyProvider> get availableSellProviders {
|
||||
final providerTypes = ProvidersHelper.getAvailableSellProviderTypes(wallet.type);
|
||||
return providerTypes
|
||||
|
@ -372,6 +374,8 @@ abstract class DashboardViewModelBase with Store {
|
|||
.toList();
|
||||
}
|
||||
|
||||
bool get hasSellProviders => ProvidersHelper.getAvailableSellProviderTypes(wallet.type).isNotEmpty;
|
||||
|
||||
bool get shouldShowYatPopup => settingsStore.shouldShowYatPopup;
|
||||
|
||||
@action
|
||||
|
@ -384,13 +388,13 @@ abstract class DashboardViewModelBase with Store {
|
|||
bool hasExchangeAction;
|
||||
|
||||
@computed
|
||||
bool get isEnabledBuyAction => !settingsStore.disableBuy && availableBuyProviders.isNotEmpty;
|
||||
bool get isEnabledBuyAction => !settingsStore.disableBuy && hasBuyProviders;
|
||||
|
||||
@observable
|
||||
bool hasBuyAction;
|
||||
|
||||
@computed
|
||||
bool get isEnabledSellAction => !settingsStore.disableSell && availableSellProviders.isNotEmpty;
|
||||
bool get isEnabledSellAction => !settingsStore.disableSell && hasSellProviders;
|
||||
|
||||
@observable
|
||||
bool hasSellAction;
|
||||
|
@ -529,34 +533,38 @@ abstract class DashboardViewModelBase with Store {
|
|||
void setSyncAll(bool value) => settingsStore.currentSyncAll = value;
|
||||
|
||||
Future<List<String>> checkAffectedWallets() async {
|
||||
// await load file
|
||||
final vulnerableSeedsString = await rootBundle
|
||||
.loadString('assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt');
|
||||
final vulnerableSeeds = vulnerableSeedsString.split("\n");
|
||||
try {
|
||||
// await load file
|
||||
final vulnerableSeedsString = await rootBundle
|
||||
.loadString('assets/text/cakewallet_weak_bitcoin_seeds_hashed_sorted_version1.txt');
|
||||
final vulnerableSeeds = vulnerableSeedsString.split("\n");
|
||||
|
||||
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
final walletInfoSource = await CakeHive.openBox<WalletInfo>(WalletInfo.boxName);
|
||||
|
||||
List<String> affectedWallets = [];
|
||||
for (var walletInfo in walletInfoSource.values) {
|
||||
if (walletInfo.type == WalletType.bitcoin) {
|
||||
final password = await keyService.getWalletPassword(walletName: walletInfo.name);
|
||||
final path = await pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final mnemonic = data['mnemonic'] as String?;
|
||||
List<String> affectedWallets = [];
|
||||
for (var walletInfo in walletInfoSource.values) {
|
||||
if (walletInfo.type == WalletType.bitcoin) {
|
||||
final password = await keyService.getWalletPassword(walletName: walletInfo.name);
|
||||
final path = await pathForWallet(name: walletInfo.name, type: walletInfo.type);
|
||||
final jsonSource = await read(path: path, password: password);
|
||||
final data = json.decode(jsonSource) as Map;
|
||||
final mnemonic = data['mnemonic'] as String?;
|
||||
|
||||
if (mnemonic == null) continue;
|
||||
if (mnemonic == null) continue;
|
||||
|
||||
final hash = await Cryptography.instance.sha256().hash(utf8.encode(mnemonic));
|
||||
final seedSha = bytesToHex(hash.bytes);
|
||||
final hash = await Cryptography.instance.sha256().hash(utf8.encode(mnemonic));
|
||||
final seedSha = bytesToHex(hash.bytes);
|
||||
|
||||
if (vulnerableSeeds.contains(seedSha)) {
|
||||
affectedWallets.add(walletInfo.name);
|
||||
if (vulnerableSeeds.contains(seedSha)) {
|
||||
affectedWallets.add(walletInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return affectedWallets;
|
||||
return affectedWallets;
|
||||
} catch (_) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
Future<ServicesResponse> getServicesStatus() async {
|
||||
|
|
|
@ -272,7 +272,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
|||
final SendTemplateViewModel sendTemplateViewModel;
|
||||
final BalanceViewModel balanceViewModel;
|
||||
final ContactListViewModel contactListViewModel;
|
||||
final LedgerViewModel ledgerViewModel;
|
||||
final LedgerViewModel? ledgerViewModel;
|
||||
final FiatConversionStore _fiatConversationStore;
|
||||
final Box<TransactionDescription> transactionDescriptionBox;
|
||||
|
||||
|
@ -368,7 +368,7 @@ abstract class SendViewModelBase extends WalletChangeListenerViewModel with Stor
|
|||
final errorCode = e.errorCode.toRadixString(16);
|
||||
final fallbackMsg =
|
||||
e.message.isNotEmpty ? e.message : "Unexpected Ledger Error Code: $errorCode";
|
||||
final errorMsg = ledgerViewModel.interpretErrorCode(errorCode) ?? fallbackMsg;
|
||||
final errorMsg = ledgerViewModel!.interpretErrorCode(errorCode) ?? fallbackMsg;
|
||||
|
||||
state = FailureState(errorMsg);
|
||||
} else {
|
||||
|
|
|
@ -15,15 +15,15 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
|
|||
APP_ANDROID_TYPE=$1
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.13.2"
|
||||
MONERO_COM_BUILD_NUMBER=88
|
||||
MONERO_COM_VERSION="1.14.0"
|
||||
MONERO_COM_BUILD_NUMBER=89
|
||||
MONERO_COM_BUNDLE_ID="com.monero.app"
|
||||
MONERO_COM_PACKAGE="com.monero.app"
|
||||
MONERO_COM_SCHEME="monero.com"
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.17.0"
|
||||
CAKEWALLET_BUILD_NUMBER=213
|
||||
CAKEWALLET_BUILD_NUMBER=215
|
||||
CAKEWALLET_BUNDLE_ID="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_PACKAGE="com.cakewallet.cake_wallet"
|
||||
CAKEWALLET_SCHEME="cakewallet"
|
||||
|
@ -72,4 +72,4 @@ export APP_ANDROID_VERSION
|
|||
export APP_ANDROID_BUILD_NUMBER
|
||||
export APP_ANDROID_BUNDLE_ID
|
||||
export APP_ANDROID_PACKAGE
|
||||
export APP_ANDROID_SCHEME
|
||||
export APP_ANDROID_SCHEME
|
||||
|
|
|
@ -13,13 +13,13 @@ TYPES=($MONERO_COM $CAKEWALLET $HAVEN)
|
|||
APP_IOS_TYPE=$1
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.13.2"
|
||||
MONERO_COM_BUILD_NUMBER=86
|
||||
MONERO_COM_VERSION="1.14.0"
|
||||
MONERO_COM_BUILD_NUMBER=87
|
||||
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="4.17.0"
|
||||
CAKEWALLET_BUILD_NUMBER=241
|
||||
CAKEWALLET_BUILD_NUMBER=244
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
HAVEN_NAME="Haven"
|
||||
|
|
|
@ -16,13 +16,13 @@ if [ -n "$1" ]; then
|
|||
fi
|
||||
|
||||
MONERO_COM_NAME="Monero.com"
|
||||
MONERO_COM_VERSION="1.3.2"
|
||||
MONERO_COM_BUILD_NUMBER=19
|
||||
MONERO_COM_VERSION="1.4.0"
|
||||
MONERO_COM_BUILD_NUMBER=20
|
||||
MONERO_COM_BUNDLE_ID="com.cakewallet.monero"
|
||||
|
||||
CAKEWALLET_NAME="Cake Wallet"
|
||||
CAKEWALLET_VERSION="1.10.0"
|
||||
CAKEWALLET_BUILD_NUMBER=75
|
||||
CAKEWALLET_BUILD_NUMBER=76
|
||||
CAKEWALLET_BUNDLE_ID="com.fotolockr.cakewallet"
|
||||
|
||||
if ! [[ " ${TYPES[*]} " =~ " ${APP_MACOS_TYPE} " ]]; then
|
||||
|
|
Loading…
Reference in a new issue