Skip to content

Commit

Permalink
Resolve wallet type from wallet file metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
KingGorrin committed Feb 9, 2024
1 parent a6258fa commit 4d4deb2
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 71 deletions.
4 changes: 2 additions & 2 deletions lib/blocs/decrypt_wallet_file_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import 'package:zenon_syrius_wallet_flutter/utils/wallet_file.dart';
import 'package:zenon_syrius_wallet_flutter/utils/wallet_utils.dart';

class DecryptWalletFileBloc extends BaseBloc<WalletFile?> {
Future<void> decryptWalletFile(String type, String path, String password) async {
Future<void> decryptWalletFile(String path, String password) async {
try {
addEvent(null);
final walletFile = await WalletUtils.decryptWalletFile(type, path, password);
final walletFile = await WalletUtils.decryptWalletFile(path, password);
addEvent(walletFile);
} catch (e, stackTrace) {
addError(e, stackTrace);
Expand Down
3 changes: 1 addition & 2 deletions lib/blocs/hide_widget_status_bloc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@ class HideWidgetStatusBloc extends BaseBloc<bool?> {
try {
addEvent(null);
if (!isHidden) {
await WalletUtils.decryptWalletFile(
kWalletType!, kWalletPath!, password);
await WalletUtils.decryptWalletFile(kWalletPath!, password);
}
await _markWidgetAsHidden(widgetTitle, isHidden);
addEvent(isHidden);
Expand Down
5 changes: 1 addition & 4 deletions lib/screens/change_wallet_password_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -221,10 +221,7 @@ class _ChangeWalletPasswordScreenState
? () {
_loadingButtonKey.currentState!.animateForward();
model.decryptWalletFile(
kWalletType!,
kWalletPath!,
_currentPasswordController.text,
);
kWalletPath!, _currentPasswordController.text);
}
: null,
text: 'Change password',
Expand Down
1 change: 0 additions & 1 deletion lib/screens/dump_mnemonic_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,6 @@ class _DumpMnemonicScreenState extends State<DumpMnemonicScreen> {
try {
_continueButtonKey.currentState!.animateForward();
var walletFile = await WalletUtils.decryptWalletFile(
kWalletType!,
kWalletPath!,
_passwordController.text,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ class _ImportWalletDecryptScreenState extends State<ImportWalletDecryptScreen> {
? () async {
_loadingButtonKey.currentState!.animateForward();
await model.decryptWalletFile(
kKeyStoreWalletType,
widget.path,
_passwordController.text,
);
Expand Down
1 change: 0 additions & 1 deletion lib/screens/splash_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ class _SplashScreenState extends State<SplashScreen>
Future<void> _deleteWalletFile() async {
await FileUtils.deleteFile(kWalletPath!);
kWalletPath = null;
kWalletType = null;
}

void _checkForDefaultNode() => sharedPrefsService!.get(
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/account_block_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class AccountBlockUtils {
transactionParams,
blockSigningKey: walletAccount,
);
bool needReview = kWalletType == kLedgerWalletType;
bool needReview = kWalletFile!.isHardwareWallet;

if (needPlasma) {
sl
Expand Down
4 changes: 0 additions & 4 deletions lib/utils/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ const List<String> kCacheBoxesToBeDeleted = [
// Wallet file name
const String kNameWalletFile = 'wallet';

// Wallet types
const String kLedgerWalletType = 'ledger';
const String kKeyStoreWalletType = 'keyStore';

// Github Syrius releases link
const String kGithubReleasesLink =
'https://github.com/zenon-network/syrius/releases/latest';
Expand Down
1 change: 0 additions & 1 deletion lib/utils/global.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ ValueNotifier<String?> kLastWalletConnectUriNotifier = ValueNotifier(null);
String? kCurrentNode;
String? kSelectedAddress;
String? kWalletPath;
String? kWalletType;
String? kLocalIpAddress;

int? kAutoLockWalletMinutes;
Expand Down
2 changes: 1 addition & 1 deletion lib/utils/init_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class InitUtils {
WidgetUtils.setTextScale(context);
_setAutoEraseWalletNumAttempts();
_setAutoLockWalletTimeInterval();
await WalletUtils.setWalletPathAndType();
await WalletUtils.setWalletPath();
await _setNumUnlockFailedAttempts();
await NodeUtils.setNode();
_setChainId();
Expand Down
76 changes: 58 additions & 18 deletions lib/utils/wallet_file.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,40 @@ import 'dart:io';

import 'package:hex/hex.dart';
import 'package:mutex/mutex.dart';
import 'package:zenon_syrius_wallet_flutter/utils/constants.dart';
import 'package:znn_ledger_dart/znn_ledger_dart.dart';
import 'package:znn_sdk_dart/znn_sdk_dart.dart';
import 'package:path/path.dart' as path;

abstract class WalletFile {
final String _path;

static Future<List<int>> read(String walletPath, String password) async {
static Future<WalletFile> decrypt(String walletPath, String password) async {
final encrypted = await WalletFile.read(walletPath);
final walletType =
encrypted.metadata != null ? encrypted.metadata![walletTypeKey] : null;
if (walletType == null || walletType == keyStoreWalletType) {
return await KeyStoreWalletFile.decrypt(walletPath, password);
} else if (walletType == ledgerWalletType) {
return await LedgerWalletFile.decrypt(walletPath, password);
} else {
throw WalletException(
'Wallet type (${encrypted.metadata![walletTypeKey]}) is not supported');
}
}

static Future<EncryptedFile> read(String walletPath) async {
final file = File(walletPath);
if (!file.existsSync()) {
throw InvalidWalletPath('Given wallet path does not exist ($walletPath)');
throw WalletException('Given wallet path does not exist ($walletPath)');
}
return EncryptedFile.fromJson(json.decode(file.readAsStringSync()))
.decrypt(password);
return EncryptedFile.fromJson(json.decode(file.readAsStringSync()));
}

static Future<void> write(
String walletPath, String password, List<int> data) async {
static Future<void> write(String walletPath, String password, List<int> data,
{Map<String, dynamic>? metadata}) async {
final file = File(walletPath);
final encrypted = await EncryptedFile.encrypt(data, password);
final encrypted =
await EncryptedFile.encrypt(data, password, metadata: metadata);
file.writeAsString(json.encode(encrypted), mode: FileMode.writeOnly);
}

Expand All @@ -35,6 +48,8 @@ abstract class WalletFile {

bool get isOpen;

bool get isHardwareWallet;

Future<Wallet> open();

void close();
Expand All @@ -50,8 +65,10 @@ abstract class WalletFile {

Future<void> changePassword(
String currentPassword, String newPassword) async {
var decrypted = await WalletFile.read(walletPath, currentPassword);
await WalletFile.write(walletPath, newPassword, decrypted);
final file = await WalletFile.read(walletPath);
final decrypted = await file.decrypt(currentPassword);
await WalletFile.write(walletPath, newPassword, decrypted,
metadata: file.metadata);
}
}

Expand All @@ -74,18 +91,28 @@ class KeyStoreWalletFile extends WalletFile {

static Future<KeyStoreWalletFile> decrypt(
String walletPath, String password) async {
List<int> decrypted = await WalletFile.read(walletPath, password);
final encrypted = await WalletFile.read(walletPath);
if (encrypted.metadata != null &&
encrypted.metadata![walletTypeKey] != null &&
encrypted.metadata![walletTypeKey] != keyStoreWalletType) {
throw WalletException(
'Wallet type (${encrypted.metadata![walletTypeKey]}) is not supported');
}
final decrypted = await encrypted.decrypt(password);
return KeyStoreWalletFile._internal(walletPath, HEX.encode(decrypted));
}

KeyStoreWalletFile._internal(super._path, this._walletSeed);

@override
String get walletType => kKeyStoreWalletType;
String get walletType => keyStoreWalletType;

@override
bool get isOpen => _lock.isLocked;

@override
bool get isHardwareWallet => false;

@override
Future<Wallet> open() async {
await _lock.acquire();
Expand Down Expand Up @@ -123,9 +150,14 @@ class LedgerWalletFile extends WalletFile {
{String? name}) async {
LedgerWallet wallet = await _connect(walletId);
try {
name ??= (await (await wallet.getAccount()).getAddress()).toString();
final baseAddress = (await (await wallet.getAccount()).getAddress());
name ??= baseAddress.toString();
final walletPath = path.join(znnDefaultWalletDirectory.path, name);
await WalletFile.write(walletPath, password, utf8.encode(walletId));
await WalletFile.write(walletPath, password, utf8.encode(walletId),
metadata: {
baseAddressKey: baseAddress.toString(),
walletTypeKey: ledgerWalletType
});
return LedgerWalletFile._internal(walletPath, walletId);
} finally {
await wallet.disconnect();
Expand All @@ -134,23 +166,31 @@ class LedgerWalletFile extends WalletFile {

static Future<LedgerWalletFile> decrypt(
String walletPath, String password) async {
List<int> decrypted = await WalletFile.read(walletPath, password);
final encrypted = await WalletFile.read(walletPath);
if (encrypted.metadata == null ||
encrypted.metadata![walletTypeKey] != ledgerWalletType) {
throw WalletException(
'Wallet type (${encrypted.metadata![walletTypeKey]}) is not supported');
}
final decrypted = await encrypted.decrypt(password);
return LedgerWalletFile._internal(walletPath, utf8.decode(decrypted));
}

LedgerWalletFile._internal(super._path, this._walletId);

@override
String get walletType => kLedgerWalletType;
String get walletType => ledgerWalletType;

@override
bool get isOpen => _lock.isLocked;

@override
bool get isHardwareWallet => true;

@override
Future<Wallet> open() async {
await _lock.acquire();
try
{
try {
_wallet = await _connect(_walletId);
return _wallet!;
} catch (_) {
Expand Down
33 changes: 3 additions & 30 deletions lib/utils/wallet_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,8 @@ class WalletUtils {
}

static Future<WalletFile> decryptWalletFile(
String walletType, String walletPath, String password) async {
if (walletType == kKeyStoreWalletType) {
return await KeyStoreWalletFile.decrypt(walletPath, password);
} else if (walletType == kLedgerWalletType) {
return await LedgerWalletFile.decrypt(walletPath, password);
} else {
throw UnsupportedError(
'The specified wallet type $walletType is not supported.');
}
String walletPath, String password) async {
return await WalletFile.decrypt(walletPath, password);
}

static Future<void> createLedgerWalletFile(
Expand All @@ -29,9 +22,7 @@ class WalletUtils {
}) async {
kWalletFile = await LedgerWalletFile.create(walletId, password, name: name);
kWalletPath = kWalletFile!.walletPath;
kWalletType = kWalletFile!.walletType;
await _storeWalletPath(kWalletFile!.walletPath);
await _storeWalletType(kWalletFile!.walletType);
}

static Future<void> createKeyStoreWalletFile(
Expand All @@ -42,22 +33,15 @@ class WalletUtils {
kWalletFile =
await KeyStoreWalletFile.create(mnemonic, password, name: name);
kWalletPath = kWalletFile!.walletPath;
kWalletType = kWalletFile!.walletType;
await _storeWalletPath(kWalletFile!.walletPath);
await _storeWalletType(kWalletFile!.walletType);
}

static Future<void> _storeWalletPath(String? walletPath) async {
Box keyStoreBox = await Hive.openBox(kKeyStoreBox);
await keyStoreBox.put(0, walletPath);
}

static Future<void> _storeWalletType(String? walletType) async {
Box keyStoreBox = await Hive.openBox(kKeyStoreBox);
await keyStoreBox.put(1, walletType);
}

static Future<void> setWalletPathAndType() async {
static Future<void> setWalletPath() async {
if (kWalletPath == null) {
Box keyStoreBox = await Hive.openBox(kKeyStoreBox);
if (keyStoreBox.isEmpty) {
Expand All @@ -74,16 +58,5 @@ class WalletUtils {
} else {
_storeWalletPath(kWalletPath);
}

if (kWalletType == null) {
Box keyStoreBox = await Hive.openBox(kKeyStoreBox);
if (keyStoreBox.values.length > 1) {
kWalletType = keyStoreBox.getAt(1);
} else {
kWalletType = null;
}
} else {
_storeWalletType(kWalletType);
}
}
}
2 changes: 1 addition & 1 deletion lib/widgets/modular_widgets/help_widgets/about_card.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class AboutCardState extends State<AboutCard> {
CustomExpandablePanel(
'Syrius wallet type',
_getGenericOpenButtonExpandedChild(
kWalletType!),
kWalletFile!.walletType),
),
CustomExpandablePanel(
'Client hostname',
Expand Down
5 changes: 2 additions & 3 deletions lib/widgets/modular_widgets/settings_widgets/backup.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:zenon_syrius_wallet_flutter/screens/screens.dart';
import 'package:zenon_syrius_wallet_flutter/utils/constants.dart';
import 'package:zenon_syrius_wallet_flutter/utils/global.dart';
import 'package:zenon_syrius_wallet_flutter/utils/navigation_utils.dart';
import 'package:zenon_syrius_wallet_flutter/widgets/widgets.dart';
Expand Down Expand Up @@ -38,7 +37,7 @@ class _BackupWidgetState extends State<BackupWidget> {
Widget _getBackupWalletButton() {
return Center(
child: SettingsButton(
onPressed: (kWalletFile!.walletType == kKeyStoreWalletType)
onPressed: (!kWalletFile!.isHardwareWallet)
? _onBackupWalletPressed
: null,
text: 'Backup wallet',
Expand All @@ -61,7 +60,7 @@ class _BackupWidgetState extends State<BackupWidget> {
Widget _getDumpMnemonicButton() {
return Center(
child: SettingsButton(
onPressed: (kWalletFile!.walletType == kKeyStoreWalletType)
onPressed: (!kWalletFile!.isHardwareWallet)
? _onDumpMnemonicPressed
: null,
text: 'Dump Mnemonic',
Expand Down
1 change: 0 additions & 1 deletion lib/widgets/tab_children_widgets/lock_tab_child.dart
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,6 @@ class _LockTabChildState extends State<LockTabChild> {
try {
_actionButtonKey.currentState!.animateForward();
kWalletFile = await WalletUtils.decryptWalletFile(
kWalletType!,
kWalletPath!,
_passwordController.text,
);
Expand Down

0 comments on commit 4d4deb2

Please sign in to comment.