CW-608-Fetch-And-Save-Icons-Of-ERC20-And-SPL-Tokens-When-Adding-Them (#1365)

* feat: Fetch and save icons of SPL tokens when adding them

* feat: Implement fetch and save icons for ERC20 tokens when adding them

* fix: Add moralisApiKey to evm secrets

* Add check to ensure decimals cannot be zero

* - Fallback to adding erc20 token from web3dart
- Wrap fetching spl token icon in a try/catch block

---------

Co-authored-by: OmarHatem <omarh.ismail1@gmail.com>
This commit is contained in:
Adegoke David
2024-04-09 00:53:14 +02:00
committed by GitHub
co-authored by OmarHatem
parent d4b317b3a0
commit 2877cc160c
41 changed files with 182 additions and 69 deletions
+1 -1
View File
@@ -131,7 +131,7 @@ class CWEthereum extends Ethereum {
@override
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) async {
final ethereumWallet = wallet as EthereumWallet;
return await ethereumWallet.getErc20Token(contractAddress);
return await ethereumWallet.getErc20Token(contractAddress, 'eth');
}
@override
+1 -1
View File
@@ -129,7 +129,7 @@ class CWPolygon extends Polygon {
@override
Future<Erc20Token?> getErc20Token(WalletBase wallet, String contractAddress) async {
final polygonWallet = wallet as PolygonWallet;
return await polygonWallet.getErc20Token(contractAddress);
return await polygonWallet.getErc20Token(contractAddress, 'polygon');
}
@override
+1
View File
@@ -86,6 +86,7 @@ class CWSolana extends Solana {
decimal: token.decimals,
mint: token.name.toUpperCase(),
enabled: token.enabled,
iconPath: token.iconPath,
);
await (wallet as SolanaWallet).addSPLToken(splToken);
@@ -59,6 +59,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
final TextEditingController _tokenNameController = TextEditingController();
final TextEditingController _tokenSymbolController = TextEditingController();
final TextEditingController _tokenDecimalController = TextEditingController();
final TextEditingController _tokenIconPathController = TextEditingController();
final FocusNode _contractAddressFocusNode = FocusNode();
final FocusNode _tokenNameFocusNode = FocusNode();
@@ -83,6 +84,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
_tokenNameController.text = widget.token!.name;
_tokenSymbolController.text = widget.token!.title;
_tokenDecimalController.text = widget.token!.decimals.toString();
_tokenIconPathController.text = widget.token?.iconPath ?? '';
}
if (widget.initialContractAddress != null) {
@@ -200,6 +202,7 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
name: _tokenNameController.text,
title: _tokenSymbolController.text.toUpperCase(),
decimals: int.parse(_tokenDecimalController.text),
iconPath: _tokenIconPathController.text,
),
contractAddress: _contractAddressController.text,
);
@@ -228,6 +231,8 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
if (token != null) {
if (_tokenNameController.text.isEmpty) _tokenNameController.text = token.name;
if (_tokenSymbolController.text.isEmpty) _tokenSymbolController.text = token.title;
if (_tokenIconPathController.text.isEmpty)
_tokenIconPathController.text = token.iconPath ?? '';
if (_tokenDecimalController.text.isEmpty)
_tokenDecimalController.text = token.decimals.toString();
}
@@ -305,10 +310,15 @@ class _EditTokenPageBodyState extends State<EditTokenPageBody> {
if (text?.isEmpty ?? true) {
return S.of(context).field_required;
}
if (int.tryParse(text!) == null) {
return S.of(context).invalid_input;
}
if (int.tryParse(text) == 0) {
return S.current.decimals_cannot_be_zero;
}
return null;
},
),
@@ -129,25 +129,29 @@ class HomeSettingsPage extends BasePage {
'token': token,
});
},
leading: CakeImageWidget(
imageUrl: token.iconPath,
height: 40,
width: 40,
displayOnError: Container(
height: 30.0,
width: 30.0,
child: Center(
child: Text(
token.title.substring(0, min(token.title.length, 2)),
style: TextStyle(fontSize: 11),
),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey.shade400,
leading: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(shape: BoxShape.circle),
child: CakeImageWidget(
imageUrl: token.iconPath,
height: 40,
width: 40,
displayOnError: Container(
height: 30.0,
width: 30.0,
child: Center(
child: Text(
token.title.substring(0, min(token.title.length, 2)),
style: TextStyle(fontSize: 11),
),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey.shade400,
),
),
),
),
),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(30),
@@ -323,7 +323,7 @@ class BalanceRowWidget extends StatelessWidget {
style: TextStyle(
fontSize: 16,
fontFamily: 'Lato',
fontWeight: FontWeight.w500,
fontWeight: FontWeight.w500,
color: Theme.of(context).extension<BalancePageTheme>()!.textColor,
height: 1)),
],
@@ -334,24 +334,28 @@ class BalanceRowWidget extends StatelessWidget {
child: Center(
child: Column(
children: [
CakeImageWidget(
imageUrl: currency.iconPath,
height: 40,
width: 40,
displayOnError: Container(
height: 30.0,
width: 30.0,
child: Center(
child: Text(
currency.title.substring(0, min(currency.title.length, 2)),
style: TextStyle(fontSize: 11),
),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey.shade400,
Container(
clipBehavior: Clip.antiAlias,
decoration: BoxDecoration(shape: BoxShape.circle),
child: CakeImageWidget(
imageUrl: currency.iconPath,
height: 40,
width: 40,
displayOnError: Container(
height: 30.0,
width: 30.0,
child: Center(
child: Text(
currency.title.substring(0, min(currency.title.length, 2)),
style: TextStyle(fontSize: 11),
),
),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey.shade400,
),
),
),
),
const SizedBox(height: 10),
Text(
@@ -410,9 +414,7 @@ class BalanceRowWidget extends StatelessWidget {
fontSize: 20,
fontFamily: 'Lato',
fontWeight: FontWeight.w400,
color: Theme.of(context)
.extension<BalancePageTheme>()!
.balanceAmountColor,
color: Theme.of(context).extension<BalancePageTheme>()!.balanceAmountColor,
height: 1,
),
maxLines: 1,
+1 -1
View File
@@ -18,7 +18,7 @@ class CakeImageWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
try {
if (imageUrl == null) return _displayOnError!;
if (imageUrl == null || imageUrl!.isEmpty) return _displayOnError!;
if (imageUrl!.contains('assets/images')) {
return Image.asset(
@@ -54,6 +54,7 @@ abstract class HomeSettingsViewModelBase with Store {
symbol: token.title,
decimal: token.decimals,
contractAddress: contractAddress,
iconPath: token.iconPath,
);
await ethereum!.addErc20Token(_balanceViewModel.wallet, erc20token);
@@ -65,6 +66,7 @@ abstract class HomeSettingsViewModelBase with Store {
symbol: token.title,
decimal: token.decimals,
contractAddress: contractAddress,
iconPath: token.iconPath,
);
await polygon!.addErc20Token(_balanceViewModel.wallet, polygonToken);
}