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
+109 -90
View File
@@ -2,7 +2,7 @@ import UIKit
import Flutter
@main
@objc class AppDelegate: FlutterAppDelegate {
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
@@ -11,101 +11,120 @@ import Flutter
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
makeSecure()
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let legacyMigrationChannel = FlutterMethodChannel(
name: "com.cakewallet.cakewallet/legacy_wallet_migration",
binaryMessenger: controller.binaryMessenger)
legacyMigrationChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
switch call.method {
case "decrypt":
guard let args = call.arguments as? Dictionary<String, Any>,
let data = args["bytes"] as? FlutterStandardTypedData,
let key = args["key"] as? String,
let salt = args["salt"] as? String else {
result(nil)
return
}
let content = decrypt(data: data.data, key: key, salt: salt)
result(content)
case "read_user_defaults":
guard let args = call.arguments as? Dictionary<String, Any>,
let key = args["key"] as? String,
let type = args["type"] as? String else {
result(nil)
return
}
var value: Any?
switch (type) {
case "string":
value = UserDefaults.standard.string(forKey: key)
case "int":
value = UserDefaults.standard.integer(forKey: key)
case "bool":
value = UserDefaults.standard.bool(forKey: key)
default:
break
}
result(value)
default:
result(FlutterMethodNotImplemented)
}
})
let utilsChannel = FlutterMethodChannel(
name: "com.cake_wallet/native_utils",
binaryMessenger: controller.binaryMessenger)
utilsChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
switch call.method {
case "sec_random":
guard let args = call.arguments as? Dictionary<String, Any>,
let count = args["count"] as? Int else {
result(nil)
return
}
DispatchQueue.main.async { [weak self] in
self?.makeSecure()
}
result(secRandom(count: count))
case "setIsAppSecure":
guard let args = call.arguments as? Dictionary<String, Bool>,
let isAppSecure = args["isAppSecure"] else {
result(nil)
return
}
if isAppSecure {
self?.textField.isSecureTextEntry = true
} else {
self?.textField.isSecureTextEntry = false
}
result(nil)
default:
result(FlutterMethodNotImplemented)
}
})
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
let messenger = engineBridge.applicationRegistrar.messenger()
let legacyMigrationChannel = FlutterMethodChannel(
name: "com.cakewallet.cakewallet/legacy_wallet_migration",
binaryMessenger: messenger)
legacyMigrationChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
switch call.method {
case "decrypt":
guard let args = call.arguments as? Dictionary<String, Any>,
let data = args["bytes"] as? FlutterStandardTypedData,
let key = args["key"] as? String,
let salt = args["salt"] as? String else {
result(nil)
return
}
let content = decrypt(data: data.data, key: key, salt: salt)
result(content)
case "read_user_defaults":
guard let args = call.arguments as? Dictionary<String, Any>,
let key = args["key"] as? String,
let type = args["type"] as? String else {
result(nil)
return
}
var value: Any?
switch (type) {
case "string":
value = UserDefaults.standard.string(forKey: key)
case "int":
value = UserDefaults.standard.integer(forKey: key)
case "bool":
value = UserDefaults.standard.bool(forKey: key)
default:
break
}
result(value)
default:
result(FlutterMethodNotImplemented)
}
})
let utilsChannel = FlutterMethodChannel(
name: "com.cake_wallet/native_utils",
binaryMessenger: messenger)
utilsChannel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
switch call.method {
case "sec_random":
guard let args = call.arguments as? Dictionary<String, Any>,
let count = args["count"] as? Int else {
result(nil)
return
}
result(secRandom(count: count))
case "setIsAppSecure":
guard let args = call.arguments as? Dictionary<String, Bool>,
let isAppSecure = args["isAppSecure"] else {
result(nil)
return
}
if isAppSecure {
self?.textField.isSecureTextEntry = true
} else {
self?.textField.isSecureTextEntry = false
}
result(nil)
default:
result(FlutterMethodNotImplemented)
}
})
}
private var textField = UITextField()
private func makeSecure() {
if (!self.window.subviews.contains(textField)) {
let view = UIView(frame: CGRect(x: 0, y: 0, width: textField.frame.self.width, height: textField.frame.self.height))
self.window.addSubview(textField)
self.window.layer.superlayer?.addSublayer(textField.layer)
textField.layer.sublayers?.last!.addSublayer(self.window.layer)
textField.leftView = view
textField.leftViewMode = .always
}
private func keyWindow() -> UIWindow? {
UIApplication.shared.connectedScenes
.compactMap { $0 as? UIWindowScene }
.flatMap { $0.windows }
.first { $0.isKeyWindow }
}
private func makeSecure() {
guard let window = self.window ?? keyWindow() else { return }
if (!window.subviews.contains(textField)) {
let view = UIView(frame: CGRect(x: 0, y: 0, width: textField.frame.self.width, height: textField.frame.self.height))
window.addSubview(textField)
window.layer.superlayer?.addSublayer(textField.layer)
textField.layer.sublayers?.last?.addSublayer(window.layer)
textField.leftView = view
textField.leftViewMode = .always
}
}
}
+24
View File
@@ -195,6 +195,7 @@
<string>solana-wallet</string>
<key>CFBundleURLSchemes</key>
<array>
<string>solana</string>
<string>solana-wallet</string>
</array>
</dict>
@@ -447,5 +448,28 @@
<false/>
<key>FlutterDeepLinkingEnabled</key>
<false/>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneDelegateClassName</key>
<string>FlutterSceneDelegate</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>