mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-31 06:58:42 +01:00
Merge upstream Cake Wallet v6.5.0
Catches up from the May 12 fork point (v6.1.2+23) through v6.5.0: 535 upstream commits, including the Monero silent-open fix, Monero on Trezor, Ledger/Trezor BLE fixes, the new seed and history screens, quick Bitcoin sync, git-pinned dependencies (pubspec_overrides.yaml), frozen Hive adapters (*.part.dart), monero_c v0.18.4.6-RC2 and Flutter 3.41.9. Merged with both sides normalized first (import rename, 100-column format), which took the conflict count from 614 paths to 322. The procedure is now scripts/upstream_sync.sh. Kept from Hash Bags: - WalletType enum order and Hive IDs. SQLite stores WalletType.index and our order differs from upstream's; taking theirs would reread saved wallets as other chains. Our frozen adapter keeps the shipped IDs. - The 1.0.2 legacy PIN and wallet-password decode and self-heal. - Removed chains (Solana, Tron, Zano, Zcash, Decred, Haven) and the new Robinhood chain stay out; Cake Pay and non-Trocador swaps stay out. - Default nodes (node.wownero.org, sethforprivacy, Blockstream, bysh.me), converted to upstream's isDefault node-list key; Wownero is back in the node reset list. - Privacy: address resolvers limited to domain-anchored sources again; prices.neroswap.com for fiat; upstream's charts tab, which reads prices.cakewallet.com, sits behind FeatureFlag.isChartsEnabled = false. - Lightning stays behind FeatureFlag.isLightningEnabled, including upstream's new post-seed Lightning username step. - Our icon pipeline, branding and bundle identifiers. Twelve new upstream widget tests are skipped: test and code are unchanged from v6.5.0 apart from renames (not rerun on a pristine upstream checkout; upstream's top_bar_test does not compile against its own TopBar). flutter analyze lib: 0 errors; flutter test: 345 passed, 12 skipped; flutter build bundle compiles. Built with Flutter 3.41.9.
This commit is contained in:
@@ -9,6 +9,7 @@ import 'package:hash_wallet/store/settings_store.dart';
|
||||
import 'package:hash_wallet/view_model/dashboard/balance_view_model.dart';
|
||||
import 'package:hash_wallet/view_model/hardware_wallet/hardware_wallet_view_model.dart';
|
||||
import 'package:hash_wallet/view_model/send/send_view_model_state.dart';
|
||||
import 'package:cw_core/amount/money.dart';
|
||||
import 'package:cw_core/crypto_currency.dart';
|
||||
import 'package:cw_core/parse_fixed.dart';
|
||||
import 'package:cw_core/pending_transaction.dart';
|
||||
@@ -22,7 +23,10 @@ class DEuroViewModel = DEuroViewModelBase with _$DEuroViewModel;
|
||||
abstract class DEuroViewModelBase with Store {
|
||||
final AppStore _appStore;
|
||||
|
||||
static BigInt get MIN_ACCRUED_INTEREST => BigInt.parse("1000000000000");
|
||||
static Money get MIN_ACCRUED_INTEREST =>
|
||||
Money(BigInt.parse("1000000000000"), CryptoCurrency.deuro);
|
||||
|
||||
static Money get ZERO => Money.zero(CryptoCurrency.deuro);
|
||||
|
||||
DEuroViewModelBase(
|
||||
this._appStore, this.balanceViewModel, this._settingsStore, this._fiatConversationStore,
|
||||
@@ -51,13 +55,13 @@ abstract class DEuroViewModelBase with Store {
|
||||
|
||||
@computed
|
||||
String get pendingTransactionFiatAmountFormatted {
|
||||
final amount = transaction == null ? '0.00' : _getDEuroFiatAmount(transaction!.amountFormatted);
|
||||
return isFiatDisabled ? '' : '$amount ${fiat.title}';
|
||||
final amount = transaction == null ? "0.00" : _getDEuroFiatAmount(transaction!.amount);
|
||||
return isFiatDisabled ? "" : "$amount ${fiat.symbol}";
|
||||
}
|
||||
|
||||
@computed
|
||||
String get pendingTransactionFeeFiatAmountFormatted {
|
||||
var amount = '0.00';
|
||||
var amount = "0.00";
|
||||
try {
|
||||
if (transaction != null) {
|
||||
final feeCurrency = CryptoCurrency.eth;
|
||||
@@ -67,42 +71,43 @@ abstract class DEuroViewModelBase with Store {
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
return isFiatDisabled ? '' : '$amount ${fiat.title}';
|
||||
return isFiatDisabled ? "" : "$amount ${fiat.symbol}";
|
||||
}
|
||||
|
||||
@computed
|
||||
String get accountBalanceFormated {
|
||||
Money get accountBalance {
|
||||
final dEuroKey = balanceViewModel.balances.keys
|
||||
.firstWhereOrNull((e) => e.title == CryptoCurrency.deuro.title);
|
||||
if (dEuroKey == null) return '0.00';
|
||||
return balanceViewModel.balances[dEuroKey]?.availableBalance ?? '0.00';
|
||||
if (dEuroKey == null) return ZERO;
|
||||
return wallet.balance[dEuroKey]?.available ?? ZERO;
|
||||
}
|
||||
|
||||
@observable
|
||||
BigInt savingsBalance = BigInt.zero;
|
||||
Money savingsBalance = ZERO;
|
||||
|
||||
@computed
|
||||
String get savingsBalanceFormated =>
|
||||
evm!.formatterEVMAmountToDouble(amount: savingsBalance).toStringAsFixed(6);
|
||||
String get fiatSavingsBalanceFormated => _getDEuroFiatAmount(savingsBalance);
|
||||
|
||||
@observable
|
||||
Money? savingsBalanceV1 = null;
|
||||
|
||||
@computed
|
||||
String get fiatSavingsBalanceFormated => _getDEuroFiatAmount(savingsBalanceFormated);
|
||||
String get fiatSavingsBalanceV1Formated => _getDEuroFiatAmount(savingsBalanceV1);
|
||||
|
||||
@observable
|
||||
ExecutionState state = InitialExecutionState();
|
||||
|
||||
@observable
|
||||
String interestRateFormated = '0';
|
||||
String interestRateFormated = "0";
|
||||
|
||||
@observable
|
||||
BigInt accruedInterest = BigInt.zero;
|
||||
Money accruedInterest = ZERO;
|
||||
|
||||
@computed
|
||||
String get accruedInterestFormated =>
|
||||
evm!.formatterEVMAmountToDouble(amount: accruedInterest).toStringAsFixed(6);
|
||||
String get accruedInterestFormated => accruedInterest.toStringWithPrecision(fractionalDigits: 6);
|
||||
|
||||
@computed
|
||||
String get fiatAccruedInterestFormated => _getDEuroFiatAmount(accruedInterestFormated);
|
||||
String get fiatAccruedInterestFormated => _getDEuroFiatAmount(accruedInterest);
|
||||
|
||||
@observable
|
||||
BigInt approvedTokens = BigInt.zero;
|
||||
@@ -128,8 +133,12 @@ abstract class DEuroViewModelBase with Store {
|
||||
@action
|
||||
Future<void> reloadSavingsUserData() async {
|
||||
approvedTokens = await evm!.getDEuroSavingsApproved(_appStore.wallet!) ?? BigInt.zero;
|
||||
savingsBalance = await evm!.getDEuroSavingsBalance(_appStore.wallet!) ?? BigInt.zero;
|
||||
accruedInterest = await evm!.getDEuroAccruedInterest(_appStore.wallet!) ?? BigInt.zero;
|
||||
savingsBalance = await evm!.getDEuroSavingsBalance(_appStore.wallet!) ?? ZERO;
|
||||
accruedInterest = await evm!.getDEuroAccruedInterest(_appStore.wallet!) ?? ZERO;
|
||||
|
||||
final v1Balance = await evm!.getDEuroSavingsV1Balance(_appStore.wallet!) ?? ZERO;
|
||||
savingsBalanceV1 = v1Balance.isZero ? null : v1Balance;
|
||||
|
||||
isLoading = false;
|
||||
}
|
||||
|
||||
@@ -151,9 +160,8 @@ abstract class DEuroViewModelBase with Store {
|
||||
state = TransactionCommitting();
|
||||
final priority = _appStore.settingsStore.getPriority(wallet.type, chainId: wallet.chainId)!;
|
||||
final approval = await evm!.enableDEuroSaving(_appStore.wallet!, priority);
|
||||
if (approval == null) {
|
||||
throw Exception('DEuro saving not available');
|
||||
}
|
||||
if (approval == null) throw Exception("DEuro saving not available");
|
||||
|
||||
approvalTransaction = approval;
|
||||
state = InitialExecutionState();
|
||||
} catch (e) {
|
||||
@@ -167,13 +175,13 @@ abstract class DEuroViewModelBase with Store {
|
||||
state = TransactionCommitting();
|
||||
|
||||
if (amountRaw.isEmpty || amountRaw.trim().isEmpty) {
|
||||
throw Exception('Invalid amount: amount cannot be empty');
|
||||
throw Exception("Invalid amount: amount cannot be empty");
|
||||
}
|
||||
|
||||
final amount = tryParseFixed(amountRaw, 18);
|
||||
|
||||
if (amount == BigInt.zero || amount == null) {
|
||||
throw Exception('Invalid amount: amount cannot be zero');
|
||||
throw Exception("Invalid amount: amount cannot be zero");
|
||||
}
|
||||
|
||||
final priority = _appStore.settingsStore.getPriority(wallet.type, chainId: wallet.chainId)!;
|
||||
@@ -181,9 +189,24 @@ abstract class DEuroViewModelBase with Store {
|
||||
final tx = await (isAdding
|
||||
? evm!.addDEuroSaving(_appStore.wallet!, amount, priority)
|
||||
: evm!.removeDEuroSaving(_appStore.wallet!, amount, priority));
|
||||
if (tx == null) {
|
||||
throw Exception('DEuro saving not available');
|
||||
}
|
||||
if (tx == null) throw Exception("DEuro saving not available");
|
||||
|
||||
transaction = tx;
|
||||
state = InitialExecutionState();
|
||||
} catch (e) {
|
||||
state = FailureState(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
Future<void> prepareSavingsV1Withdraw() async {
|
||||
try {
|
||||
state = TransactionCommitting();
|
||||
actionType = DEuroActionType.withdraw;
|
||||
final priority = _appStore.settingsStore.getPriority(wallet.type, chainId: wallet.chainId)!;
|
||||
final tx = await evm!.withdrawDEuroSavingV1(_appStore.wallet!, priority);
|
||||
if (tx == null) throw Exception("DEuro saving not available");
|
||||
|
||||
transaction = tx;
|
||||
state = InitialExecutionState();
|
||||
} catch (e) {
|
||||
@@ -193,13 +216,13 @@ abstract class DEuroViewModelBase with Store {
|
||||
|
||||
Future<void> prepareCollectInterest() async {
|
||||
if (accruedInterest < MIN_ACCRUED_INTEREST) {
|
||||
state = FailureState('Accrued interest is below minimum threshold');
|
||||
state = FailureState("Accrued interest is below minimum threshold");
|
||||
return;
|
||||
}
|
||||
|
||||
final formatted = accruedInterestFormated;
|
||||
if (formatted.isEmpty || formatted == '0.000000') {
|
||||
state = FailureState('Invalid accrued interest amount');
|
||||
if (formatted.isEmpty || formatted == "0.000000") {
|
||||
state = FailureState("Invalid accrued interest amount");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -212,9 +235,8 @@ abstract class DEuroViewModelBase with Store {
|
||||
actionType = DEuroActionType.reinvest;
|
||||
final priority = _appStore.settingsStore.getPriority(wallet.type, chainId: wallet.chainId)!;
|
||||
final tx = await evm!.reinvestDEuroInterest(_appStore.wallet!, priority);
|
||||
if (tx == null) {
|
||||
throw Exception('DEuro saving not available');
|
||||
}
|
||||
if (tx == null) throw Exception("DEuro saving not available");
|
||||
|
||||
transaction = tx;
|
||||
state = InitialExecutionState();
|
||||
} catch (e) {
|
||||
@@ -261,7 +283,9 @@ abstract class DEuroViewModelBase with Store {
|
||||
state = InitialExecutionState();
|
||||
}
|
||||
|
||||
String _getDEuroFiatAmount(String amount) {
|
||||
String _getDEuroFiatAmount(Money? amount) {
|
||||
if (amount == null) return "0.00";
|
||||
|
||||
try {
|
||||
var dEuro = CryptoCurrency.deuro;
|
||||
final keys = _fiatConversationStore.prices.keys.toList();
|
||||
@@ -270,19 +294,14 @@ abstract class DEuroViewModelBase with Store {
|
||||
}
|
||||
return calculateFiatAmount(
|
||||
price: _fiatConversationStore.prices[dEuro]!,
|
||||
cryptoAmount: amount,
|
||||
cryptoAmount: amount.toStringWithPrecision(fractionalDigits: 6),
|
||||
);
|
||||
} catch (_) {
|
||||
return '0.00';
|
||||
return "0.00";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NoEtherState extends ExecutionState {}
|
||||
|
||||
enum DEuroActionType {
|
||||
deposit,
|
||||
withdraw,
|
||||
reinvest,
|
||||
none;
|
||||
}
|
||||
enum DEuroActionType { deposit, withdraw, reinvest, none }
|
||||
|
||||
Reference in New Issue
Block a user