Skip to content

Commit

Permalink
Release 4.4.3 (#415)
Browse files Browse the repository at this point in the history
* Add ability for change password for wallets classes.

* Update generateWalletPassword

* Add WalletLoadingService

* Add update monero password after wallet loading.

* Update version for Cake Wallet to 4.4.2 (103)

* Changed version for Cake Wallet to 4.4.3 (104).

* Changed version for Cake Wallet android

* Changed version for Monero.com ios and android.
  • Loading branch information
mkyq authored Jul 19, 2022
1 parent 8fec327 commit b72443a
Show file tree
Hide file tree
Showing 25 changed files with 214 additions and 41 deletions.
7 changes: 6 additions & 1 deletion cw_bitcoin/lib/electrum_transaction_history.dart
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ abstract class ElectrumTransactionHistoryBase
}

final WalletInfo walletInfo;
final String _password;
String _password;
int _height;

Future<void> init() async => await _load();
Expand All @@ -51,6 +51,11 @@ abstract class ElectrumTransactionHistoryBase
}
}

Future<void> changePassword(String password) async {
_password = password;
await save();
}

Future<Map<String, Object>> _read() async {
final dirPath =
await pathForWalletDir(name: walletInfo.name, type: walletInfo.type);
Expand Down
9 changes: 8 additions & 1 deletion cw_bitcoin/lib/electrum_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
BitcoinWalletKeys get keys => BitcoinWalletKeys(
wif: hd.wif, privateKey: hd.privKey, publicKey: hd.pubKey);

final String _password;
String _password;
List<BitcoinUnspent> unspentCoins;
List<int> _feeRates;
Map<String, BehaviorSubject<Object>> _scripthashesUpdateSubject;
Expand Down Expand Up @@ -392,6 +392,13 @@ abstract class ElectrumWalletBase extends WalletBase<ElectrumBalance,
await transactionHistory.save();
}

@override
Future<void> changePassword(String password) async {
_password = password;
await save();
await transactionHistory.changePassword(password);
}

bitcoin.ECPair keyPairFor({@required int index}) =>
generateKeyPair(hd: hd, index: index, network: networkType);

Expand Down
2 changes: 2 additions & 0 deletions cw_core/lib/wallet_base.dart
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,6 @@ abstract class WalletBase<
Future<void> rescan({int height});

void close();

Future<void> changePassword(String password);
}
10 changes: 10 additions & 0 deletions cw_haven/ios/Classes/haven_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,16 @@ extern "C"
store_lock.unlock();
}

bool set_password(char *password, Utf8Box &error) {
bool is_changed = get_current_wallet()->setPassword(std::string(password));

if (!is_changed) {
error = Utf8Box(strdup(get_current_wallet()->errorString().c_str()));
}

return is_changed;
}

bool transaction_create(char *address, char *asset_type, char *payment_id, char *amount,
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
{
Expand Down
2 changes: 2 additions & 0 deletions cw_haven/lib/api/signatures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ typedef set_recovering_from_seed = Void Function(Int8);

typedef store_c = Void Function(Pointer<Utf8>);

typedef set_password = Int8 Function(Pointer<Utf8> password, Pointer<Utf8Box> error);

typedef set_listener = Void Function();

typedef get_syncing_height = Int64 Function();
Expand Down
2 changes: 2 additions & 0 deletions cw_haven/lib/api/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ typedef SetRecoveringFromSeed = void Function(int);

typedef Store = void Function(Pointer<Utf8>);

typedef SetPassword = int Function(Pointer<Utf8> password, Pointer<Utf8Box> error);

typedef SetListener = void Function();

typedef GetSyncingHeight = int Function();
Expand Down
19 changes: 19 additions & 0 deletions cw_haven/lib/api/wallet.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:cw_haven/api/structs/ut8_box.dart';
import 'package:cw_haven/api/convert_utf8_to_string.dart';
import 'package:cw_haven/api/signatures.dart';
import 'package:cw_haven/api/types.dart';
Expand Down Expand Up @@ -67,6 +68,9 @@ final setRecoveringFromSeedNative = havenApi
final storeNative =
havenApi.lookup<NativeFunction<store_c>>('store').asFunction<Store>();

final setPasswordNative =
havenApi.lookup<NativeFunction<set_password>>('set_password').asFunction<SetPassword>();

final setListenerNative = havenApi
.lookup<NativeFunction<set_listener>>('set_listener')
.asFunction<SetListener>();
Expand Down Expand Up @@ -193,6 +197,21 @@ void storeSync() {
free(pathPointer);
}

void setPasswordSync(String password) {
final passwordPointer = Utf8.toUtf8(password);
final errorMessagePointer = allocate<Utf8Box>();
final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0;
free(passwordPointer);

if (!changed) {
final message = errorMessagePointer.ref.getValue();
free(errorMessagePointer);
throw Exception(message);
}

free(errorMessagePointer);
}

void closeCurrentWallet() => closeCurrentWalletNative();

String getSecretViewKey() =>
Expand Down
5 changes: 5 additions & 0 deletions cw_haven/lib/haven_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,11 @@ abstract class HavenWalletBase extends WalletBase<MoneroBalance,
await haven_wallet.store();
}

@override
Future<void> changePassword(String password) async {
haven_wallet.setPasswordSync(password);
}

Future<int> getNodeHeight() async => haven_wallet.getNodeHeight();

Future<bool> isConnected() async => haven_wallet.isConnected();
Expand Down
10 changes: 10 additions & 0 deletions cw_monero/ios/Classes/monero_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,16 @@ extern "C"
store_lock.unlock();
}

