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