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
+5
View File
@@ -0,0 +1,5 @@
targets:
$default:
sources:
exclude:
- "**/.secrets.g.dart"
-35
View File
@@ -1,35 +0,0 @@
import 'package:cw_core/balance.dart';
import 'package:nanoutil/nanoutil.dart';
BigInt stringAmountToBigIntBanano(String amount) {
return BigInt.parse(NanoAmounts.getAmountAsRaw(amount, NanoAmounts.rawPerBanano));
}
class BananoBalance extends Balance {
final BigInt currentBalance;
final BigInt receivableBalance;
BananoBalance({required this.currentBalance, required this.receivableBalance})
: super(BigInt.zero, BigInt.zero);
BananoBalance.fromFormattedString(
{required String formattedCurrentBalance, required String formattedReceivableBalance})
: currentBalance = stringAmountToBigIntBanano(formattedCurrentBalance),
receivableBalance = stringAmountToBigIntBanano(formattedReceivableBalance),
super(BigInt.zero, BigInt.zero);
BananoBalance.fromRawString({required String currentBalance, required String receivableBalance})
: currentBalance = BigInt.parse(currentBalance),
receivableBalance = BigInt.parse(receivableBalance),
super(BigInt.zero, BigInt.zero);
@override
String get formattedAvailableBalance {
return NanoAmounts.getRawAsUsableString(currentBalance.toString(), NanoAmounts.rawPerBanano);
}
@override
String get formattedAdditionalBalance {
return NanoAmounts.getRawAsUsableString(receivableBalance.toString(), NanoAmounts.rawPerBanano);
}
}
+14 -29
View File
@@ -1,37 +1,22 @@
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/balance.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:nanoutil/nanoutil.dart';
BigInt stringAmountToBigIntNano(String amount) {
return BigInt.parse(NanoAmounts.getAmountAsRaw(amount, NanoAmounts.rawPerNano));
}
import 'package:cw_core/crypto_currency.dart';
class NanoBalance extends Balance {
final BigInt currentBalance;
final BigInt receivableBalance;
final Money currentBalance;
final Money receivableBalance;
NanoBalance({required this.currentBalance, required this.receivableBalance})
: super(currentBalance, receivableBalance);
NanoBalance.fromFormattedString(
{required String formattedCurrentBalance, required String formattedReceivableBalance})
: currentBalance = stringAmountToBigIntNano(formattedCurrentBalance),
receivableBalance = stringAmountToBigIntNano(formattedReceivableBalance),
super(stringAmountToBigIntNano(formattedCurrentBalance),
stringAmountToBigIntNano(formattedReceivableBalance));
NanoBalance.fromRawString({required String currentBalance, required String receivableBalance})
: currentBalance = BigInt.parse(currentBalance),
receivableBalance = BigInt.parse(receivableBalance),
super(BigInt.parse(currentBalance), BigInt.parse(receivableBalance));
@override
String get formattedAvailableBalance {
return NanoAmounts.getRawAsUsableString(currentBalance.toString(), NanoAmounts.rawPerNano);
}
@override
String get formattedAdditionalBalance {
return NanoAmounts.getRawAsUsableString(receivableBalance.toString(), NanoAmounts.rawPerNano);
}
factory NanoBalance.fromRawString({
required String currentBalance,
required String receivableBalance,
}) =>
NanoBalance(
currentBalance:
Money.tryParse(currentBalance, CryptoCurrency.nano) ?? Money.zero(CryptoCurrency.nano),
receivableBalance: Money.tryParse(receivableBalance, CryptoCurrency.nano) ??
Money.zero(CryptoCurrency.nano),
);
}
+7 -5
View File
@@ -1,6 +1,8 @@
import 'dart:async';
import 'dart:convert';
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/nano_account_info_response.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
@@ -85,10 +87,10 @@ class NanoClient {
throw Exception(
"Error while trying to get balance! ${data["error"] != null ? data["error"] : ""}");
}
final String currentBalance = data["balance"] as String;
final String receivableBalance = data["receivable"] as String;
final BigInt cur = BigInt.parse(currentBalance);
final BigInt rec = BigInt.parse(receivableBalance);
final currentBalance = data["balance"] as String;
final receivableBalance = data["receivable"] as String;
final cur = Money(BigInt.parse(currentBalance), CryptoCurrency.nano);
final rec = Money(BigInt.parse(receivableBalance), CryptoCurrency.nano);
return NanoBalance(currentBalance: cur, receivableBalance: rec);
}
@@ -258,7 +260,7 @@ class NanoClient {
// first get the current account balance:
if (balanceAfterTx == null) {
final BigInt currentBalance = (await getBalance(publicAddress)).currentBalance;
final BigInt currentBalance = (await getBalance(publicAddress)).currentBalance.amount;
final BigInt txAmount = BigInt.parse(amountRaw);
balanceAfterTx = currentBalance - txAmount;
}
+7 -18
View File
@@ -1,13 +1,14 @@
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/format_amount.dart';
import 'package:cw_core/transaction_direction.dart';
import 'package:cw_core/transaction_info.dart';
import 'package:nanoutil/nanoutil.dart';
class NanoTransactionInfo extends TransactionInfo {
NanoTransactionInfo({
required this.id,
required this.height,
required this.amountRaw,
required Money amountRaw,
this.tokenSymbol = "XNO",
required this.direction,
required this.confirmed,
@@ -15,12 +16,11 @@ class NanoTransactionInfo extends TransactionInfo {
required this.confirmations,
required this.to,
required this.from,
}) : this.amount = amountRaw.toInt();
}) : this.amount = amountRaw;
final String id;
final int height;
final int amount;
final BigInt amountRaw;
final Money amount;
final TransactionDirection direction;
final DateTime date;
final bool confirmed;
@@ -32,28 +32,17 @@ class NanoTransactionInfo extends TransactionInfo {
bool get isPending => !this.confirmed;
@override
String amountFormatted() {
final String amt =
NanoAmounts.getRawAsUsableString(amountRaw.toString(), NanoAmounts.rawPerNano);
final String acc = NanoAmounts.getRawAccuracy(amountRaw.toString(), NanoAmounts.rawPerNano);
return "$acc$amt $tokenSymbol";
}
@override
String fiatAmount() => _fiatAmount ?? '';
@override
void changeFiatAmount(String amount) => _fiatAmount = formatAmount(amount);
@override
String feeFormatted() => "0 XNO";
factory NanoTransactionInfo.fromJson(Map<String, dynamic> data) {
return NanoTransactionInfo(
id: data['id'] as String,
height: data['height'] as int,
amountRaw: BigInt.parse(data['amountRaw'] as String),
amountRaw: Money(BigInt.parse(data['amountRaw'] as String), CryptoCurrency.nano),
direction: parseTransactionDirectionFromInt(data['direction'] as int),
date: DateTime.fromMillisecondsSinceEpoch(data['date'] as int),
confirmed: data['confirmed'] as bool,
@@ -67,7 +56,7 @@ class NanoTransactionInfo extends TransactionInfo {
Map<String, dynamic> toJson() => {
'id': id,
'height': height,
'amountRaw': amountRaw.toString(),
'amountRaw': amount.amount.toString(),
'direction': direction.index,
'date': date.millisecondsSinceEpoch,
'confirmed': confirmed,
+17 -13
View File
@@ -3,6 +3,7 @@ import 'dart:convert';
import 'dart:io';
import 'package:bip39/bip39.dart' as bip39;
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/cake_hive.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/encryption_file_utils.dart';
@@ -55,7 +56,10 @@ abstract class NanoWalletBase
walletAddresses = NanoWalletAddresses(walletInfo),
balance = ObservableMap<CryptoCurrency, NanoBalance>.of({
CryptoCurrency.nano: initialBalance ??
NanoBalance(currentBalance: BigInt.zero, receivableBalance: BigInt.zero)
NanoBalance(
currentBalance: Money.zero(CryptoCurrency.nano),
receivableBalance: Money.zero(CryptoCurrency.nano),
)
}),
super(walletInfo, derivationInfo) {
this.walletInfo = walletInfo;
@@ -191,7 +195,7 @@ abstract class NanoWalletBase
BigInt runningAmount = BigInt.zero;
await _updateBalance();
BigInt runningBalance = balance[currency]?.currentBalance ?? BigInt.zero;
BigInt runningBalance = balance[currency]?.currentBalance.amount ?? BigInt.zero;
final List<Map<String, String>> blocks = [];
String? previousHash;
@@ -199,14 +203,13 @@ abstract class NanoWalletBase
for (var txOut in credentials.outputs) {
late BigInt amt;
if (txOut.sendAll) {
amt = balance[currency]?.currentBalance ?? BigInt.zero;
amt = balance[currency]?.currentBalance.amount ?? BigInt.zero;
} else {
amt = BigInt.tryParse(NanoAmounts.getAmountAsRaw(
txOut.cryptoAmount?.replaceAll(',', '.') ?? "0", NanoAmounts.rawPerNano)) ??
BigInt.zero;
amt = txOut.cryptoAmount.amount;
}
if (balance[currency]?.currentBalance != null && amt > balance[currency]!.currentBalance) {
if (balance[currency]?.currentBalance != null &&
amt > balance[currency]!.currentBalance.amount) {
throw Exception("Trying to send more than entire balance!");
}
@@ -233,7 +236,8 @@ abstract class NanoWalletBase
}
try {
if (runningAmount > balance[currency]!.currentBalance || runningBalance < BigInt.zero) {
if (runningAmount > balance[currency]!.currentBalance.amount ||
runningBalance < BigInt.zero) {
throw Exception(("Trying to send more than entire balance!"));
}
} catch (e) {
@@ -241,7 +245,7 @@ abstract class NanoWalletBase
}
return PendingNanoTransaction(
amount: runningAmount,
amount: Money(runningAmount, currency),
id: "",
nanoClient: _client,
blocks: blocks,
@@ -294,7 +298,7 @@ abstract class NanoWalletBase
final bool isSend = transactionModel.type == "send";
result[transactionModel.hash] = NanoTransactionInfo(
id: transactionModel.hash,
amountRaw: transactionModel.amount,
amountRaw: Money(transactionModel.amount, currency),
height: transactionModel.height,
direction: isSend ? TransactionDirection.outgoing : TransactionDirection.incoming,
confirmed: transactionModel.confirmed,
@@ -360,7 +364,7 @@ abstract class NanoWalletBase
// get our balance:
await _updateBalance();
// if we have anything to receive, process it:
if (balance[currency]!.receivableBalance > BigInt.zero) {
if (balance[currency]!.receivableBalance.amount > BigInt.zero) {
await _receiveAll();
}
});
@@ -465,8 +469,8 @@ abstract class NanoWalletBase
// if we don't have a balance, we should at least create one, since it's a late binding
// otherwise, it's better to just leave it as whatever it was before:
if (balance[currency] == null) {
balance[currency] =
NanoBalance(currentBalance: BigInt.zero, receivableBalance: BigInt.zero);
balance[currency] = NanoBalance(
currentBalance: Money.zero(currency), receivableBalance: Money.zero(currency));
}
}
// don't save unnecessarily:
+7 -18
View File
@@ -1,6 +1,7 @@
import 'package:cw_core/amount/money.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_nano/nano_client.dart';
import 'package:nanoutil/nanoutil.dart';
class PendingNanoTransaction with PendingTransaction {
PendingNanoTransaction({
@@ -11,38 +12,26 @@ class PendingNanoTransaction with PendingTransaction {
});
final NanoClient nanoClient;
final BigInt amount;
final String id;
final List<Map<String, String>> blocks;
String hex = "unused";
@override
String get amountFormatted {
final String amt = NanoAmounts.getRawAsUsableString(amount.toString(), NanoAmounts.rawPerNano);
return amt;
}
String get accurateAmountFormatted {
final String amt = NanoAmounts.getRawAsUsableString(amount.toString(), NanoAmounts.rawPerNano);
final String acc = NanoAmounts.getRawAccuracy(amount.toString(), NanoAmounts.rawPerNano);
return "$acc$amt";
}
final Money amount;
@override
String get feeFormatted => "$feeFormattedValue XNO";
String get amountFormatted => amount.toString();
@override
String get feeFormattedValue => "0";
Money get fee => Money.zero(CryptoCurrency.nano);
@override
Future<void> commit() async {
for (var block in blocks) {
for (final block in blocks) {
await nanoClient.processBlock(block, "send");
}
}
@override
Future<Map<String, String>> commitUR() {
throw UnimplementedError();
}
Future<Map<String, String>> commitUR() => throw UnimplementedError();
}
-1060
View File
File diff suppressed because it is too large Load Diff
+6 -5
View File
@@ -6,13 +6,13 @@ author: Hash Bags
homepage: https://github.com/Such-Software/hash-wallet
environment:
sdk: '>=2.18.2 <3.0.0'
sdk: '>=3.0.0 <4.0.0'
flutter: ">=1.17.0"
dependencies:
flutter:
sdk: flutter
mobx: ^2.0.7+4
mobx: ^2.6.0
bip39: ^1.0.6
bip32: ^2.0.0
decimal: ^2.3.3
@@ -31,9 +31,10 @@ dependencies:
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: ^2.4.15
mobx_codegen: ^2.0.7
hive_generator: ^2.0.1
build_runner: ^2.15.0
mobx_codegen: ^2.7.7
# hive_generator: ^2.0.1
hive: 2.0.1
dependency_overrides:
watcher: ^1.1.0
+1
View File
@@ -0,0 +1 @@
../pubspec_overrides.yaml