bool set_password(char *password, Utf8Box &error) {
bool is_changed = get_current_wallet()->setPassword(std::string(password));

if (!is_changed) {
error = Utf8Box(strdup(get_current_wallet()->errorString().c_str()));
}

return is_changed;
}

bool transaction_create(char *address, char *payment_id, char *amount,
uint8_t priority_raw, uint32_t subaddr_account, Utf8Box &error, PendingTransactionRaw &pendingTransaction)
{
Expand Down
2 changes: 2 additions & 0 deletions cw_monero/lib/api/signatures.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ typedef set_recovering_from_seed = Void Function(Int8);

typedef store_c = Void Function(Pointer<Utf8>);

typedef set_password = Int8 Function(Pointer<Utf8> password, Pointer<Utf8Box> error);

typedef set_listener = Void Function();

typedef get_syncing_height = Int64 Function();
Expand Down
2 changes: 2 additions & 0 deletions cw_monero/lib/api/types.dart
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ typedef SetRecoveringFromSeed = void Function(int);

typedef Store = void Function(Pointer<Utf8>);

typedef SetPassword = int Function(Pointer<Utf8> password, Pointer<Utf8Box> error);

typedef SetListener = void Function();

typedef GetSyncingHeight = int Function();
Expand Down
19 changes: 19 additions & 0 deletions cw_monero/lib/api/wallet.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:ffi';
import 'package:ffi/ffi.dart';
import 'package:cw_monero/api/structs/ut8_box.dart';
import 'package:cw_monero/api/convert_utf8_to_string.dart';
import 'package:cw_monero/api/signatures.dart';
import 'package:cw_monero/api/types.dart';
Expand Down Expand Up @@ -67,6 +68,9 @@ final setRecoveringFromSeedNative = moneroApi
final storeNative =
moneroApi.lookup<NativeFunction<store_c>>('store').asFunction<Store>();

final setPasswordNative =
moneroApi.lookup<NativeFunction<set_password>>('set_password').asFunction<SetPassword>();

final setListenerNative = moneroApi
.lookup<NativeFunction<set_listener>>('set_listener')
.asFunction<SetListener>();
Expand Down Expand Up @@ -197,6 +201,21 @@ void storeSync() {
free(pathPointer);
}

void setPasswordSync(String password) {
final passwordPointer = Utf8.toUtf8(password);
final errorMessagePointer = allocate<Utf8Box>();
final changed = setPasswordNative(passwordPointer, errorMessagePointer) != 0;
free(passwordPointer);

if (!changed) {
final message = errorMessagePointer.ref.getValue();
free(errorMessagePointer);
throw Exception(message);
}

free(errorMessagePointer);
}

void closeCurrentWallet() => closeCurrentWalletNative();

String getSecretViewKey() =>
Expand Down
5 changes: 5 additions & 0 deletions cw_monero/lib/monero_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,11 @@ abstract class MoneroWalletBase extends WalletBase<MoneroBalance,
await monero_wallet.store();
}

@override
Future<void> changePassword(String password) async {
monero_wallet.setPasswordSync(password);
}

Future<int> getNodeHeight() async => monero_wallet.getNodeHeight();

