Merge pull request from Tritonn204/xelis

Xelis init/open refactor
This commit is contained in:
julian-CStack 2025-03-20 14:35:58 -06:00 committed by GitHub
commit 22ff0b1709
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 120 additions and 124 deletions
lib/wallets/wallet

View file

@ -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';
@ -31,7 +33,46 @@ 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");
@ -39,21 +80,82 @@ class XelisWallet extends LibXelisWallet {
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();
@ -97,7 +199,7 @@ class XelisWallet extends LibXelisWallet {
} catch (_) {
await handleOffline();
return false;
}
}
}
final _balanceUpdateMutex = Mutex();

View file

@ -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());
}
@ -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();
});
}
@ -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,