CW-1228: Automatically detect wallet tokens for EVM chains (#2827)

* feat: Automatically detect wallet tokens for EVM chains

* feat: Disable potential tg scam tokens by default

* feat: Add homoglyph normalization to detect spoofing attacks in token symbols

* refactor: Improve scam token detection and apply to automatically fetched EVM tokens

* refactor: Enhance scam detection for automatically detected tokens in evm wallets

* feat: Add fiat check to scam checks on automatically imported token and disable tokens that fail the check

* feat: Add fiat check to scam checks on automatically imported token and disable tokens that fail the check

* feat: Add fiat check to scam checks on automatically imported token and disable tokens that fail the check

* feat: Enable whitelisted tokens with balance when importing wallet tokens
This commit is contained in:
David Adegoke
2026-02-05 13:53:39 +01:00
committed by GitHub
parent 308de0389d
commit 4f8cccce4f
8 changed files with 419 additions and 73 deletions
@@ -101,78 +101,83 @@ class BalanceRowWidget extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: hasAdditionalBalance
? () => _showBalanceDescription(
context, S.of(context).available_balance_description)
: null,
child: Row(
children: [
Semantics(
hint: 'Double tap to see more information',
container: true,
child: Text(
'${availableBalanceLabel}',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
),
if (hasAdditionalBalance)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Icon(
Icons.help_outline,
size: 16,
color: Theme.of(context).colorScheme.onSurfaceVariant,
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: hasAdditionalBalance
? () => _showBalanceDescription(
context, S.of(context).available_balance_description)
: null,
child: Row(
children: [
Semantics(
hint: 'Double tap to see more information',
container: true,
child: Text(
'${availableBalanceLabel}',
style: Theme.of(context).textTheme.bodySmall?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
),
],
if (hasAdditionalBalance)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 4),
child: Icon(
Icons.help_outline,
size: 16,
color: Theme.of(context).colorScheme.onSurfaceVariant,
),
),
],
),
),
),
SizedBox(height: 6),
AutoSizeText(
availableBalance,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.w900,
fontSize: 24,
height: 1,
),
maxLines: 1,
textAlign: TextAlign.start,
),
SizedBox(height: 6),
if (isTestnet)
Text(
S.of(context).testnet_coins_no_value,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
SizedBox(height: 6),
AutoSizeText(
availableBalance,
minFontSize: 16,
overflow: TextOverflow.ellipsis,
style: Theme.of(context).textTheme.titleLarge?.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.w900,
fontSize: 24,
height: 1,
),
maxLines: 1,
textAlign: TextAlign.start,
),
if (!isTestnet)
Text(
'${availableFiatBalance}',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
],
SizedBox(height: 6),
if (isTestnet)
Text(
S.of(context).testnet_coins_no_value,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
height: 1,
),
),
if (!isTestnet)
Text(
'${availableFiatBalance}',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
fontSize: 16,
fontWeight: FontWeight.w500,
color: Theme.of(context).colorScheme.onSurfaceVariant,
height: 1,
),
),
],
),
),
SizedBox(
//width: min(MediaQuery.of(context).size.width * 0.2, 100),
child: Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
CakeImageWidget(
imageUrl: currency.iconPath,