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>
This commit is contained in:
Omar Hatem 2024-03-29 20:54:59 +02:00 committed by GitHub
parent fd9018bcc4
commit 698c222291
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 87 additions and 30 deletions

View file

@ -38,6 +38,8 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.trx,
CryptoCurrency.usdt,
CryptoCurrency.usdterc20,
CryptoCurrency.sol,
CryptoCurrency.maticpoly,
CryptoCurrency.xlm,
CryptoCurrency.xrp,
CryptoCurrency.xhv,
@ -50,7 +52,6 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.usdttrc20,
CryptoCurrency.hbar,
CryptoCurrency.sc,
CryptoCurrency.sol,
CryptoCurrency.usdc,
CryptoCurrency.usdcsol,
CryptoCurrency.zaddr,
@ -61,7 +62,6 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
CryptoCurrency.dcr,
CryptoCurrency.kmd,
CryptoCurrency.mana,
CryptoCurrency.maticpoly,
CryptoCurrency.matic,
CryptoCurrency.mkr,
CryptoCurrency.near,

View file

@ -41,4 +41,29 @@ class EthereumClient extends EVMChainClient {
return [];
}
}
@override
Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address) async {
try {
final response = await httpClient.get(Uri.https("api.etherscan.io", "/api", {
"module": "account",
"action": "txlistinternal",
"address": "0x72067Bf532b21A096D2e2B4953d69554E1a61917",
"apikey": secrets.etherScanApiKey,
}));
final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
return (jsonResponse['result'] as List)
.map((e) => EVMChainTransactionModel.fromJson(e as Map<String, dynamic>, 'ETH'))
.toList();
}
return [];
} catch (e) {
log(e.toString());
return [];
}
}
}

View file

@ -27,6 +27,8 @@ abstract class EVMChainClient {
Future<List<EVMChainTransactionModel>> fetchTransactions(String address,
{String? contractAddress});
Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address);
Uint8List prepareSignedTransactionForSending(Uint8List signedTransaction);
//! Common methods across all child classes

View file

@ -32,15 +32,15 @@ class EVMChainTransactionModel {
factory EVMChainTransactionModel.fromJson(Map<String, dynamic> json, String defaultSymbol) =>
EVMChainTransactionModel(
date: DateTime.fromMillisecondsSinceEpoch(int.parse(json["timeStamp"]) * 1000),
hash: json["hash"],
from: json["from"],
to: json["to"],
amount: BigInt.parse(json["value"]),
gasUsed: int.parse(json["gasUsed"]),
gasPrice: BigInt.parse(json["gasPrice"]),
contractAddress: json["contractAddress"],
confirmations: int.parse(json["confirmations"]),
blockNumber: int.parse(json["blockNumber"]),
hash: json["hash"] ?? "",
from: json["from"] ?? "",
to: json["to"] ?? "",
amount: BigInt.parse(json["value"] ?? "0"),
gasUsed: int.parse(json["gasUsed"] ?? "0"),
gasPrice: BigInt.parse(json["gasPrice"] ?? "0"),
contractAddress: json["contractAddress"] ?? "",
confirmations: int.parse(json["confirmations"] ?? "0"),
blockNumber: int.parse(json["blockNumber"] ?? "0"),
tokenSymbol: json["tokenSymbol"] ?? defaultSymbol,
tokenDecimal: int.tryParse(json["tokenDecimal"] ?? ""),
isError: json["isError"] == "1",

View file

@ -318,6 +318,7 @@ abstract class EVMChainWalletBase
Future<Map<String, EVMChainTransactionInfo>> fetchTransactions() async {
final address = _evmChainPrivateKey.address.hex;
final transactions = await _client.fetchTransactions(address);
final internalTransactions = await _client.fetchInternalTransactions(address);
final List<Future<List<EVMChainTransactionModel>>> erc20TokensTransactions = [];
@ -332,6 +333,7 @@ abstract class EVMChainWalletBase
final tokensTransaction = await Future.wait(erc20TokensTransactions);
transactions.addAll(tokensTransaction.expand((element) => element));
transactions.addAll(internalTransactions);
final Map<String, EVMChainTransactionInfo> result = {};
@ -492,7 +494,7 @@ abstract class EVMChainWalletBase
_transactionsUpdateTimer!.cancel();
}
_transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 10), (_) {
_transactionsUpdateTimer = Timer.periodic(const Duration(seconds: 15), (_) {
_updateTransactions();
_updateBalance();
});

View file

@ -56,4 +56,28 @@ class PolygonClient extends EVMChainClient {
return [];
}
}
@override
Future<List<EVMChainTransactionModel>> fetchInternalTransactions(String address) async {
try {
final response = await httpClient.get(Uri.https("api.polygonscan.io", "/api", {
"module": "account",
"action": "txlistinternal",
"address": address,
"apikey": secrets.polygonScanApiKey,
}));
final jsonResponse = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode >= 200 && response.statusCode < 300 && jsonResponse['status'] != 0) {
return (jsonResponse['result'] as List)
.map((e) => EVMChainTransactionModel.fromJson(e as Map<String, dynamic>, 'ETH'))
.toList();
}
return [];
} catch (_) {
return [];
}
}
}

View file

