mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-17 05:41:29 +02:00
Cw 1294 fix xo swaps bug (#2645)
* Improve currency parsing with tag support * changenow currency parsing fix * exolix currency parsing fix * letsExchange currency parsing fix * stealth currency parsing fix * trocador currency parsing fix --------- Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:cw_core/currency.dart';
|
||||
import 'package:cw_core/enumerable_item.dart';
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implements Currency {
|
||||
const CryptoCurrency({
|
||||
@@ -336,9 +337,23 @@ class CryptoCurrency extends EnumerableItem<int> with Serializable<int> implemen
|
||||
return CryptoCurrency._fullNameCurrencyMap[name.split("(").first.trim().toLowerCase()]!;
|
||||
}
|
||||
|
||||
static CryptoCurrency? safeParseCurrencyFromString(String? raw, {CryptoCurrency? walletCurrency}) {
|
||||
static CryptoCurrency? safeParseCurrencyFromString(
|
||||
String? raw, {
|
||||
String? tag,
|
||||
CryptoCurrency? walletCurrency,
|
||||
}) {
|
||||
if (raw == null || raw.isEmpty) return null;
|
||||
|
||||
if (tag != null && tag.isNotEmpty) {
|
||||
final match = CryptoCurrency.all.firstWhereOrNull(
|
||||
(e) =>
|
||||
e.title.toUpperCase() == raw.toUpperCase() &&
|
||||
e.tag?.toUpperCase() == tag.toUpperCase(),
|
||||
);
|
||||
if (match != null) return match;
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return CryptoCurrency.fromString(raw, walletCurrency: walletCurrency);
|
||||
} catch (_) {}
|
||||
|
||||
@@ -476,8 +476,12 @@ abstract class EVMChainWalletBase
|
||||
'0x${opReturnMemo.codeUnits.map((char) => char.toRadixString(16).padLeft(2, '0')).join()}';
|
||||
}
|
||||
|
||||
final CryptoCurrency transactionCurrency =
|
||||
balance.keys.firstWhere((element) => element.title == _credentials.currency.title);
|
||||
final transactionCurrency = balance.keys.firstWhere(
|
||||
(currency) =>
|
||||
currency.title == _credentials.currency.title &&
|
||||
currency.tag == _credentials.currency.tag,
|
||||
orElse: () => throw Exception(
|
||||
'Currency ${_credentials.currency.title} ${_credentials.currency.tag} is not accessible in the wallet, try to enable it first.'));
|
||||
|
||||
final currencyBalance = balance[transactionCurrency]!;
|
||||
BigInt totalAmount = BigInt.zero;
|
||||
|
||||
@@ -226,8 +226,12 @@ abstract class SolanaWalletBase
|
||||
|
||||
await _updateBalance();
|
||||
|
||||
final CryptoCurrency transactionCurrency =
|
||||
balance.keys.firstWhere((element) => element.title == solCredentials.currency.title);
|
||||
final transactionCurrency = balance.keys.firstWhere(
|
||||
(currency) =>
|
||||
currency.title == credentials.currency.title &&
|
||||
currency.tag == credentials.currency.tag,
|
||||
orElse: () => throw Exception(
|
||||
'Currency ${credentials.currency.title} ${credentials.currency.tag} is not accessible in the wallet, try to enable it first.'));
|
||||
|
||||
final walletBalanceForCurrency = balance[transactionCurrency]!.balance;
|
||||
|
||||
|
||||
@@ -312,8 +312,13 @@ abstract class TronWalletBase
|
||||
|
||||
final hasMultiDestination = outputs.length > 1;
|
||||
|
||||
final CryptoCurrency transactionCurrency =
|
||||
balance.keys.firstWhere((element) => element.title == tronCredentials.currency.title);
|
||||
final transactionCurrency = balance.keys.firstWhere(
|
||||
(currency) =>
|
||||
currency.title == tronCredentials.currency.title &&
|
||||
currency.tag == tronCredentials.currency.tag,
|
||||
orElse: () => throw Exception(
|
||||
'Currency ${tronCredentials.currency.title} ${tronCredentials.currency.tag} is not accessible in the wallet, try to enable it first.'));
|
||||
|
||||
|
||||
final walletBalanceForCurrency = balance[transactionCurrency]!.balance;
|
||||
|
||||
|
||||
@@ -278,12 +278,21 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
// Parsing 'from' currency
|
||||
final fromCurrency = responseJSON['fromCurrency'] as String;
|
||||
final fromNetwork = responseJSON['fromNetwork'] as String?;
|
||||
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency);
|
||||
final _normalizedFromNetwork = _normalizeNetworkType(fromNetwork ?? '');
|
||||
final fromTag = fromCurrency == _normalizedFromNetwork ? null : _normalizedFromNetwork;
|
||||
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency, tag: fromTag);
|
||||
|
||||
// Parsing 'to' currency
|
||||
final toCurrency = responseJSON['toCurrency'] as String;
|
||||
final toNetwork = responseJSON['toNetwork'] as String?;
|
||||
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency);
|
||||
final _normalizedToNetwork = _normalizeNetworkType(toNetwork ?? '');
|
||||
final toTag = toCurrency == _normalizedToNetwork ? null : _normalizedToNetwork;
|
||||
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency, tag: toTag);
|
||||
|
||||
final inputAddress = responseJSON['payinAddress'] as String;
|
||||
final expectedSendAmount = responseJSON['expectedAmountFrom'].toString();
|
||||
final status = responseJSON['status'] as String;
|
||||
@@ -294,9 +303,6 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
||||
final payoutAddress = responseJSON['payoutAddress'] as String;
|
||||
final expiredAt = DateTime.tryParse(expiredAtRaw ?? '')?.toLocal();
|
||||
|
||||
final _normalizedFromNetwork = _normalizeNetworkType(fromNetwork ?? '');
|
||||
final _normalizedToNetwork = _normalizeNetworkType(toNetwork ?? '');
|
||||
|
||||
return Trade(
|
||||
id: id,
|
||||
from: from,
|
||||
@@ -309,8 +315,8 @@ class ChangeNowExchangeProvider extends ExchangeProvider {
|
||||
expiredAt: expiredAt,
|
||||
outputTransaction: outputTransaction,
|
||||
payoutAddress: payoutAddress,
|
||||
userCurrencyFromRaw: '${fromCurrency.toUpperCase()}' + '_' + '${_normalizedFromNetwork.toUpperCase()}',
|
||||
userCurrencyToRaw: '${toCurrency.toUpperCase()}' + '_' + '${_normalizedToNetwork.toUpperCase()}',
|
||||
userCurrencyFromRaw: '${fromCurrency.toUpperCase()}' + '_' + '${fromTag?.toUpperCase() ?? ''}',
|
||||
userCurrencyToRaw: '${toCurrency.toUpperCase()}' + '_' + '${toTag?.toUpperCase() ?? ''}',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -360,10 +360,19 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
||||
throw Exception('Unexpected http status: ${response.statusCode}');
|
||||
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
|
||||
// Parsing 'from' currency
|
||||
final coinFrom = responseJSON['coinFrom']['coinCode'] as String;
|
||||
final coinFromNetwork = responseJSON['coinFrom']['network'] as String?;
|
||||
final fromTag = coinFrom == coinFromNetwork ? null : coinFromNetwork;
|
||||
final from = CryptoCurrency.safeParseCurrencyFromString(coinFrom, tag: fromTag);
|
||||
|
||||
// Parsing 'to' currency
|
||||
final coinTo = responseJSON['coinTo']['coinCode'] as String;
|
||||
final coinToNetwork = responseJSON['coinTo']['network'] as String?;
|
||||
final toTag = coinTo == coinToNetwork ? null : coinToNetwork;
|
||||
final to = CryptoCurrency.safeParseCurrencyFromString(coinTo, tag: toTag);
|
||||
|
||||
final inputAddress = responseJSON['depositAddress'] as String;
|
||||
final amount = responseJSON['amount'].toString();
|
||||
final status = responseJSON['status'] as String;
|
||||
@@ -373,8 +382,8 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
||||
|
||||
return Trade(
|
||||
id: id,
|
||||
from: CryptoCurrency.safeParseCurrencyFromString(coinFrom),
|
||||
to: CryptoCurrency.safeParseCurrencyFromString(coinTo),
|
||||
from: from,
|
||||
to: to,
|
||||
provider: description,
|
||||
inputAddress: inputAddress,
|
||||
amount: amount,
|
||||
@@ -382,8 +391,8 @@ class ExolixExchangeProvider extends ExchangeProvider {
|
||||
extraId: extraId,
|
||||
outputTransaction: outputTransaction,
|
||||
payoutAddress: payoutAddress,
|
||||
userCurrencyFromRaw: '${coinFrom.toUpperCase()}' + '_' + '${coinFromNetwork ?? ''}',
|
||||
userCurrencyToRaw: '${coinTo.toUpperCase()}' + '_' + '${coinToNetwork ?? ''}',
|
||||
userCurrencyFromRaw: '${coinFrom.toUpperCase()}' + '_' + '${fromTag?.toUpperCase() ?? ''}',
|
||||
userCurrencyToRaw: '${coinTo.toUpperCase()}' + '_' + '${toTag?.toUpperCase() ?? ''}',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -348,10 +348,22 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
|
||||
throw Exception('LetsExchange fetch trade failed: ${response.body}');
|
||||
}
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final from = responseJSON['coin_from'] as String;
|
||||
|
||||
// Parsing 'from' currency
|
||||
final fromCurrency = responseJSON['coin_from'] as String;
|
||||
final fromNetwork = responseJSON['coin_from_network'] as String?;
|
||||
final to = responseJSON['coin_to'] as String;
|
||||
final normalizedFromNetwork = _normalizeNetworkType(fromNetwork ?? '');
|
||||
final fromTag = fromCurrency == normalizedFromNetwork ? null : normalizedFromNetwork;
|
||||
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency, tag: fromTag);
|
||||
|
||||
// Parsing 'to' currency
|
||||
final toCurrency = responseJSON['coin_to'] as String;
|
||||
final toNetwork = responseJSON['coin_to_network'] as String?;
|
||||
final normalizedToNetwork = _normalizeNetworkType(toNetwork ?? '');
|
||||
final toTag = toCurrency == normalizedToNetwork ? null : normalizedToNetwork;
|
||||
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency, tag: toTag);
|
||||
|
||||
|
||||
final payoutAddress = responseJSON['withdrawal'] as String;
|
||||
final depositAddress = responseJSON['deposit'] as String;
|
||||
final refundAddress = responseJSON['return'] as String;
|
||||
@@ -365,13 +377,10 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
|
||||
final createdAt = DateTime.parse(createdAtString).toLocal();
|
||||
final expiredAt = DateTime.fromMillisecondsSinceEpoch(expiredAtTimestamp * 1000).toLocal();
|
||||
|
||||
final normalizedFromNetwork = _normalizeNetworkType(fromNetwork ?? '');
|
||||
final normalizedToNetwork = _normalizeNetworkType(toNetwork ?? '');
|
||||
|
||||
return Trade(
|
||||
id: id,
|
||||
from: CryptoCurrency.safeParseCurrencyFromString(from),
|
||||
to: CryptoCurrency.safeParseCurrencyFromString(to),
|
||||
from: from,
|
||||
to: to,
|
||||
provider: description,
|
||||
inputAddress: depositAddress,
|
||||
payoutAddress: payoutAddress,
|
||||
@@ -383,8 +392,8 @@ class LetsExchangeExchangeProvider extends ExchangeProvider {
|
||||
expiredAt: expiredAt,
|
||||
isRefund: status == 'refund',
|
||||
extraId: extraId,
|
||||
userCurrencyFromRaw: '$from' + '_' + normalizedFromNetwork,
|
||||
userCurrencyToRaw: '$to' + '_' + '$normalizedToNetwork',
|
||||
userCurrencyFromRaw: '${fromCurrency.toUpperCase()}' + '_' + '${fromTag?.toUpperCase() ?? ''}',
|
||||
userCurrencyToRaw: '${toCurrency.toUpperCase()}' + '_' + '${toTag?.toUpperCase() ?? ''}',
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -74,8 +74,8 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
||||
throw Exception('StealthEx fetch limits failed: ${response.body}');
|
||||
}
|
||||
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
|
||||
final min = toDouble(responseJSON['min_amount']);
|
||||
final max = responseJSON['max_amount'] as double?;
|
||||
final min = _toDouble(responseJSON['min_amount']);
|
||||
final max = _toDouble(responseJSON['max_amount']);
|
||||
return Limits(min: min, max: max);
|
||||
} catch (e) {
|
||||
log(e.toString());
|
||||
@@ -230,8 +230,8 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
||||
final payoutAddress = withdrawal['address'] as String;
|
||||
final depositAddress = deposit['address'] as String;
|
||||
final refundAddress = responseJSON['refund_address'] as String;
|
||||
final depositAmount = toDouble(deposit['amount']);
|
||||
final receiveAmount = toDouble(withdrawal['amount']);
|
||||
final depositAmount = _toDouble(deposit['amount']);
|
||||
final receiveAmount = _toDouble(withdrawal['amount']);
|
||||
final status = responseJSON['status'] as String;
|
||||
final createdAtString = responseJSON['created_at'] as String;
|
||||
final extraId = deposit['extra_id'] as String?;
|
||||
@@ -342,15 +342,24 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
||||
final withdrawal = responseJSON['withdrawal'] as Map<String, dynamic>;
|
||||
|
||||
final respId = responseJSON['id'] as String;
|
||||
final from = deposit['symbol'] as String;
|
||||
|
||||
// Parsing 'from' currency with network tag
|
||||
final fromCurrency = deposit['symbol'] as String;
|
||||
final fromNetwork = deposit['network'] as String?;
|
||||
final to = withdrawal['symbol'] as String;
|
||||
final fromTag = fromNetwork == 'mainnet' ? null : fromNetwork;
|
||||
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency, tag: fromTag);
|
||||
|
||||
// Parsing 'to' currency with network tag
|
||||
final toCurrency = withdrawal['symbol'] as String;
|
||||
final toNetwork = withdrawal['network'] as String?;
|
||||
final toTag = toNetwork == 'mainnet' ? null : toNetwork;
|
||||
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency, tag: toTag);
|
||||
|
||||
final payoutAddress = withdrawal['address'] as String;
|
||||
final depositAddress = deposit['address'] as String;
|
||||
final refundAddress = responseJSON['refund_address'] as String;
|
||||
final depositAmount = toDouble(deposit['amount']);
|
||||
final receiveAmount = toDouble(withdrawal['amount']);
|
||||
final depositAmount = _toDouble(deposit['amount']);
|
||||
final receiveAmount = _toDouble(withdrawal['amount']);
|
||||
final status = responseJSON['status'] as String;
|
||||
final createdAtString = responseJSON['created_at'] as String;
|
||||
final createdAt = DateTime.parse(createdAtString).toLocal();
|
||||
@@ -358,8 +367,8 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
||||
|
||||
return Trade(
|
||||
id: respId,
|
||||
from: CryptoCurrency.safeParseCurrencyFromString(from),
|
||||
to: CryptoCurrency.safeParseCurrencyFromString(to),
|
||||
from: from,
|
||||
to: to,
|
||||
provider: description,
|
||||
inputAddress: depositAddress,
|
||||
payoutAddress: payoutAddress,
|
||||
@@ -370,8 +379,8 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
||||
createdAt: createdAt,
|
||||
isRefund: status == 'refunded',
|
||||
extraId: extraId,
|
||||
userCurrencyFromRaw: '${from.toUpperCase()}' + '_' + '${fromNetwork?.toUpperCase() ?? ''}',
|
||||
userCurrencyToRaw: '${to.toUpperCase()}' + '_' + '${toNetwork?.toUpperCase() ?? ''}',
|
||||
userCurrencyFromRaw: '${fromCurrency.toUpperCase()}' + '_' + '${fromTag?.toUpperCase() ?? ''}',
|
||||
userCurrencyToRaw: '${toCurrency.toUpperCase()}' + '_' + '${toTag?.toUpperCase() ?? ''}',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -414,16 +423,18 @@ class StealthExExchangeProvider extends ExchangeProvider {
|
||||
}
|
||||
}
|
||||
|
||||
double toDouble(dynamic value) {
|
||||
static double? _toDouble(dynamic value) {
|
||||
if (value is int) {
|
||||
return value.toDouble();
|
||||
} else if (value is double) {
|
||||
return value;
|
||||
} else {
|
||||
return 0.0;
|
||||
} else if (value is String) {
|
||||
return double.tryParse(value);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
String _getName(CryptoCurrency currency) {
|
||||
if (currency == CryptoCurrency.usdcEPoly) return 'usdce';
|
||||
return currency.title.toLowerCase();
|
||||
|
||||
@@ -420,15 +420,22 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
||||
final providerName = responseJSON['provider'] as String;
|
||||
final addressProviderMemo = responseJSON['address_provider_memo'] as String?;
|
||||
|
||||
final from = responseJSON['ticker_from'] as String;
|
||||
final networkFrom = responseJSON['network_from'] as String?;
|
||||
final to = responseJSON['ticker_to'] as String;
|
||||
final fromCurrency = responseJSON['ticker_from'] as String;
|
||||
final fromNetwork = responseJSON['network_from'] as String?;
|
||||
final _normalizedFromNetwork = _normalizeNetworkType(fromNetwork ?? '');
|
||||
final fromTag = _normalizedFromNetwork.isEmpty || _normalizedFromNetwork == 'Mainnet' ? null : _normalizedFromNetwork;
|
||||
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency, tag: fromTag);
|
||||
|
||||
final toCurrency = responseJSON['ticker_to'] as String;
|
||||
final networkTo = responseJSON['network_to'] as String?;
|
||||
final _normalizedToNetwork = _normalizeNetworkType(networkTo ?? '');
|
||||
final toTag = _normalizedToNetwork.isEmpty || _normalizedToNetwork == 'Mainnet' ? null : _normalizedToNetwork;
|
||||
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency, tag: toTag);
|
||||
|
||||
return Trade(
|
||||
id: id,
|
||||
from: CryptoCurrency.safeParseCurrencyFromString(from),
|
||||
to: CryptoCurrency.safeParseCurrencyFromString(to),
|
||||
from: from,
|
||||
to: to,
|
||||
provider: description,
|
||||
inputAddress: inputAddress,
|
||||
refundAddress: refundAddress,
|
||||
@@ -440,8 +447,8 @@ class TrocadorExchangeProvider extends ExchangeProvider {
|
||||
providerId: providerId,
|
||||
providerName: providerName,
|
||||
extraId: addressProviderMemo,
|
||||
userCurrencyFromRaw: '${from.toUpperCase()}' + '_' + _normalizeNetworkType(networkFrom ?? ''),
|
||||
userCurrencyToRaw: '${to.toUpperCase()}' + '_' + _normalizeNetworkType(networkTo ?? ''), // Handle null network
|
||||
userCurrencyFromRaw: '${fromCurrency.toUpperCase()}' + '_' + '${fromTag?.toUpperCase() ?? ''}',
|
||||
userCurrencyToRaw: '${toCurrency.toUpperCase()}' + '_' + '${toTag?.toUpperCase() ?? ''}',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -43,8 +43,41 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
||||
'LTC': 'litecoin',
|
||||
'EOS': 'eosio',
|
||||
'XLM': 'stellar',
|
||||
'BASE': 'basemainnet',
|
||||
};
|
||||
|
||||
static const supportedTags = [
|
||||
'POL',
|
||||
'ETH',
|
||||
'BTC',
|
||||
'BSC',
|
||||
'SOL',
|
||||
'TRX',
|
||||
'ZEC',
|
||||
'ADA',
|
||||
'DOGE',
|
||||
'XMR',
|
||||
'BCH',
|
||||
'BSV',
|
||||
'XRP',
|
||||
'LTC',
|
||||
'EOS',
|
||||
'XLM',
|
||||
'BASE',
|
||||
];
|
||||
|
||||
|
||||
String _normalizeXOSwapsNetwork(String string) {
|
||||
final lower = string.toLowerCase();
|
||||
|
||||
if (lower.endsWith('matic0a883d9b')) return string.replaceFirst(RegExp(r'matic0a883d9b$', caseSensitive: false), 'POL');
|
||||
if (lower.endsWith('matic86e249c1')) return string.replaceFirst(RegExp(r'matic86e249c1$', caseSensitive: false), 'POL');
|
||||
if (lower.endsWith('bscddedf0f8')) return string.replaceFirst(RegExp(r'bscddedf0f8$', caseSensitive: false), 'BSC');
|
||||
if (lower.endsWith('basemainnetb5a52617')) return string.replaceFirst(RegExp(r'basemainnetb5a52617$', caseSensitive: false), 'BASE');
|
||||
|
||||
return string;
|
||||
}
|
||||
|
||||
@override
|
||||
String get title => 'XOSwap';
|
||||
|
||||
@@ -422,9 +455,46 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
||||
final pairId = responseJSON['pairId'] as String;
|
||||
final pairParts = pairId.split('_');
|
||||
final fromAsset = pairParts.isNotEmpty ? pairParts[0] : '';
|
||||
final normalizedFromAsset = _normalizeXOSwapsNetwork(fromAsset);
|
||||
String? fromAssetTag = _extractTagFromAsset(normalizedFromAsset);
|
||||
|
||||
String fromAssetBase = fromAssetTag != null
|
||||
? normalizedFromAsset.substring(0, normalizedFromAsset.length - fromAssetTag.length)
|
||||
: normalizedFromAsset;
|
||||
|
||||
// Special case for USDT defaulting to ETH tag
|
||||
if (fromAssetBase == 'USDT' && fromAssetTag == null) {
|
||||
fromAssetTag = 'ETH';
|
||||
}
|
||||
|
||||
// Special case for BASE defaulting to BASE tag
|
||||
if (fromAssetBase == 'BASE' && fromAssetTag == null) {
|
||||
fromAssetTag = 'BASE';
|
||||
fromAssetBase = 'ETH';
|
||||
}
|
||||
|
||||
final toAsset = pairParts.length > 1 ? pairParts[1] : '';
|
||||
final fromCurrency = CryptoCurrency.safeParseCurrencyFromString(fromAsset);
|
||||
final toCurrency = CryptoCurrency.safeParseCurrencyFromString(toAsset);
|
||||
final normalizedToAsset = _normalizeXOSwapsNetwork(toAsset);
|
||||
String? toAssetTag = _extractTagFromAsset(normalizedToAsset);
|
||||
|
||||
String toAssetBase = toAssetTag != null
|
||||
? normalizedToAsset.substring(0, normalizedToAsset.length - toAssetTag.length)
|
||||
: normalizedToAsset;
|
||||
|
||||
// Special case for USDT defaulting to ETH tag
|
||||
if (toAssetBase == 'USDT' && toAssetTag == null) {
|
||||
toAssetTag = 'ETH';
|
||||
}
|
||||
|
||||
// Special case for BASE defaulting to BASE tag
|
||||
if (toAssetBase == 'BASE' && toAssetTag == null) {
|
||||
toAssetTag = 'ETH';
|
||||
toAssetBase = 'BASE';
|
||||
}
|
||||
|
||||
final fromCurrency = CryptoCurrency.safeParseCurrencyFromString(fromAssetBase,tag: fromAssetTag);
|
||||
final toCurrency = CryptoCurrency.safeParseCurrencyFromString(toAssetBase,tag: toAssetTag);
|
||||
|
||||
|
||||
final amount = responseJSON['amount'] as Map<String, dynamic>;
|
||||
final toAmount = responseJSON['toAmount'] as Map<String, dynamic>;
|
||||
@@ -439,6 +509,14 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
||||
final createdAt = DateTime.parse(createdAtString).toLocal();
|
||||
final extraId = responseJSON['payInAddressTag'] as String?;
|
||||
|
||||
final userCurrencyFromRaw = fromCurrency != null
|
||||
? '${fromCurrency.title}' + '_' + '${fromCurrency.tag ?? ''}'
|
||||
: '${fromAssetBase}' + '_' + '${fromAssetTag ?? ''}';
|
||||
|
||||
final userCurrencyToRaw = toCurrency != null
|
||||
? '${toCurrency.title}' + '_' + '${toCurrency.tag ?? ''}'
|
||||
: '${toAssetBase}' + '_' + '${toAssetTag ?? ''}';
|
||||
|
||||
return Trade(
|
||||
id: orderId,
|
||||
from: fromCurrency,
|
||||
@@ -452,8 +530,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
||||
receiveAmount: receiveAmount,
|
||||
payoutAddress: payoutAddress,
|
||||
extraId: extraId,
|
||||
userCurrencyFromRaw: '$fromAsset' + '_',
|
||||
userCurrencyToRaw: '$toAsset' + '_',
|
||||
userCurrencyFromRaw: userCurrencyFromRaw,
|
||||
userCurrencyToRaw: userCurrencyToRaw,
|
||||
);
|
||||
} catch (e) {
|
||||
printV(e.toString());
|
||||
@@ -461,6 +539,22 @@ class XOSwapExchangeProvider extends ExchangeProvider {
|
||||
}
|
||||
}
|
||||
|
||||
// ensure something remains before tag (at least 2 chars)
|
||||
String? _extractTagFromAsset(String asset) {
|
||||
|
||||
|
||||
|
||||
for (final tag in supportedTags) {
|
||||
if (asset.endsWith(tag)) {
|
||||
final prefixLength = asset.length - tag.length;
|
||||
if (prefixLength >= 2) {
|
||||
return tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
double _toDouble(dynamic value) {
|
||||
if (value is int) {
|
||||
return value.toDouble();
|
||||
|
||||
Reference in New Issue
Block a user