Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
120 changes: 111 additions & 9 deletions lib/wallets/wallet/impl/xelis_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import '../../../services/event_bus/events/global/wallet_sync_status_changed_eve
import '../../../services/event_bus/global_event_bus.dart';
import '../../../utilities/amount/amount.dart';
import '../../../utilities/logger.dart';
import '../../../utilities/stack_file_system.dart';

import '../../crypto_currency/crypto_currency.dart';
import '../../models/tx_data.dart';
import '../intermediate/lib_xelis_wallet.dart';
Expand All @@ -31,29 +33,129 @@ class XelisWallet extends LibXelisWallet {
@override
int get isarTransactionVersion => 2;

Future<void> _restoreWallet() async {
final tablePath = await getPrecomputedTablesPath();
final tableState = await getTableState();
final xelisDir = await StackFileSystem.applicationXelisDirectory();
final String name = walletId;
final String directory = xelisDir.path;
final password = await secureStorageInterface.read(
key: Wallet.mnemonicPassphraseKey(walletId: info.walletId),
);

final mnemonic = await getMnemonic();
final seedLength = mnemonic.trim().split(" ").length;

invalidSeedLengthCheck(seedLength);

Logging.instance.i("Xelis: recovering wallet");
final wallet = await x_wallet.createXelisWallet(
name: name,
directory: directory,
password: password!,
seed: mnemonic.trim(),
network: cryptoCurrency.network.xelisNetwork,
precomputedTablesPath: tablePath,
l1Low: tableState.currentSize.isLow,
);

await secureStorageInterface.write(
key: Wallet.mnemonicKey(walletId: walletId),
value: mnemonic.trim(),
);

libXelisWallet = wallet;
}

Future<void> _createNewWallet() async {
final tablePath = await getPrecomputedTablesPath();
final tableState = await getTableState();
final xelisDir = await StackFileSystem.applicationXelisDirectory();
final String name = walletId;
final String directory = xelisDir.path;
final String password = generatePassword();

Logging.instance.d("Xelis: storing password");
await secureStorageInterface.write(
key: Wallet.mnemonicPassphraseKey(walletId: info.walletId),
value: password,
);

final wallet = await x_wallet.createXelisWallet(
name: name,
directory: directory,
password: password!,
network: cryptoCurrency.network.xelisNetwork,
precomputedTablesPath: tablePath,
l1Low: tableState.currentSize.isLow,
);

final mnemonic = await wallet.getSeed();
await secureStorageInterface.write(
key: Wallet.mnemonicKey(walletId: walletId),
value: mnemonic.trim(),
);

libXelisWallet = wallet;
}

@override
Future<void> init({bool? isRestore}) async {
Logging.instance.d("Xelis: init");

if (isRestore == true) {
await super.init();
return await open(openType: XelisWalletOpenType.restore);
}
if (libXelisWallet == null) {
if (isRestore == true) {
await _restoreWallet();
} else {
final bool walletExists = await LibXelisWallet.checkWalletExists(walletId);
if (!walletExists) {
await _createNewWallet();
} else {
Logging.instance.i("Xelis: opening existing wallet");
final tablePath = await getPrecomputedTablesPath();
final tableState = await getTableState();
final xelisDir = await StackFileSystem.applicationXelisDirectory();
final String name = walletId;
final String directory = xelisDir.path;
final password = await secureStorageInterface.read(
key: Wallet.mnemonicPassphraseKey(walletId: info.walletId),
);

final bool walletExists = await LibXelisWallet.checkWalletExists(walletId);
if (!walletExists) {
await _createNewWallet();
await open(openType: XelisWalletOpenType.create);
libXelisWallet = await x_wallet.openXelisWallet(
name: name,
directory: directory,
password: password!,
network: cryptoCurrency.network.xelisNetwork,
precomputedTablesPath: tablePath,
l1Low: tableState.currentSize.isLow,
);
}
}

if (await isTableUpgradeAvailable()) {
unawaited(updateTablesToDesiredSize());
}

final newReceivingAddress =
await getCurrentReceivingAddress() ??
Address(
walletId: walletId,
derivationIndex: 0,
derivationPath: null,
value: libXelisWallet!.getAddressStr(),
publicKey: [],
type: AddressType.xelis,
subType: AddressSubType.receiving,
);

await mainDB.updateOrPutAddresses([newReceivingAddress]);

if (info.cachedReceivingAddress != newReceivingAddress.value) {
await info.updateReceivingAddress(
newAddress: newReceivingAddress.value,
isar: mainDB.isar,
);
}
}

return await super.init();
Expand Down Expand Up @@ -97,7 +199,7 @@ class XelisWallet extends LibXelisWallet {
} catch (_) {
await handleOffline();
return false;
}
}
}

final _balanceUpdateMutex = Mutex();
Expand Down
124 changes: 9 additions & 115 deletions lib/wallets/wallet/intermediate/lib_xelis_wallet.dart
Original file line number Diff line number Diff line change
Expand Up @@ -331,119 +331,15 @@ abstract class LibXelisWallet<T extends ElectrumCurrency>

@override
Future<void> open({XelisWalletOpenType? openType}) async {
bool wasNull = false;

if (libXelisWallet == null) {
wasNull = true;
final tablePath = await getPrecomputedTablesPath();
final tableState = await getTableState();
final xelisDir = await StackFileSystem.applicationXelisDirectory();
final String name = walletId;
final String directory = xelisDir.path;
final password = await secureStorageInterface.read(
key: Wallet.mnemonicPassphraseKey(walletId: info.walletId),
);

await LibXelisWallet._initMutex.protect(() async {
try {
libXelisWallet = await syncMutex.protect(() async {
switch (openType) {
case XelisWalletOpenType.create:
Logging.instance.i("Xelis: creating new wallet");
final wallet = await x_wallet.createXelisWallet(
name: name,
directory: directory,
password: password!,
network: cryptoCurrency.network.xelisNetwork,
precomputedTablesPath: tablePath,
l1Low: tableState.currentSize.isLow,
);

final mnemonic = await wallet.getSeed();
await secureStorageInterface.write(
key: Wallet.mnemonicKey(walletId: walletId),
value: mnemonic.trim(),
);

return wallet;

case XelisWalletOpenType.restore:
final mnemonic = await getMnemonic();
final seedLength = mnemonic.trim().split(" ").length;

invalidSeedLengthCheck(seedLength);

Logging.instance.i("Xelis: recovering wallet");
final wallet = await x_wallet.createXelisWallet(
name: name,
directory: directory,
password: password!,
seed: mnemonic.trim(),
network: cryptoCurrency.network.xelisNetwork,
precomputedTablesPath: tablePath,
l1Low: tableState.currentSize.isLow,
);

await secureStorageInterface.write(
key: Wallet.mnemonicKey(walletId: walletId),
value: mnemonic.trim(),
);

return wallet;

case null:
Logging.instance.i("Xelis: opening existing wallet");
return await x_wallet.openXelisWallet(
name: name,
directory: directory,
password: password!,
network: cryptoCurrency.network.xelisNetwork,
precomputedTablesPath: tablePath,
l1Low: tableState.currentSize.isLow,
);
}
});
} catch (e, s) {
Logging.instance.e(
"Rethrowing failed $runtimeType open(openType: $openType)",
error: e,
stackTrace: s,
);
rethrow;
}
});

Logging.instance.i("Xelis: Checking for upgradability");
if (await isTableUpgradeAvailable()) {
Logging.instance.i("Xelis: Generating large tables in background");
unawaited(updateTablesToDesiredSize());
}
}

final newReceivingAddress =
await getCurrentReceivingAddress() ??
Address(
walletId: walletId,
derivationIndex: 0,
derivationPath: null,
value: libXelisWallet!.getAddressStr(),
publicKey: [],
type: AddressType.xelis,
subType: AddressSubType.receiving,
);
await mainDB.updateOrPutAddresses([newReceivingAddress]);

if (info.cachedReceivingAddress != newReceivingAddress.value) {
await info.updateReceivingAddress(
newAddress: newReceivingAddress.value,
isar: mainDB.isar,
);
}

if (wasNull) {
try {
await connect();
} catch (e) {
// Logging.instance.log(
// "Failed to start sync: $e",
// level: LogLevel.Error,
// );
rethrow;
}

unawaited(refresh());
}

Expand All @@ -457,10 +353,6 @@ abstract class LibXelisWallet<T extends ElectrumCurrency>
_eventSubscription = null;

await libXelisWallet?.offlineMode();
await libXelisWallet?.close();
libXelisWallet?.dispose();
libXelisWallet = null;

await super.exit();
});
}
Expand Down Expand Up @@ -511,6 +403,8 @@ extension XelisTableManagement on LibXelisWallet {
await setTableState(state.copyWith(isGenerating: true));

try {
Logging.instance.i("Xelis: Generating large tables in background");

final tablePath = await getPrecomputedTablesPath();
await x_wallet.updateTables(
precomputedTablesPath: tablePath,
Expand Down
Loading