@ -58,16 +58,16 @@ post_install do |installer|
'PERMISSION_CONTACTS=0',
## dart: PermissionGroup.camera
'PERMISSION_CAMERA=0',
'PERMISSION_CAMERA=1',
## dart: PermissionGroup.microphone
'PERMISSION_MICROPHONE=0',
'PERMISSION_MICROPHONE=1',
## dart: PermissionGroup.speech
'PERMISSION_SPEECH_RECOGNIZER=0',
## dart: PermissionGroup.photos
'PERMISSION_PHOTOS=0',
'PERMISSION_PHOTOS=1',
## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
'PERMISSION_LOCATION=0',

View file

@ -300,6 +300,6 @@ SPEC CHECKSUMS:
wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47
workmanager: 0afdcf5628bbde6924c21af7836fed07b42e30e6
PODFILE CHECKSUM: fcb1b8418441a35b438585c9dd8374e722e6c6ca
PODFILE CHECKSUM: a2fe518be61cdbdc5b0e2da085ab543d556af2d3
COCOAPODS: 1.15.2

View file

@ -4,6 +4,7 @@ import 'package:cake_wallet/core/wallet_loading_service.dart';
import 'package:cake_wallet/entities/preferences_key.dart';
import 'package:cake_wallet/store/settings_store.dart';
import 'package:cake_wallet/utils/device_info.dart';
import 'package:cake_wallet/utils/feature_flag.dart';
import 'package:cake_wallet/view_model/settings/sync_mode.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_item.dart';
import 'package:cake_wallet/view_model/wallet_list/wallet_list_view_model.dart';
@ -107,7 +108,7 @@ class BackgroundTasks {
final SyncMode syncMode = settingsStore.currentSyncMode;
final bool syncAll = settingsStore.currentSyncAll;
if (syncMode.type == SyncType.disabled) {
if (syncMode.type == SyncType.disabled || !FeatureFlag.isBackgroundSyncEnabled) {
cancelSyncTask();
return;
}

View file

@ -10,6 +10,7 @@ class BiometricAuth {
return await _localAuth.authenticate(
localizedReason: S.current.biometric_auth_reason,
options: AuthenticationOptions(
biometricOnly: true,
useErrorDialogs: true,
stickyAuth: false));
} on PlatformException catch (e) {

View file

@ -485,14 +485,14 @@ class ExchangeCardState extends State<ExchangeCard> {
context: context,
builder: (dialogContext) {
return AlertWithTwoActions(
alertTitle: S.of(context).overwrite_amount,
alertContent: S.of(context).qr_payment_amount,
rightButtonText: S.of(context).ok,
leftButtonText: S.of(context).cancel,
alertTitle: S.of(dialogContext).overwrite_amount,
alertContent: S.of(dialogContext).qr_payment_amount,
rightButtonText: S.of(dialogContext).ok,
leftButtonText: S.of(dialogContext).cancel,
actionRightButton: () {
widget.amountFocusNode?.requestFocus();
amountController.text = paymentRequest.amount;
Navigator.of(context).pop();
Navigator.of(dialogContext).pop();
},
actionLeftButton: () => Navigator.of(dialogContext).pop());
});

View file

@ -15,7 +15,6 @@ import 'package:flutter/material.dart';
import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/base_page.dart';
import 'package:cake_wallet/src/widgets/standard_list.dart';
import 'package:cake_wallet/src/widgets/alert_with_two_actions.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
@ -43,7 +42,7 @@ class ConnectionSyncPage extends BasePage {
title: S.current.rescan,
handler: (context) => Navigator.of(context).pushNamed(Routes.rescan),
),
if (DeviceInfo.instance.isMobile) ...[
if (DeviceInfo.instance.isMobile && FeatureFlag.isBackgroundSyncEnabled) ...[
Observer(builder: (context) {
return SettingsPickerCell<SyncMode>(
title: S.current.background_sync_mode,

View file

@ -27,10 +27,12 @@ class UnspentCoinsListItem extends StatelessWidget {
Widget build(BuildContext context) {
final unselectedItemColor = Theme.of(context).cardColor;
final selectedItemColor = Theme.of(context).primaryColor;
final itemColor = isSending ? selectedItemColor : unselectedItemColor;
final amountColor =
isSending ? Colors.white : Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor;
final itemColor = isSending
? selectedItemColor
: unselectedItemColor;
final amountColor = isSending
? Colors.white
: Theme.of(context).extension<CakeTextTheme>()!.buttonTextColor;
final addressColor = isSending
? Colors.white.withOpacity(0.5)
: Theme.of(context).extension<CakeTextTheme>()!.buttonSecondaryTextColor;
@ -85,7 +87,7 @@ class UnspentCoinsListItem extends StatelessWidget {
child: Text(
S.of(context).frozen,
style: TextStyle(
color: amountColor, fontSize: 7, fontWeight: FontWeight.w600),
color: Colors.black, fontSize: 7, fontWeight: FontWeight.w600),
)),
],
),

View file

@ -111,7 +111,7 @@ class _ServicesUpdatesWidgetState extends State<ServicesUpdatesWidget> {
color: Theme.of(context).extension<DashboardPageTheme>()!.pageTitleTextColor,
width: 30,
),
if (state.hasData && state.data!.hasUpdates)
if (state.hasData && state.data!.hasUpdates && !wasOpened)
Container(
height: 7,
width: 7,

View file

@ -2,4 +2,5 @@ class FeatureFlag {
static const bool isCakePayEnabled = false;
static const bool isExolixEnabled = true;
static const bool isInAppTorEnabled = false;
static const bool isBackgroundSyncEnabled = false;
}