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:
jwinterm
2026-10-24 23:49:29 -04:00
1406 changed files with 81062 additions and 48972 deletions
+91 -75
View File
@@ -78,6 +78,8 @@ import 'dart:typed_data';
import 'package:bitcoin_base/bitcoin_base.dart';
import 'package:hash_wallet/view_model/hardware_wallet/ledger_view_model.dart';
import 'package:hash_wallet/view_model/send/output.dart';
import "package:cw_core/account.dart";
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/hardware/hardware_account_data.dart';
import 'package:cw_core/hardware/hardware_wallet_service.dart';
import 'package:cw_core/node.dart';
@@ -93,6 +95,7 @@ import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/wallet_base.dart';
import 'package:cw_core/wallet_credentials.dart';
import 'package:cw_core/wallet_info.dart';
import "package:cw_core/balance.dart";
import 'package:cw_core/wallet_service.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:cw_core/utils/print_verbose.dart';
@@ -101,6 +104,7 @@ import 'package:hive/hive.dart';
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
import 'package:bitbox_flutter/bitbox_flutter.dart' as bitbox;
import 'package:trezor_connect/trezor_connect.dart' as trezor;
import 'package:trezor_flutter/trezor_flutter.dart' as trezor;
import 'package:blockchain_utils/blockchain_utils.dart';
import 'package:bip39/bip39.dart' as bip39;
import 'package:collection/collection.dart';
@@ -123,13 +127,16 @@ import 'package:cw_bitcoin/bitcoin_amount_format.dart';
import 'package:cw_bitcoin/bitcoin_address_record.dart';
import 'package:cw_bitcoin/bitcoin_wallet_addresses.dart';
import 'package:cw_bitcoin/bitcoin_transaction_credentials.dart';
import 'package:cw_bitcoin/lightning/lightning_addres_type.dart';
import 'package:cw_bitcoin/lightning/pending_lightning_transaction.dart';
import 'package:cw_bitcoin/litecoin_wallet_service.dart';
import 'package:cw_bitcoin/litecoin_wallet.dart';
import 'package:cw_bitcoin/hardware/bitcoin_ledger_service.dart';
import 'package:cw_bitcoin/hardware/litecoin_ledger_service.dart';
import 'package:cw_bitcoin/hardware/bitbox_service.dart';
import 'package:cw_bitcoin/hardware/litecoin_trezor_service.dart';
import 'package:cw_bitcoin/hardware/trezor_service.dart';
import 'package:cw_bitcoin/electrum_balance.dart';
import 'package:mobx/mobx.dart';
import "package:breez_sdk_spark_flutter/src/rust/errors.dart";
""";
@@ -188,12 +195,11 @@ abstract class Bitcoin {
List<ElectrumSubAddress> getSilentPaymentAddresses(Object wallet);
List<ElectrumSubAddress> getSilentPaymentReceivedAddresses(Object wallet);
Future<int> estimateFakeSendAllTxAmount(Object wallet, TransactionPriority priority,
Future<Money> estimateFakeSendAllTxAmount(WalletBase wallet, TransactionPriority priority,
{UnspentCoinType coinTypeToSpendFrom = UnspentCoinType.any});
List<ElectrumSubAddress> getSubAddresses(Object wallet);
String formatterBitcoinAmountToString({required int amount});
double formatterBitcoinAmountToDouble({required int amount});
int formatterStringDoubleToBitcoinAmount(String amount);
String bitcoinTransactionPriorityWithLabel(TransactionPriority priority, int rate, {int? customRate});
@@ -220,6 +226,7 @@ abstract class Bitcoin {
ReceivePageOption getLitecoinMwebReceivePageOption();
bool isPayjoinAvailable(Object wallet);
bool hasSelectedSilentPayments(Object wallet);
bool hasSelectedLightning(Object wallet);
bool isBitcoinReceivePageOption(ReceivePageOption option);
BitcoinAddressType getOptionToType(ReceivePageOption option);
bool hasTaprootInput(PendingTransaction pendingTransaction);
@@ -248,7 +255,7 @@ abstract class Bitcoin {
Future<void> setHardwareWalletService(WalletBase wallet, HardwareWalletService service);
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection, bool isBitcoin);
HardwareWalletService getBitboxHardwareWalletService(bitbox.BitboxManager manager, bool isBitcoin);
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect connect, bool isBitcoin);
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorConnect? connect, trezor.TrezorClient? client, bool isBitcoin);
List<Output> updateOutputs(PendingTransaction pendingTransaction, List<Output> outputs);
bool txIsReceivedSilentPayment(TransactionInfo txInfo);
bool txIsMweb(TransactionInfo txInfo);
@@ -272,6 +279,11 @@ abstract class Bitcoin {
Future<String?> getLightningUsername(Object wallet);
Future<String?> getLightningInvoice(Object wallet, BigInt amount);
String? getBreezSdkError(Object exception);
Future<Account> getCurrentAccount(Object wallet);
Money balanceForAccount(Object wallet, int accountIndex);
Map<int, Object> accountBalancesSnapshot(Object wallet);
Future<void> setCurrentAccount(Object wallet, int accountIndex);
List<TransactionInfo> getCurrentAccountBitcoinTransactions(Object wallet);
}
""";
@@ -295,6 +307,9 @@ abstract class Bitcoin {
Future<void> generateMonero(bool hasImplementation) async {
final outputFile = File(moneroOutputPath);
const moneroCommonHeaders = """
import 'package:cw_core/account.dart';
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:mobx/mobx.dart';
@@ -309,6 +324,8 @@ import 'package:hash_wallet/view_model/send/output.dart';
import 'package:cw_core/wallet_service.dart';
import 'package:hive/hive.dart';
import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
import 'package:trezor_flutter/trezor_flutter.dart' as trezor;
import "package:cw_core/hardware/hardware_wallet_service.dart";
import 'package:polyseed/polyseed.dart';""";
const moneroCWHeaders = """
import 'package:cw_core/account.dart' as monero_account;
@@ -320,6 +337,7 @@ import 'package:cw_monero/api/wallet.dart' as monero_wallet_api;
import 'package:cw_monero/ledger.dart';
import 'package:cw_monero/monero_unspent.dart';
import 'package:cw_monero/api/account_list.dart';
import 'package:cw_monero/trezor.dart';
import 'package:cw_monero/monero_wallet_service.dart';
import 'package:cw_monero/monero_wallet.dart';
import 'package:cw_monero/monero_transaction_info.dart';
@@ -338,12 +356,6 @@ import 'package:cw_monero/pending_monero_transaction.dart';
""";
const moneroCwPart = "part 'cw_monero.dart';";
const moneroContent = """
class Account {
Account({required this.id, required this.label, this.balance});
final int id;
final String label;
final String? balance;
}
class Subaddress {
Subaddress({
@@ -360,30 +372,17 @@ class Subaddress {
}
class MoneroBalance extends Balance {
MoneroBalance({required this.fullBalance, required this.unlockedBalance})
: formattedFullBalance = monero!.formatterMoneroAmountToString(amount: fullBalance),
formattedUnlockedBalance =
monero!.formatterMoneroAmountToString(amount: unlockedBalance),
super.fromInt(unlockedBalance, fullBalance);
MoneroBalance({
required this.fullBalance,
required Money unlockedBalance,
Money? frozen,
}) : super(
unlockedBalance,
fullBalance - unlockedBalance,
frozen: frozen ?? Money.zero(CryptoCurrency.xmr),
);
MoneroBalance.fromString(
{required this.formattedFullBalance,
required this.formattedUnlockedBalance})
: fullBalance = monero!.formatterMoneroParseAmount(amount: formattedFullBalance),
unlockedBalance = monero!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
super.fromInt(monero!.formatterMoneroParseAmount(amount: formattedUnlockedBalance),
monero!.formatterMoneroParseAmount(amount: formattedFullBalance));
final int fullBalance;
final int unlockedBalance;
final String formattedFullBalance;
final String formattedUnlockedBalance;
@override
String get formattedAvailableBalance => formattedUnlockedBalance;
@override
String get formattedAdditionalBalance => formattedFullBalance;
final Money fullBalance;
}
abstract class MoneroWalletDetails {
@@ -397,6 +396,8 @@ abstract class MoneroWalletDetails {
abstract class Monero {
MoneroAccountList getAccountList(Object wallet);
Money getAccountFullBalance(int accountIndex);
MoneroSubaddressList getSubaddressList(Object wallet);
TransactionHistoryBase getTransactionHistory(Object wallet);
@@ -424,7 +425,9 @@ abstract class Monero {
Map<String, String> exportOutputsUR(Object wallet);
bool needExportOutputs(Object wallet, int amount);
bool needExportOutputs(Object wallet, Money amount);
bool hasUnknownKeyImages(Object wallet);
bool importKeyImagesUR(Object wallet, String ur);
@@ -438,7 +441,7 @@ abstract class Monero {
HardwareWalletType? hardwareWalletType,
required int height});
WalletCredentials createMoneroRestoreWalletFromSeedCredentials({required String name, required String password, required String passphrase, required int height, required String mnemonic});
WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required ledger.LedgerConnection ledgerConnection});
WalletCredentials createMoneroRestoreWalletFromHardwareCredentials({required String name, required String password, required int height, required HardwareWalletService hardwareWalletService, required String? passphrase});
WalletCredentials createMoneroNewWalletCredentials({required String name, required String language, required int seedType, required String? passphrase, String? password, String? mnemonic});
Map<String, String> getKeys(Object wallet);
int? getRestoreHeight(Object wallet);
@@ -458,9 +461,19 @@ WalletCredentials createMoneroNewWalletCredentials({required String name, requir
Future<void> setLedgerConnection(Object wallet, ledger.LedgerConnection connection);
void resetLedgerConnection();
void setGlobalLedgerConnection(ledger.LedgerConnection connection);
bool hasGlobalLedgerConnection();
String? getLastLedgerCommand();
void setHardwareWalletService(Object wallet, HardwareWalletService service);
HardwareWalletService getLedgerHardwareWalletService(ledger.LedgerConnection connection);
HardwareWalletService getTrezorHardwareWalletService(trezor.TrezorClient client);
Future<void> syncTrezor(Object wallet);
Map<String, List<int>> debugCallLength();
Map<String, dynamic> getWalletCacheDebug();
Future<int> getNodeHeight(Object wallet);
String getLegacySeed(Object wallet, String langName);
bool isBackgroundSyncRunning(Object wallet);
Future<void> startBackgroundSync(Object wallet);
Future<void> stopBackgroundSync(Object wallet, String password);
}
abstract class MoneroSubaddressList {
@@ -503,6 +516,9 @@ abstract class MoneroAccountList {
Future<void> generateWownero(bool hasImplementation) async {
final outputFile = File(wowneroOutputPath);
const wowneroCommonHeaders = """
import 'package:cw_core/account.dart';
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/unspent_transaction_output.dart';
import 'package:cw_core/unspent_coins_info.dart';
import 'package:mobx/mobx.dart';
@@ -549,12 +565,6 @@ import 'package:cw_wownero/pending_wownero_transaction.dart';
""";
const wowneroCwPart = "part 'cw_wownero.dart';";
const wowneroContent = """
class Account {
Account({required this.id, required this.label, this.balance});
final int id;
final String label;
final String? balance;
}
class Subaddress {
Subaddress({
@@ -567,30 +577,17 @@ class Subaddress {
}
class WowneroBalance extends Balance {
WowneroBalance({required this.fullBalance, required this.unlockedBalance})
: formattedFullBalance = wownero!.formatterWowneroAmountToString(amount: fullBalance),
formattedUnlockedBalance =
wownero!.formatterWowneroAmountToString(amount: unlockedBalance),
super.fromInt(unlockedBalance, fullBalance);
WowneroBalance({
required this.fullBalance,
required Money unlockedBalance,
Money? frozen,
}) : super(
unlockedBalance,
fullBalance - unlockedBalance,
frozen: frozen ?? Money.zero(CryptoCurrency.wow),
);
WowneroBalance.fromString(
{required this.formattedFullBalance,
required this.formattedUnlockedBalance})
: fullBalance = wownero!.formatterWowneroParseAmount(amount: formattedFullBalance),
unlockedBalance = wownero!.formatterWowneroParseAmount(amount: formattedUnlockedBalance),
super.fromInt(wownero!.formatterWowneroParseAmount(amount: formattedUnlockedBalance),
wownero!.formatterWowneroParseAmount(amount: formattedFullBalance));
final int fullBalance;
final int unlockedBalance;
final String formattedFullBalance;
final String formattedUnlockedBalance;
@override
String get formattedAvailableBalance => formattedUnlockedBalance;
@override
String get formattedAdditionalBalance => formattedFullBalance;
final Money fullBalance;
}
abstract class WowneroWalletDetails {
@@ -604,6 +601,8 @@ abstract class WowneroWalletDetails {
abstract class Wownero {
WowneroAccountList getAccountList(Object wallet);
Money getAccountFullBalance(int accountIndex);
WowneroSubaddressList getSubaddressList(Object wallet);
TransactionHistoryBase getTransactionHistory(Object wallet);
@@ -826,7 +825,6 @@ abstract class Nano {
Object createNanoTransactionCredentials(List<Output> outputs);
Future<void> changeRep(Object wallet, String address);
Future<bool> updateTransactions(Object wallet);
BigInt getTransactionAmountRaw(TransactionInfo transactionInfo);
String getRepresentative(Object wallet);
Future<List<N2Node>> getN2Reps(Object wallet);
bool isRepOk(Object wallet);
@@ -948,6 +946,8 @@ Future<void> generateEVM(bool hasImplementation) async {
import 'dart:math' as math;
import 'package:hash_wallet/core/utilities.dart';
import 'package:hash_wallet/view_model/send/output.dart';
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/erc20_token.dart';
import 'package:cw_core/hardware/hardware_account_data.dart';
@@ -966,6 +966,7 @@ import 'package:ledger_flutter_plus/ledger_flutter_plus.dart' as ledger;
import 'package:bitbox_flutter/bitbox_flutter.dart' as bitbox;
import 'package:trezor_connect/trezor_connect.dart' as trezor;
import 'package:web3dart/web3dart.dart';
import 'package:cw_core/transaction_direction.dart';
""";
const evmCWHeaders = """
@@ -976,6 +977,7 @@ import 'package:hash_wallet/entities/fiat_currency.dart';
import 'package:hash_wallet/store/settings_store.dart';
import 'package:cw_evm/utils/evm_chain_formatter.dart';
import 'package:cw_evm/evm_chain_mnemonics.dart';
import 'package:cw_evm/pending_evm_chain_transaction.dart';
import 'package:cw_evm/evm_chain_registry.dart';
import 'package:cw_evm/evm_erc20_balance.dart';
import 'package:cw_evm/evm_chain_transaction_credentials.dart';
@@ -1069,11 +1071,6 @@ abstract class EVM {
});
int formatterEVMParseAmount(String amount);
double formatterEVMAmountToDouble({
TransactionInfo? transaction,
BigInt? amount,
int exponent = 18,
});
List<Erc20Token> getERC20Currencies(WalletBase wallet);
Future<void> addErc20Token(WalletBase wallet, CryptoCurrency token);
@@ -1085,7 +1082,6 @@ abstract class EVM {
void updateScanProviderUsageState(WalletBase wallet, bool isEnabled);
Web3Client? getWeb3Client(WalletBase wallet);
String getTokenAddress(CryptoCurrency asset);
BigInt? getERC20AvailableBalance(Object balance);
Future<bool> isApprovalRequired(
WalletBase wallet,
@@ -1101,9 +1097,8 @@ abstract class EVM {
Future<PendingTransaction> createTokenApproval(
WalletBase wallet,
BigInt amount,
Money amount,
String spender,
CryptoCurrency token,
TransactionPriority? priority,
{bool useBlinkProtection = true}
);
@@ -1112,7 +1107,7 @@ abstract class EVM {
WalletBase wallet,
String to,
String dataHex,
BigInt valueWei,
Money valueWei,
TransactionPriority? priority,
{bool useBlinkProtection = true,
String? sourceTokenAddress,
@@ -1134,10 +1129,12 @@ abstract class EVM {
String? getEVMERC20EstimatedFee(WalletBase wallet);
// Chain-specific integrations (optional, can be null for non-Ethereum chains)
Future<BigInt>? getDEuroSavingsBalance(WalletBase wallet) => null;
Future<BigInt>? getDEuroAccruedInterest(WalletBase wallet) => null;
Future<Money>? getDEuroSavingsBalance(WalletBase wallet) => null;
Future<Money>? getDEuroSavingsV1Balance(WalletBase wallet) => null;
Future<Money>? getDEuroAccruedInterest(WalletBase wallet) => null;
Future<BigInt>? getDEuroInterestRate(WalletBase wallet) => null;
Future<BigInt>? getDEuroSavingsApproved(WalletBase wallet) => null;
Future<PendingTransaction>? withdrawDEuroSavingV1(WalletBase wallet, TransactionPriority priority) => null;
Future<PendingTransaction>? addDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority) => null;
Future<PendingTransaction>? removeDEuroSaving(WalletBase wallet, BigInt amount, TransactionPriority priority) => null;
Future<PendingTransaction>? reinvestDEuroInterest(WalletBase wallet, TransactionPriority priority) => null;
@@ -1153,6 +1150,7 @@ abstract class EVM {
WalletType? getWalletTypeByChainId(int chainId);
String getChainNameByChainId(int chainId);
String getTokenNameByChainId(int chainId);
String? getMoralisChainName(WalletBase wallet);
// Chain selection methods
List<ChainInfo> getAllChains();
ChainInfo? getCurrentChain(WalletBase wallet);
@@ -1195,6 +1193,24 @@ abstract class EVM {
WalletBase wallet,
TransactionPriority priority,
);
TransactionInfo getTransactionInfo({
required String id,
required int height,
required Money amount,
required Money fee,
required String tokenSymbol,
int exponent = 18,
required TransactionDirection direction,
required bool isPending,
required DateTime date,
required int confirmations,
String? to,
String? from,
String? evmSignatureName,
String? contractAddress,
required int chainId,
});
Future<void> discoverAndAddWalletTokens(WalletBase wallet);
}