send all for private funds in firo, and bug fix for failing to load wallets

This commit is contained in:
Marco 2022-09-08 20:45:38 +08:00
parent 2b6aa83535
commit d672c2bd17
4 changed files with 132 additions and 63 deletions

View file

@ -10,6 +10,8 @@ import 'package:stackwallet/models/trade_wallet_lookup.dart';
import 'package:stackwallet/services/wallets_service.dart';
import 'package:stackwallet/utilities/enums/coin_enum.dart';
import 'package:stackwallet/utilities/logger.dart';
class DB {
static const String boxNameAddressBook = "addressBook";
static const String boxNameDebugInfo = "debugInfoBox";
@ -141,6 +143,18 @@ class DB {
Future<void> _loadWalletBoxes() async {
final names = _boxAllWalletsData.get("names") as Map? ?? {};
names.removeWhere((name, dyn) {
final jsonObject = Map<String, dynamic>.from(dyn as Map);
try {
Coin.values.byName(jsonObject["coin"] as String);
return false;
} catch (e, s) {
Logging.instance.log(
"Error, ${jsonObject["coin"]} does not exist, $name wallet cannot be loaded",
level: LogLevel.Error);
return true;
}
});
final mapped = Map<String, dynamic>.from(names).map((name, dyn) => MapEntry(
name, WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map))));

View file

@ -731,6 +731,38 @@ Future<void> _setTestnetWrapper(bool isTestnet) async {
// setTestnet(isTestnet);
}
Future<bool> getAnonymity(int groupID) async {
Logging.instance.log("getAnonymity", level: LogLevel.Info);
final Client client = Client();
try {
final uri = Uri.parse("$kStackCommunityNodesEndpoint/getAnonymity");
final anonSetResult = await client.post(
uri,
headers: {'Content-Type': 'application/json'},
body: jsonEncode({
"jsonrpc": "2.0",
"id": "0",
'index': groupID,
}),
);
// TODO: should the following be removed for security reasons in production?
Logging.instance
.log(anonSetResult.statusCode.toString(), level: LogLevel.Info);
Logging.instance.log(anonSetResult.body.toString(), level: LogLevel.Info);
final response = jsonDecode(anonSetResult.body.toString());
if (response['status'] == 'success') {
return true;
} else {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
/// Handles a single instance of a firo wallet
class FiroWallet extends CoinServiceAPI {
static const integrationTestFlag =
@ -1087,8 +1119,16 @@ class FiroWallet extends CoinServiceAPI {
Map<String, dynamic>? args,
}) async {
try {
// check for send all
bool isSendAll = false;
final balance =
Format.decimalAmountToSatoshis(await availablePrivateBalance());
if (satoshiAmount == balance) {
print("is send all");
isSendAll = true;
}
dynamic txHexOrError =
await _createJoinSplitTransaction(satoshiAmount, address, false);
await _createJoinSplitTransaction(satoshiAmount, address, isSendAll);
Logging.instance.log("txHexOrError $txHexOrError", level: LogLevel.Error);
if (txHexOrError is int) {
// Here, we assume that transaction crafting returned an error

View file

@ -103,75 +103,79 @@ class NotificationsService extends ChangeNotifier {
void _checkTransactions() async {
for (final notification in _watchedTransactionNotifications) {
final Coin coin = coinFromPrettyName(notification.coinName);
final txid = notification.txid!;
try {
final Coin coin = coinFromPrettyName(notification.coinName);
final txid = notification.txid!;
final node = nodeService.getPrimaryNodeFor(coin: coin);
if (node != null) {
if (coin.isElectrumXCoin) {
final eNode = ElectrumXNode(
address: node.host,
port: node.port,
name: node.name,
id: node.id,
useSSL: node.useSSL,
);
final failovers = nodeService
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
port: e.port,
name: e.name,
id: e.id,
useSSL: e.useSSL,
))
.toList();
final client = ElectrumX.from(
node: eNode,
failovers: failovers,
prefs: prefs,
);
final tx = await client.getTransaction(txHash: txid);
int confirmations = tx["confirmations"] as int? ?? 0;
bool shouldWatchForUpdates = true;
// check if the number of confirmations is greater than the number
// required by the wallet to count the tx as confirmed and update the
// flag on whether this notification should still be monitored
if (confirmations >= coin.requiredConfirmations) {
shouldWatchForUpdates = false;
confirmations = coin.requiredConfirmations;
}
// grab confirms string to compare
final String newConfirms =
"($confirmations/${coin.requiredConfirmations})";
final String oldConfirms =
notification.title.substring(notification.title.lastIndexOf("("));
// only update if they don't match
if (oldConfirms != newConfirms) {
final String newTitle =
notification.title.replaceFirst(oldConfirms, newConfirms);
final updatedNotification = notification.copyWith(
title: newTitle,
shouldWatchForUpdates: shouldWatchForUpdates,
final node = nodeService.getPrimaryNodeFor(coin: coin);
if (node != null) {
if (coin.isElectrumXCoin) {
final eNode = ElectrumXNode(
address: node.host,
port: node.port,
name: node.name,
id: node.id,
useSSL: node.useSSL,
);
final failovers = nodeService
.failoverNodesFor(coin: coin)
.map((e) => ElectrumXNode(
address: e.host,
port: e.port,
name: e.name,
id: e.id,
useSSL: e.useSSL,
))
.toList();
// remove from watch list if shouldWatchForUpdates was changed
if (!shouldWatchForUpdates) {
await _deleteWatchedTxNotification(notification);
final client = ElectrumX.from(
node: eNode,
failovers: failovers,
prefs: prefs,
);
final tx = await client.getTransaction(txHash: txid);
int confirmations = tx["confirmations"] as int? ?? 0;
bool shouldWatchForUpdates = true;
// check if the number of confirmations is greater than the number
// required by the wallet to count the tx as confirmed and update the
// flag on whether this notification should still be monitored
if (confirmations >= coin.requiredConfirmations) {
shouldWatchForUpdates = false;
confirmations = coin.requiredConfirmations;
}
// replaces the current notification with the updated one
add(updatedNotification, true);
// grab confirms string to compare
final String newConfirms =
"($confirmations/${coin.requiredConfirmations})";
final String oldConfirms = notification.title
.substring(notification.title.lastIndexOf("("));
// only update if they don't match
if (oldConfirms != newConfirms) {
final String newTitle =
notification.title.replaceFirst(oldConfirms, newConfirms);
final updatedNotification = notification.copyWith(
title: newTitle,
shouldWatchForUpdates: shouldWatchForUpdates,
);
// remove from watch list if shouldWatchForUpdates was changed
if (!shouldWatchForUpdates) {
await _deleteWatchedTxNotification(notification);
}
// replaces the current notification with the updated one
add(updatedNotification, true);
}
} else {
// TODO: check non electrumx coins
}
} else {
// TODO: check non electrumx coins
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
}
}
}

View file

@ -126,6 +126,17 @@ class WalletsService extends ChangeNotifier {
}
Logging.instance.log("Fetched wallet names: $names", level: LogLevel.Info);
final mapped = Map<String, dynamic>.from(names);
mapped.removeWhere((name, dyn) {
final jsonObject = Map<String, dynamic>.from(dyn as Map);
try {
Coin.values.byName(jsonObject["coin"] as String);
return false;
} catch (e, s) {
Logging.instance.log("Error, ${jsonObject["coin"]} does not exist",
level: LogLevel.Error);
return true;
}
});
return mapped.map((name, dyn) => MapEntry(
name, WalletInfo.fromJson(Map<String, dynamic>.from(dyn as Map))));