Generic fixes (#1348)

* Change order of currencies in currency picker * Disable Background sync until implemented properly * remove ability to use device pin in bio auth * Fix condition * Minor fix [skip ci] * make notifications red dot go when opened * Update Frozen coin text color * Update Frozen coin text color * Fetch internal transactions for eth and polygon * Remove debug prints [skip ci] * Fix Camera permission on iOS [skip ci] --------- Co-authored-by: tuxsudo <tuxsudo@tux.pizza>

Omar Hatem committed Mar 29, 2024 at 20:54 UTC 698c22229109ca4da39269ac96416c7bdc18bcd7
15 files changed +87 -30
cw_core/lib/crypto_currency.dart
+2 -2
@@ -38,6 +38,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
38 CryptoCurrency.trx,
39 CryptoCurrency.usdt,
40 CryptoCurrency.usdterc20,
41 + CryptoCurrency.sol,
42 + CryptoCurrency.maticpoly,
43 CryptoCurrency.xlm,
44 CryptoCurrency.xrp,
45 CryptoCurrency.xhv,
@@ -50,7 +52,6 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
52 CryptoCurrency.usdttrc20,
53 CryptoCurrency.hbar,
54 CryptoCurrency.sc,
53 - CryptoCurrency.sol,
55 CryptoCurrency.usdc,
56 CryptoCurrency.usdcsol,
57 CryptoCurrency.zaddr,
@@ -61,7 +62,6 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
62 CryptoCurrency.dcr,
63 CryptoCurrency.kmd,
64 CryptoCurrency.mana,
64 - CryptoCurrency.maticpoly,
65 CryptoCurrency.matic,
66 CryptoCurrency.mkr,
67 CryptoCurrency.near,
cw_ethereum/lib/ethereum_client.dart
+25
@@ -41,4 +41,29 @@ class EthereumClient extends EVMChainClient {
41 return [];
42 }
43 }
44 +
45 + @override
46 + Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address) async {
47 + try {
48 + final response = await httpClient.get(Uri.https("api.etherscan.io", "/api", {
49 + "module": "account",
50 + "action": "txlistinternal",
51 + "address": "0x72067Bf532b21A096D2e2B4953d69554E1a61917",
52 + "apikey": secrets.etherScanApiKey,
53 + }));
54 +
55 + final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
56 +
57 + if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
58 + return (jsonResponse['result'] as List)
59 + .map((e) => EVMChainTransactionModel.fromJson(e as Map<String, dynamic>, 'ETH'))
60 + .toList();
61 + }
62 +
63 + return [];
64 + } catch (e) {
65 + log(e.toString());
66 + return [];
67 + }
68 + }
69 }
cw_evm/lib/evm_chain_client.dart
+2
@@ -27,6 +27,8 @@ abstract class EVMChainClient {
27 Future<List<EVMChainTransactionModel>> fetchTransactions(String address,
28 {String? contractAddress});
29
30 + Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address);
31 +
32 Uint8List prepareSignedTransactionForSending(Uint8List signedTransaction);
33
34 //! Common methods across all child classes
cw_evm/lib/evm_chain_transaction_model.dart
+9 -9
@@ -32,15 +32,15 @@ class EVMChainTransactionModel {
32 factory EVMChainTransactionModel.fromJson(Map<String, dynamic> json, String defaultSymbol) =>
33 EVMChainTransactionModel(
34 date: DateTime.fromMillisecondsSinceEpoch(int.parse(json["timeStamp"]) * 1000),
35 - hash: json["hash"],
36 - from: json["from"],
37 - to: json["to"],
38 - amount: BigInt.parse(json["value"]),
39 - gasUsed: int.parse(json["gasUsed"]),
40 - gasPrice: BigInt.parse(json["gasPrice"]),
41 - contractAddress: json["contractAddress"],
42 - confirmations: int.parse(json["confirmations"]),
43 - blockNumber: int.parse(json["blockNumber"]),
35 + hash: json["hash"] ?? "",
36 + from: json["from"] ?? "",
37 + to: json["to"] ?? "",
38 + amount: BigInt.parse(json["value"] ?? "0"),
39 + gasUsed: int.parse(json["gasUsed"] ?? "0"),
40 + gasPrice: BigInt.parse(json["gasPrice"] ?? "0"),
41 + contractAddress: json["contractAddress"] ?? "",
42 + confirmations: int.parse(json["confirmations"] ?? "0"),
43 + blockNumber: int.parse(json["blockNumber"] ?? "0"),
44 tokenSymbol: json["tokenSymbol"] ?? defaultSymbol,
45 tokenDecimal: int.tryParse(json["tokenDecimal"] ?? ""),
46 isError: json["isError"] == "1",
cw_evm/lib/evm_chain_wallet.dart
+3 -1
@@ -318,6 +318,7 @@ abstract class EVMChainWalletBase
318 Future<Map<String, EVMChainTransactionInfo>> fetchTransactions() async {
319 final address = _evmChainPrivateKey.address.hex;
320 final transactions = await _client.fetchTransactions(address);
321 + final internalTransactions = await _client.fetchInternalTransactions(address);
322
323 final List<Future<List<EVMChainTransactionModel>>> erc20TokensTransactions = [];
324
@@ -332,6 +333,7 @@ abstract class EVMChainWalletBase
333
334 final tokensTransaction = await Future.wait(erc20TokensTransactions);
335 transactions.addAll(tokensTransaction.expand((element) => element));
336 + transactions.addAll(internalTransactions);
337
338 final Map<String, EVMChainTransactionInfo> result = {};
339
@@ -492,7 +494,7 @@ abstract class EVMChainWalletBase
494 _transactionsUpdateTimer!.cancel();
495 }
496
495 - _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 10), (_) {
497 + _transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 15), (_) {
498 _updateTransactions();
499 _updateBalance();
500 });
cw_polygon/lib/polygon_client.dart
+24
@@ -56,4 +56,28 @@ class PolygonClient extends EVMChainClient {
56 return [];
57 }
58 }
59 +
60 + @override
61 + Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address) async {
62 + try {
63 + final response = await httpClient.get(Uri.https("api.polygonscan.io", "/api", {
64 + "module": "account",
65 + "action": "txlistinternal",
66 + "address": address,
67 + "apikey": secrets.polygonScanApiKey,
68 + }));
69 +
70 + final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
71 +
72 + if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
73 + return (jsonResponse['result'] as List)
74 + .map((e) => EVMChainTransactionModel.fromJson(e as Map<String, dynamic>, 'ETH'))
75 + .toList();
76 + }
77 +
78 + return [];
79 + } catch (_) {
80 + return [];
81 + }
82 + }
83 }
ios/Podfile
+3 -3
@@ -58,16 +58,16 @@ post_install do |installer|
58 'PERMISSION_CONTACTS=0',
59
60 ## dart: PermissionGroup.camera
61 - 'PERMISSION_CAMERA=0',
61 + 'PERMISSION_CAMERA=1',
62
63 ## dart: PermissionGroup.microphone
64 - 'PERMISSION_MICROPHONE=0',
64 + 'PERMISSION_MICROPHONE=1',
65
66 ## dart: PermissionGroup.speech
67 'PERMISSION_SPEECH_RECOGNIZER=0',
68
69 ## dart: PermissionGroup.photos
70 - 'PERMISSION_PHOTOS=0',
70 + 'PERMISSION_PHOTOS=1',
71
72 ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
73 'PERMISSION_LOCATION=0',
ios/Podfile.lock
+1 -1
@@ -300,6 +300,6 @@ SPEC CHECKSUMS:
300 wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
301 workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
302
303 -PODFILE CHECKSUM: fcb1b8418441a35b438585c9dd8374e722e6c6ca
303 +PODFILE CHECKSUM: a2fe518be61cdbdc5b0e2da085ab543d556af2d3
304
305 COCOAPODS: 1.15.2
lib/entities/background_tasks.dart
+2 -1
@@ -4,6 +4,7 @@ import 'package:cake_wallet/core/wallet_loading_service.dart';
4 import 'package:cake_wallet/entities/preferences_key.dart';
5 import 'package:cake_wallet/store/settings_store.dart';
6 import 'package:cake_wallet/utils/device_info.dart';
7 +import 'package:cake_wallet/utils/feature_flag.dart';
8 import 'package:cake_wallet/view_model/settings/sync_mode.dart';
9 import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
10 import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
@@ -107,7 +108,7 @@ class BackgroundTasks {
108 final SyncMode syncMode = settingsStore.currentSyncMode;
109 final bool syncAll = settingsStore.currentSyncAll;
110
110 - if (syncMode.type == SyncType.disabled) {
111 + if (syncMode.type == SyncType.disabled || !FeatureFlag.isBackgroundSyncEnabled) {
112 cancelSyncTask();
113 return;
114 }
lib/entities/biometric_auth.dart
+1
@@ -10,6 +10,7 @@ class BiometricAuth {
10 return await _localAuth.authenticate(
11 localizedReason: S.current.biometric_auth_reason,
12 options: AuthenticationOptions(
13 + biometricOnly: true,
14 useErrorDialogs: true,
15 stickyAuth: false));
16 } on PlatformException catch (e) {
lib/src/screens/exchange/widgets/exchange_card.dart
+5 -5
@@ -485,14 +485,14 @@ class ExchangeCardState extends State<ExchangeCard> {
485 context: context,
486 builder: (dialogContext) {
487 return AlertWithTwoActions(
488 - alertTitle: S.of(context).overwrite_amount,
489 - alertContent: S.of(context).qr_payment_amount,
490 - rightButtonText: S.of(context).ok,
491 - leftButtonText: S.of(context).cancel,
488 + alertTitle: S.of(dialogContext).overwrite_amount,
489 + alertContent: S.of(dialogContext).qr_payment_amount,
490 + rightButtonText: S.of(dialogContext).ok,
491 + leftButtonText: S.of(dialogContext).cancel,
492 actionRightButton: () {
493 widget.amountFocusNode?.requestFocus();
494 amountController.text = paymentRequest.amount;
495 - Navigator.of(context).pop();
495 + Navigator.of(dialogContext).pop();
496 },
497 actionLeftButton: () => Navigator.of(dialogContext).pop());
498 });
lib/src/screens/settings/connection_sync_page.dart
+1 -2
@@ -15,7 +15,6 @@ import 'package:flutter/material.dart';
15 import 'package:cake_wallet/routes.dart';
16 import 'package:cake_wallet/generated/i18n.dart';
17 import 'package:cake_wallet/src/screens/base_page.dart';
18 -import 'package:cake_wallet/src/widgets/standard_list.dart';
18 import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
19 import 'package:flutter_mobx/flutter_mobx.dart';
20
@@ -43,7 +42,7 @@ class ConnectionSyncPage extends BasePage {
42 title: S.current.rescan,
43 handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
44 ),
46 - if (DeviceInfo.instance.isMobile) ...[
45 + if (DeviceInfo.instance.isMobile && FeatureFlag.isBackgroundSyncEnabled) ...[
46 Observer(builder: (context) {
47 return SettingsPickerCell<SyncMode>(
48 title: S.current.background_sync_mode,
lib/src/screens/unspent_coins/widgets/unspent_coins_list_item.dart
+7 -5
@@ -27,10 +27,12 @@ class UnspentCoinsListItem extends StatelessWidget {
27 Widget build(BuildContext context) {
28 final unselectedItemColor = Theme.of(context).cardColor;
29 final selectedItemColor = Theme.of(context).primaryColor;
30 - final itemColor = isSending ? selectedItemColor : unselectedItemColor;
31 -
32 - final amountColor =
33 - isSending ? Colors.white : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor;
30 + final itemColor = isSending
31 + ? selectedItemColor
32 + : unselectedItemColor;
33 + final amountColor = isSending
34 + ? Colors.white
35 + : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor;
36 final addressColor = isSending
37 ? Colors.white.withOpacity(0.5)
38 : Theme.of(context).extension<CakeTextTheme>()!.buttonSecondaryTextColor;
@@ -85,7 +87,7 @@ class UnspentCoinsListItem extends StatelessWidget {
87 child: Text(
88 S.of(context).frozen,
89 style: TextStyle(
88 - color: amountColor, fontSize: 7, fontWeight: FontWeight.w600),
90 + color: Colors.black, fontSize: 7, fontWeight: FontWeight.w600),
91 )),
92 ],
93 ),
lib/src/widgets/services_updates_widget.dart
+1 -1
@@ -111,7 +111,7 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
111 color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
112 width: 30,
113 ),
114 - if (state.hasData && state.data!.hasUpdates)
114 + if (state.hasData && state.data!.hasUpdates && !wasOpened)
115 Container(
116 height: 7,
117 width: 7,
lib/utils/feature_flag.dart
+1
@@ -2,4 +2,5 @@ class FeatureFlag {
2 static const bool isCakePayEnabled = false;
3 static const bool isExolixEnabled = true;
4 static const bool isInAppTorEnabled = false;
5 + static const bool isBackgroundSyncEnabled = false;
6 }
\ No newline at end of file