Future<bool> isConnected() async => monero_wallet.isConnected();
Expand Down
10 changes: 2 additions & 8 deletions lib/core/generate_wallet_password.dart
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import 'package:uuid/uuid.dart';
import 'package:cw_core/key.dart';
import 'package:cw_core/wallet_type.dart';

String generateWalletPassword(WalletType type) {
switch (type) {
case WalletType.monero:
return Uuid().v4();
default:
return generateKey();
}
String generateWalletPassword() {
return generateKey();
}
42 changes: 36 additions & 6 deletions lib/core/wallet_creation_service.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:cake_wallet/di.dart';
import 'package:cw_core/wallet_info.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hive/hive.dart';
Expand Down Expand Up @@ -31,6 +32,8 @@ class WalletCreationService {
final Box<WalletInfo> walletInfoSource;
WalletService _service;

static const _isNewMoneroWalletPasswordUpdated = true;

void changeWalletType({@required WalletType type}) {
this.type = type;
_service = getIt.get<WalletService>(param1: type);
Expand All @@ -51,28 +54,55 @@ class WalletCreationService {

Future<WalletBase> create(WalletCredentials credentials) async {
checkIfExists(credentials.name);
final password = generateWalletPassword(type);
final password = generateWalletPassword();
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
return await _service.create(credentials);
final wallet = await _service.create(credentials);

if (wallet.type == WalletType.monero) {
await sharedPreferences
.setBool(
PreferencesKey.moneroWalletUpdateV1Key(wallet.name),
_isNewMoneroWalletPasswordUpdated);
}

return wallet;
}

Future<WalletBase> restoreFromKeys(WalletCredentials credentials) async {
checkIfExists(credentials.name);
final password = generateWalletPassword(type);
final password = generateWalletPassword();
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
return await _service.restoreFromKeys(credentials);
final wallet = await _service.restoreFromKeys(credentials);

if (wallet.type == WalletType.monero) {
await sharedPreferences
.setBool(
PreferencesKey.moneroWalletUpdateV1Key(wallet.name),
_isNewMoneroWalletPasswordUpdated);
}

return wallet;
}

Future<WalletBase> restoreFromSeed(WalletCredentials credentials) async {
checkIfExists(credentials.name);
final password = generateWalletPassword(type);
final password = generateWalletPassword();
credentials.password = password;
await keyService.saveWalletPassword(
password: password, walletName: credentials.name);
return await _service.restoreFromSeed(credentials);
final wallet = await _service.restoreFromSeed(credentials);

if (wallet.type == WalletType.monero) {
await sharedPreferences
.setBool(
PreferencesKey.moneroWalletUpdateV1Key(wallet.name),
_isNewMoneroWalletPasswordUpdated);
}

return wallet;
}
}
52 changes: 52 additions & 0 deletions lib/core/wallet_loading_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import 'package:cake_wallet/core/generate_wallet_password.dart';
import 'package:cake_wallet/core/key_service.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:shared_preferences/shared_preferences.dart';

class WalletLoadingService {
WalletLoadingService(
this.sharedPreferences,
this.keyService,
this.walletServiceFactory);

final SharedPreferences sharedPreferences;
final KeyService keyService;
final WalletService Function(WalletType type) walletServiceFactory;

Future<WalletBase> load(WalletType type, String name) async {
if (walletServiceFactory == null) {
throw Exception('WalletLoadingService.walletServiceFactory is not set');
}
final walletService = walletServiceFactory?.call(type);
final password = await keyService.getWalletPassword(walletName: name);
final wallet = await walletService.openWallet(name, password);

if (type == WalletType.monero) {
await upateMoneroWalletPassword(wallet);
}

return wallet;
}

Future<void> upateMoneroWalletPassword(WalletBase wallet) async {
final key = PreferencesKey.moneroWalletUpdateV1Key(wallet.name);
var isPasswordUpdated = sharedPreferences.getBool(key) ?? false;

if (isPasswordUpdated) {
return;
}

final password = generateWalletPassword();
// Save new generated password with backup key for case
// if wallet will change password, but it will faild to updated in secure storage
final bakWalletName = '#__${wallet.name}_bak__#';
await keyService.saveWalletPassword(walletName: bakWalletName, password: password);
await wallet.changePassword(password);
await keyService.saveWalletPassword(walletName: wallet.name, password: password);
isPasswordUpdated = true;
await sharedPreferences.setBool(key, isPasswordUpdated);
}
}
Loading

0 comments on commit b72443a

Please sign in to comment.