CakeWallet/lib/reactions/on_current_wallet_change.dart
Konstantin Ullrich 4b137bc968
CW-1091-payjoin-error-handeling (#2317)
* feat: stop polling payjoin on switch wallet

* refactor: improve Payjoin session handling and cleanup unused methods

- Replaced `initReceiver` with `getUnusedReceiver` to reuse existing Payjoin sessions.
- Streamlined session initialization by removing `spawnNewReceiver`.
- Adjusted wallet sync reactions to resume Payjoin sessions when necessary.

* fix: Receiver.fromJson correctly handle parameter format in Payjoin manager

* fix: try reloading unspents if unspents are empty; No Unpsents available are now recoverable errors

* fix: ensure transaction details display only if transactionInfo is available and adjust payjoin success status handling

* fix: adjust payjoin success status handling for pending transactions

* fix: add error handling for Payjoin initialization and receiver creation [skip-ci]

* fix: add unrecoverable error handling for Payjoin sender sessions
2025-06-19 19:55:41 +03:00

159 lines
6 KiB
Dart

import 'package:cake_wallet/bitcoin/bitcoin.dart';
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/entities/auto_generate_subaddress_status.dart';
import 'package:cake_wallet/entities/fiat_api_mode.dart';
import 'package:cake_wallet/entities/wallet_manager.dart';
import 'package:cake_wallet/ethereum/ethereum.dart';
import 'package:cake_wallet/polygon/polygon.dart';
import 'package:cake_wallet/solana/solana.dart';
import 'package:cake_wallet/tron/tron.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/transaction_history.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:mobx/mobx.dart';
import 'package:cake_wallet/reactions/check_connection.dart';
import 'package:cake_wallet/reactions/on_wallet_sync_status_change.dart';
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
import 'package:cake_wallet/store/app_store.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/core/fiat_conversion_service.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_type.dart';
ReactionDisposer? _onCurrentWalletChangeReaction;
ReactionDisposer? _onCurrentWalletChangeFiatRateUpdateReaction;
//ReactionDisposer _onCurrentWalletAddressChangeReaction;
void startCurrentWalletChangeReaction(
AppStore appStore, SettingsStore settingsStore, FiatConversionStore fiatConversionStore) {
_onCurrentWalletChangeReaction?.reaction.dispose();
_onCurrentWalletChangeFiatRateUpdateReaction?.reaction.dispose();
//_onCurrentWalletAddressChangeReaction?.reaction?dispose();
//_onCurrentWalletAddressChangeReaction = reaction((_) => appStore.wallet.walletAddresses.address,
//(String address) async {
//if (address == appStore.wallet.walletInfo.yatLastUsedAddress) {
// return;
//}
//try {
// final yatStore = getIt.get<YatStore>();
// await updateEmojiIdAddress(
// appStore.wallet.walletInfo.yatEmojiId,
// appStore.wallet.walletAddresses.address,
// yatStore.apiKey,
// appStore.wallet.type
// );
// appStore.wallet.walletInfo.yatLastUsedAddress = address;
// await appStore.wallet.walletInfo.save();
//} catch (e) {
// printV(e.toString());
//}
//});
_onCurrentWalletChangeReaction = reaction((_) => appStore.wallet,
(WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
wallet) async {
try {
if (wallet == null) {
return;
}
await getIt.get<WalletManager>().ensureGroupHasHashedIdentifier(wallet);
final node = settingsStore.getCurrentNode(wallet.type);
startWalletSyncStatusChangeReaction(wallet, settingsStore);
startCheckConnectionReaction(wallet, settingsStore);
await Future.delayed(Duration.zero);
if (wallet.type == WalletType.monero ||
wallet.type == WalletType.wownero ||
wallet.type == WalletType.bitcoin ||
wallet.type == WalletType.litecoin ||
wallet.type == WalletType.bitcoinCash ||
wallet.type == WalletType.decred) {
_setAutoGenerateSubaddressStatus(wallet, settingsStore);
}
if (wallet.type == WalletType.bitcoin) {
bitcoin!.updatePayjoinState(wallet, settingsStore.usePayjoin);
}
await wallet.connectToNode(node: node);
if (wallet.type == WalletType.nano || wallet.type == WalletType.banano) {
final powNode = settingsStore.getCurrentPowNode(wallet.type);
await wallet.connectToPowNode(node: powNode);
}
if (wallet.walletInfo.address.isEmpty) {
wallet.walletInfo.address = wallet.walletAddresses.address;
if (wallet.walletInfo.isInBox) {
await wallet.walletInfo.save();
}
}
} catch (e) {
printV(e.toString());
}
});
_onCurrentWalletChangeFiatRateUpdateReaction = reaction((_) => appStore.wallet,
(WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo>?
wallet) async {
try {
if (wallet == null || settingsStore.fiatApiMode == FiatApiMode.disabled) {
return;
}
fiatConversionStore.prices[wallet.currency] = 0;
fiatConversionStore.prices[wallet.currency] = await FiatConversionService.fetchPrice(
crypto: wallet.currency,
fiat: settingsStore.fiatCurrency,
torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
Iterable<CryptoCurrency>? currencies;
if (wallet.type == WalletType.ethereum) {
currencies =
ethereum!.getERC20Currencies(appStore.wallet!).where((element) => element.enabled);
}
if (wallet.type == WalletType.polygon) {
currencies =
polygon!.getERC20Currencies(appStore.wallet!).where((element) => element.enabled);
}
if (wallet.type == WalletType.solana) {
currencies =
solana!.getSPLTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (wallet.type == WalletType.tron) {
currencies =
tron!.getTronTokenCurrencies(appStore.wallet!).where((element) => element.enabled);
}
if (currencies != null) {
for (final currency in currencies) {
() async {
fiatConversionStore.prices[currency] = await FiatConversionService.fetchPrice(
crypto: currency,
fiat: settingsStore.fiatCurrency,
torOnly: settingsStore.fiatApiMode == FiatApiMode.torOnly);
}.call();
}
}
} catch (e) {
printV(e.toString());
}
});
}
void _setAutoGenerateSubaddressStatus(
WalletBase<Balance, TransactionHistoryBase<TransactionInfo>, TransactionInfo> wallet,
SettingsStore settingsStore,
) async {
wallet.isEnabledAutoGenerateSubaddress =
settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.enabled ||
settingsStore.autoGenerateSubaddressStatus == AutoGenerateSubaddressStatus.initialized;
}