Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ enum CoinSubClass {
zhtlc,
unknown;

static String _enumNameLower(CoinSubClass e) {
// Normalize enum value to its lowercased name without the enum prefix
return e.toString().split('.').last.toLowerCase();
}

// TODO: verify all the tickers.
String get ticker {
switch (this) {
Expand All @@ -49,8 +54,9 @@ enum CoinSubClass {
case CoinSubClass.avx20:
return 'AVAX';
case CoinSubClass.utxo:
case CoinSubClass.smartChain:
return 'UTXO';
case CoinSubClass.smartChain:
return 'SMART_CHAIN';
case CoinSubClass.moonriver:
return 'MOVR';
case CoinSubClass.ethereumClassic:
Expand Down Expand Up @@ -144,7 +150,10 @@ enum CoinSubClass {

/// Parse a string to a coin subclass.
///
/// Attempts to match the string to a coin subclass by:
/// Attempts to match the string to a coin subclass with the following
/// precedence:
/// - Exact enum name match (highest priority)
/// - Exact ticker match (with tie-breakers, e.g. 'UTXO' -> utxo)
/// - Partial match to the subclass name
/// - Partial match to the subclass ticker
/// - Partial match to the subclass token standard suffix
Expand All @@ -157,15 +166,45 @@ enum CoinSubClass {

final sanitizedValue = value.toLowerCase().replaceAll(regex, '');

// First, try to find exact enum name match (highest priority)
try {
return CoinSubClass.values.firstWhere(
(e) => _enumNameLower(e) == sanitizedValue,
);
// ignore: avoid_catching_errors
} on StateError {
// If no exact match, continue with other matching strategies
}
Comment thread
CharlVS marked this conversation as resolved.

// Second, try to find exact ticker match (sanitized)
final exactTickerMatches = CoinSubClass.values
.where(
(e) => e.ticker.toLowerCase().replaceAll(regex, '') == sanitizedValue,
)
.toList();
if (exactTickerMatches.isNotEmpty) {
// Tie-breaker for duplicated tickers. Both smartChain and utxo return
// 'UTXO' as ticker; prefer utxo to avoid mislabeling.
if (sanitizedValue == 'utxo') {
return CoinSubClass.utxo;
}

return exactTickerMatches.first;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: UTXO Ticker Misidentification

The CoinSubClass.parse method's new exact ticker matching incorrectly returns smartChain for 'UTXO'. Both smartChain and utxo share 'UTXO' as a ticker, and smartChain appears first in the enum, perpetuating the mislabeling this PR aimed to resolve.

Fix in Cursor Fix in Web


return CoinSubClass.values.firstWhere((e) {
Comment thread
CharlVS marked this conversation as resolved.
// Exit early if exact match to default to previous behavior and avoid
// unnecessary checks.
final matchesValue = e.toString().toLowerCase().contains(sanitizedValue);
// Check if enum name contains the value
final enumName = _enumNameLower(e);
final matchesValue = enumName.contains(sanitizedValue);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Coin Parsing Loses Partial Ticker Match

The CoinSubClass.parse method's fallback logic no longer includes partial ticker matching. The e.ticker.toLowerCase().contains(sanitizedValue) check was removed, so inputs that previously matched partially by ticker will now fail to parse, potentially causing a StateError. This changes the parsing behavior from previous versions.

Fix in Cursor Fix in Web

if (matchesValue) {
return true;
}

final matchesTicker = e.ticker.toLowerCase().contains(sanitizedValue);
// Check if ticker contains the value (partial ticker match, sanitized)
final matchesTicker = e.ticker
.toLowerCase()
.replaceAll(regex, '')
.contains(sanitizedValue);
if (matchesTicker) {
return true;
}
Expand All @@ -184,7 +223,7 @@ enum CoinSubClass {
static CoinSubClass? tryParse(String value) {
try {
return parse(value);
} catch (_) {
} on StateError {
return null;
}
}
Expand Down Expand Up @@ -239,7 +278,7 @@ enum CoinSubClass {
case CoinSubClass.matic:
return 'Polygon';
case CoinSubClass.utxo:
return 'UTXO';
return 'Native';
case CoinSubClass.smartBch:
return 'SmartBCH';
case CoinSubClass.erc20:
Expand Down
Loading