Files
peyawallet/lib/data/wallet_repository.dart
Codex Bot 6480e4a555
build / Build Linux wallet (push) Successful in 2m19s
build / Build Windows wallet (push) Successful in 20m35s
Improve wallet password handling and seed backup flow
2026-04-17 18:41:18 +02:00

211 lines
5.3 KiB
Dart

import '../domain/models.dart';
import '../domain/send.dart';
import '../domain/staking.dart';
import '../domain/transactions.dart';
import '../native/wallet_backend.dart';
class WalletSnapshot {
const WalletSnapshot({
required this.address,
required this.balanceAtomic,
required this.unlockedAtomic,
required this.nodeHeight,
required this.walletHeight,
required this.synced,
required this.progress,
required this.subaddresses,
});
final String address;
final int balanceAtomic;
final int unlockedAtomic;
final int nodeHeight;
final int walletHeight;
final bool synced;
final double progress;
final List<SubaddressInfo> subaddresses;
}
class WalletRepository {
WalletRepository(this._backend);
final WalletBackend _backend;
Future<void> _operationQueue = Future.value();
int get maxDestinations => _backend.maxDestinations;
Future<T> _runLocked<T>(Future<T> Function() action) {
final next = _operationQueue.then((_) => action());
_operationQueue = next.then((_) => null, onError: (_) => null);
return next;
}
Future<void> createWallet({
required String name,
required String path,
required String password,
}) {
return _runLocked(() {
return _backend.createWallet(name: name, path: path, password: password);
});
}
Future<void> restoreWalletFromSeed({
required String name,
required String seed,
required String path,
required String password,
}) {
return _runLocked(() {
return _backend.restoreWalletFromSeed(
name: name,
seed: seed,
path: path,
password: password,
);
});
}
Future<void> openWallet({
required String path,
required String password,
}) {
return _runLocked(() {
return _backend.openWallet(path: path, password: password);
});
}
Future<bool> verifyWalletPassword({
required String path,
required String password,
}) {
return _runLocked(() {
return _backend.verifyWalletPassword(path: path, password: password);
});
}
Future<void> closeWallet() {
return _runLocked(() => _backend.closeWallet());
}
Future<String> getAddress() {
return _runLocked(() => _backend.getAddress());
}
Future<String> getSeed() {
return _runLocked(() => _backend.getSeed());
}
Future<List<WalletTransaction>> getTransactions() {
return _runLocked(() => _backend.getTransactions());
}
Future<bool> isConnected() {
return _runLocked(() => _backend.isConnected());
}
Future<String> createSubaddress({String? label}) {
return _runLocked(() => _backend.createSubaddress(label: label));
}
Future<List<SubaddressInfo>> getSubaddresses() {
return _runLocked(() => _backend.getSubaddresses());
}
Future<void> setSubaddressLabel({
required int accountIndex,
required int addressIndex,
required String label,
}) {
return _runLocked(() {
return _backend.setSubaddressLabel(
accountIndex: accountIndex,
addressIndex: addressIndex,
label: label,
);
});
}
Future<SendPreview> prepareSend(SendRequest request) {
return _runLocked(() => _backend.prepareSend(request));
}
Future<SendResult> commitPreparedSend() {
return _runLocked(() => _backend.commitPreparedSend());
}
Future<void> discardPreparedSend() {
return _runLocked(() => _backend.discardPreparedSend());
}
Future<StakePreview> prepareStake({
required int amountAtomic,
int accountIndex = 0,
}) {
return _runLocked(() {
return _backend.prepareStake(
amountAtomic: amountAtomic,
accountIndex: accountIndex,
);
});
}
Future<Map<String, StakeYieldInfo>> getActiveStakeYields({
required List<WalletTransaction> activeStakes,
required int currentHeight,
}) {
return _runLocked(() {
return _backend.getActiveStakeYields(
activeStakes: activeStakes,
currentHeight: currentHeight,
);
});
}
Future<StakeResult> commitPreparedStake() {
return _runLocked(() => _backend.commitPreparedStake());
}
Future<void> discardPreparedStake() {
return _runLocked(() => _backend.discardPreparedStake());
}
Future<void> connectNode(NodeConfig nodeConfig) {
return _runLocked(() => _backend.connectToNode(nodeConfig));
}
Future<WalletSnapshot> refresh() async {
return _runLocked(() async {
await _backend.refresh();
final address = await _backend.getAddress();
final balance = await _backend.getBalance();
final unlockedBalance = await _backend.getUnlockedBalance();
final nodeHeight = await _backend.getNodeHeight();
final walletHeight = await _backend.getWalletHeight();
final synced = await _backend.isSynced();
final progress = await _backend.getSyncProgress();
List<SubaddressInfo> subaddresses;
try {
subaddresses = await _backend.getSubaddresses();
} catch (_) {
subaddresses = const [];
}
return WalletSnapshot(
address: address,
balanceAtomic: balance,
unlockedAtomic: unlockedBalance,
nodeHeight: nodeHeight,
walletHeight: walletHeight,
synced: synced,
progress: progress,
subaddresses: subaddresses,
);
});
}
Future<void> rescanBlockchain({int? fromHeight}) {
return _runLocked(() => _backend.rescanBlockchain(fromHeight: fromHeight));
}
}