From 7cc9e360164df93ee785714f74f906925b54cae9 Mon Sep 17 00:00:00 2001 From: Serhii Date: Mon, 17 Feb 2025 15:12:18 +0200 Subject: [PATCH] Cw 870 ethereum enhancements (#1951) * fix evm balance display issues * fix adding token * fix tab controller issue * Update cw_evm/lib/evm_chain_client.dart [skip ci] --------- Co-authored-by: Omar Hatem --- cw_evm/lib/evm_chain_client.dart | 12 ++++-- cw_evm/lib/evm_chain_wallet.dart | 19 ++++++--- cw_evm/lib/evm_erc20_balance.dart | 7 +++- .../screens/dashboard/edit_token_page.dart | 40 +++++++++++++------ .../dashboard/pages/balance/balance_page.dart | 1 + .../dashboard/home_settings_view_model.dart | 5 ++- 6 files changed, 60 insertions(+), 24 deletions(-) diff --git a/cw_evm/lib/evm_chain_client.dart b/cw_evm/lib/evm_chain_client.dart index 7dad39f7a..b505577e9 100644 --- a/cw_evm/lib/evm_chain_client.dart +++ b/cw_evm/lib/evm_chain_client.dart @@ -268,12 +268,18 @@ abstract class EVMChainClient { Future fetchERC20Balances( EthereumAddress userAddress, String contractAddress) async { - final erc20 = ERC20(address: EthereumAddress.fromHex(contractAddress), client: _client!); - final balance = await erc20.balanceOf(userAddress); + try { + final erc20 = ERC20(address: EthereumAddress.fromHex(contractAddress), client: _client!); + final balance = await erc20.balanceOf(userAddress); int exponent = (await erc20.decimals()).toInt(); - return EVMChainERC20Balance(balance, exponent: exponent); + return EVMChainERC20Balance(balance, exponent: exponent); + } on RangeError catch (_) { + throw Exception('Invalid token contract for this network.'); + } catch (e) { + throw Exception('Could not fetch balances: ${e.toString()}'); + } } Future getErc20Token(String contractAddress, String chainName) async { diff --git a/cw_evm/lib/evm_chain_wallet.dart b/cw_evm/lib/evm_chain_wallet.dart index 9ccb05e7f..646abd7ae 100644 --- a/cw_evm/lib/evm_chain_wallet.dart +++ b/cw_evm/lib/evm_chain_wallet.dart @@ -634,14 +634,21 @@ abstract class EVMChainWalletBase final newToken = createNewErc20TokenObject(token, iconPath); - await evmChainErc20TokensBox.put(newToken.contractAddress, newToken); - if (newToken.enabled) { - balance[newToken] = await _client.fetchERC20Balances( - _evmChainPrivateKey.address, - newToken.contractAddress, - ); + try { + final erc20Balance = await _client.fetchERC20Balances( + _evmChainPrivateKey.address, + newToken.contractAddress, + ); + + balance[newToken] = erc20Balance; + + await evmChainErc20TokensBox.put(newToken.contractAddress, newToken); + } on Exception catch (_) { + rethrow; + } } else { + await evmChainErc20TokensBox.put(newToken.contractAddress, newToken); balance.remove(newToken); } } diff --git a/cw_evm/lib/evm_erc20_balance.dart b/cw_evm/lib/evm_erc20_balance.dart index 8962f7053..952d50ba8 100644 --- a/cw_evm/lib/evm_erc20_balance.dart +++ b/cw_evm/lib/evm_erc20_balance.dart @@ -1,5 +1,6 @@ import 'dart:convert'; import 'dart:math'; +import 'package:intl/intl.dart'; import 'package:cw_core/balance.dart'; @@ -17,8 +18,10 @@ class EVMChainERC20Balance extends Balance { String get formattedAvailableBalance => _balance(); String _balance() { - final String formattedBalance = (balance / BigInt.from(10).pow(exponent)).toString(); - return formattedBalance.substring(0, min(12, formattedBalance.length)); + NumberFormat formatter = NumberFormat('0.00##########', 'en_US'); + double numBalance = (balance / BigInt.from(10).pow(exponent)).toDouble(); + String formattedBalance = formatter.format(numBalance); + return formattedBalance; } String toJSON() => json.encode({ diff --git a/lib/src/screens/dashboard/edit_token_page.dart b/lib/src/screens/dashboard/edit_token_page.dart index 9fec96deb..bb0d4a3e2 100644 --- a/lib/src/screens/dashboard/edit_token_page.dart +++ b/lib/src/screens/dashboard/edit_token_page.dart @@ -212,15 +212,34 @@ class _EditTokenPageBodyState extends State { _contractAddressController.text, ); final actionCall = () async { - await widget.homeSettingsViewModel.addToken( - token: CryptoCurrency( - name: _tokenNameController.text, - title: _tokenSymbolController.text.toUpperCase(), - decimals: int.parse(_tokenDecimalController.text), - iconPath: _tokenIconPathController.text, - ), - contractAddress: _contractAddressController.text, - ); + try { + await widget.homeSettingsViewModel.addToken( + token: CryptoCurrency( + name: _tokenNameController.text, + title: _tokenSymbolController.text.toUpperCase(), + decimals: int.parse(_tokenDecimalController.text), + iconPath: _tokenIconPathController.text, + ), + contractAddress: _contractAddressController.text, + ); + + if (mounted) { + Navigator.pop(context); + } + + } catch (e) { + showPopUp( + context: context, + builder: (dialogContext) { + return AlertWithOneAction( + alertTitle: S.current.warning, + alertContent: e.toString(), + buttonText: S.of(context).ok, + buttonAction: () => Navigator.of(dialogContext).pop(), + ); + }, + ); + } }; if (hasPotentialError) { @@ -235,9 +254,6 @@ class _EditTokenPageBodyState extends State { actionRightButton: () async { Navigator.of(dialogContext).pop(); await actionCall(); - if (mounted) { - Navigator.pop(context); - } }, actionLeftButton: () => Navigator.of(dialogContext).pop(), ); diff --git a/lib/src/screens/dashboard/pages/balance/balance_page.dart b/lib/src/screens/dashboard/pages/balance/balance_page.dart index b53d2d56b..e9c2115a9 100644 --- a/lib/src/screens/dashboard/pages/balance/balance_page.dart +++ b/lib/src/screens/dashboard/pages/balance/balance_page.dart @@ -25,6 +25,7 @@ class BalancePage extends StatelessWidget { builder: (context) { final isEVMCompatible = isEVMCompatibleChain(dashboardViewModel.type); return DefaultTabController( + key: ValueKey(isEVMCompatible), length: isEVMCompatible ? 2 : 1, child: Column( children: [ diff --git a/lib/view_model/dashboard/home_settings_view_model.dart b/lib/view_model/dashboard/home_settings_view_model.dart index 04d52a918..197d550c3 100644 --- a/lib/view_model/dashboard/home_settings_view_model.dart +++ b/lib/view_model/dashboard/home_settings_view_model.dart @@ -117,7 +117,10 @@ abstract class HomeSettingsViewModelBase with Store { _updateTokensList(); _updateFiatPrices(token); - } finally { + } catch (e) { + throw e; + } + finally { isAddingToken = false; } }