Reformat the whole codebase with 100 line width (#3403)

This commit is contained in:
Omar Hatem
2026-07-15 01:20:33 +03:00
committed by GitHub
parent 1241b28bec
commit 16ddc0837a
801 changed files with 17517 additions and 17091 deletions
+85 -33
View File
@@ -2,47 +2,99 @@ import 'package:cw_core/enumerable_item.dart';
class ExchangeProviderDescription extends EnumerableItem<int> with Serializable<int> {
const ExchangeProviderDescription(
{required String title, required int raw, required this.image, this.horizontalLogo = false, required this.isCentralized})
{required String title,
required int raw,
required this.image,
this.horizontalLogo = false,
required this.isCentralized})
: super(title: title, raw: raw);
final bool horizontalLogo;
final String image;
final bool isCentralized;
static const xmrto =
ExchangeProviderDescription(title: 'XMR.TO', raw: 0, image: 'assets/new-ui/trade_providers/xmrto.svg', isCentralized: true);
static const changeNow =
ExchangeProviderDescription(title: 'ChangeNOW', raw: 1, image: 'assets/new-ui/trade_providers/changenow.svg', isCentralized: true);
static const morphToken =
ExchangeProviderDescription(title: 'MorphToken', raw: 2, image: 'assets/new-ui/trade_providers/morph.svg', isCentralized: true);
static const sideShift =
ExchangeProviderDescription(title: 'SideShift', raw: 3, image: 'assets/new-ui/trade_providers/sideshift.svg', isCentralized: true);
static const simpleSwap =
ExchangeProviderDescription(title: 'SimpleSwap', raw: 4, image: 'assets/new-ui/trade_providers/simpleswap.svg', isCentralized: true);
static const trocador =
ExchangeProviderDescription(title: 'Trocador', raw: 5, image: 'assets/new-ui/trade_providers/trocador.svg', isCentralized: true);
static const exolix =
ExchangeProviderDescription(title: 'Exolix', raw: 6, image: 'assets/new-ui/trade_providers/exolix.svg', isCentralized: true);
static const xmrto = ExchangeProviderDescription(
title: 'XMR.TO',
raw: 0,
image: 'assets/new-ui/trade_providers/xmrto.svg',
isCentralized: true);
static const changeNow = ExchangeProviderDescription(
title: 'ChangeNOW',
raw: 1,
image: 'assets/new-ui/trade_providers/changenow.svg',
isCentralized: true);
static const morphToken = ExchangeProviderDescription(
title: 'MorphToken',
raw: 2,
image: 'assets/new-ui/trade_providers/morph.svg',
isCentralized: true);
static const sideShift = ExchangeProviderDescription(
title: 'SideShift',
raw: 3,
image: 'assets/new-ui/trade_providers/sideshift.svg',
isCentralized: true);
static const simpleSwap = ExchangeProviderDescription(
title: 'SimpleSwap',
raw: 4,
image: 'assets/new-ui/trade_providers/simpleswap.svg',
isCentralized: true);
static const trocador = ExchangeProviderDescription(
title: 'Trocador',
raw: 5,
image: 'assets/new-ui/trade_providers/trocador.svg',
isCentralized: true);
static const exolix = ExchangeProviderDescription(
title: 'Exolix',
raw: 6,
image: 'assets/new-ui/trade_providers/exolix.svg',
isCentralized: true);
static const all =
ExchangeProviderDescription(title: 'All trades', raw: 7, image: '', isCentralized: true);
static const thorChain =
ExchangeProviderDescription(title: 'ThorChain', raw: 8, image: 'assets/new-ui/trade_providers/thorchain.svg', isCentralized: true);
static const swapTrade =
ExchangeProviderDescription(title: 'SwapTrade', raw: 9, image: 'assets/new-ui/trade_providers/swaptrade.svg', isCentralized: true);
static const letsExchange =
ExchangeProviderDescription(title: 'LetsExchange', raw: 10, image: 'assets/new-ui/trade_providers/letsexchange.svg', isCentralized: true);
static const stealthEx =
ExchangeProviderDescription(title: 'StealthEx', raw: 11, image: 'assets/new-ui/trade_providers/stealthex.svg', isCentralized: true);
static const chainflip =
ExchangeProviderDescription(title: 'Chainflip', raw: 12, image: 'assets/new-ui/trade_providers/chainflip.svg', isCentralized: false);
static const xoSwap =
ExchangeProviderDescription(title: 'XOSwap', raw: 13, image: 'assets/new-ui/trade_providers/xoswap.svg', isCentralized: true);
static const swapsXyz =
ExchangeProviderDescription(title: 'Swaps.XYZ', raw: 14, image: 'assets/new-ui/trade_providers/swaps_xyz.svg', isCentralized: true);
static const nearIntents =
ExchangeProviderDescription(title: 'Near Intents', raw: 15, image: 'assets/new-ui/trade_providers/near-intents.svg', isCentralized: false);
static const jupiter =
ExchangeProviderDescription(title: 'Jupiter', raw: 16, image: 'assets/new-ui/trade_providers/jupiter.svg', isCentralized: false);
static const thorChain = ExchangeProviderDescription(
title: 'ThorChain',
raw: 8,
image: 'assets/new-ui/trade_providers/thorchain.svg',
isCentralized: true);
static const swapTrade = ExchangeProviderDescription(
title: 'SwapTrade',
raw: 9,
image: 'assets/new-ui/trade_providers/swaptrade.svg',
isCentralized: true);
static const letsExchange = ExchangeProviderDescription(
title: 'LetsExchange',
raw: 10,
image: 'assets/new-ui/trade_providers/letsexchange.svg',
isCentralized: true);
static const stealthEx = ExchangeProviderDescription(
title: 'StealthEx',
raw: 11,
image: 'assets/new-ui/trade_providers/stealthex.svg',
isCentralized: true);
static const chainflip = ExchangeProviderDescription(
title: 'Chainflip',
raw: 12,
image: 'assets/new-ui/trade_providers/chainflip.svg',
isCentralized: false);
static const xoSwap = ExchangeProviderDescription(
title: 'XOSwap',
raw: 13,
image: 'assets/new-ui/trade_providers/xoswap.svg',
isCentralized: true);
static const swapsXyz = ExchangeProviderDescription(
title: 'Swaps.XYZ',
raw: 14,
image: 'assets/new-ui/trade_providers/swaps_xyz.svg',
isCentralized: true);
static const nearIntents = ExchangeProviderDescription(
title: 'Near Intents',
raw: 15,
image: 'assets/new-ui/trade_providers/near-intents.svg',
isCentralized: false);
static const jupiter = ExchangeProviderDescription(
title: 'Jupiter',
raw: 16,
image: 'assets/new-ui/trade_providers/jupiter.svg',
isCentralized: false);
static ExchangeProviderDescription deserialize({required int raw}) {
switch (raw) {
@@ -31,7 +31,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
CryptoCurrency.usdtArb,
CryptoCurrency.trx,
CryptoCurrency.usdttrc20,
];
];
static const _baseURL = 'chainflip-broker.io';
static const _assetsPath = '/assets';
@@ -57,8 +57,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
bool get supportsMemoOrDestinationTag => false;
@override
ExchangeProviderDescription get description =>
ExchangeProviderDescription.chainflip;
ExchangeProviderDescription get description => ExchangeProviderDescription.chainflip;
@override
Future<bool> checkIsAvailable() async => true;
@@ -68,25 +67,23 @@ class ChainflipExchangeProvider extends ExchangeProvider {
{required CryptoCurrency from,
required CryptoCurrency to,
required bool isFixedRateMode}) async {
try {
if(!_supported.contains(from) || !_supported.contains(to)) {
if (!_supported.contains(from) || !_supported.contains(to)) {
throw Exception('No rates found for $from to $to');
}
final assetId = _normalizeCurrency(from);
final assetId = _normalizeCurrency(from);
final assetsResponse = await _getAssets();
final assets = assetsResponse['assets'] as List<dynamic>;
final assetsResponse = await _getAssets();
final assets = assetsResponse['assets'] as List<dynamic>;
final minAmount = assets.firstWhere(
(asset) => asset['id'] == assetId,
orElse: () => null)?['minimalAmountNative'] ?? '0';
final minAmount = assets.firstWhere((asset) => asset['id'] == assetId,
orElse: () => null)?['minimalAmountNative'] ??
'0';
if (minAmount == '0') throw Exception('No rates found for $from to $to');
if (minAmount == '0') throw Exception('No rates found for $from to $to');
return Limits(min: _amountFromNative(minAmount.toString(), from));
return Limits(min: _amountFromNative(minAmount.toString(), from));
} catch (e) {
printV(e.toString());
throw Exception('Chainflip failed to fetch limits');
@@ -94,20 +91,18 @@ class ChainflipExchangeProvider extends ExchangeProvider {
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
// TODO: It seems this rate is getting cached, and re-used for different amounts, can we not do this?
try {
if (amount == 0) return 0.0;
if(!_supported.contains(from) || !_supported.contains(to)) return 0.0;
if (!_supported.contains(from) || !_supported.contains(to)) return 0.0;
final quoteParams = {
'apiKey': _affiliateKey,
@@ -119,8 +114,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
final quoteResponse = await _getSwapQuote(quoteParams);
final expectedAmountOut =
quoteResponse['egressAmountNative'] as String? ?? '0';
final expectedAmountOut = quoteResponse['egressAmountNative'] as String? ?? '0';
final rate = _amountFromNative(expectedAmountOut, to) / amount;
@@ -194,7 +188,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
'retryDurationInBlocks': '150'
};
if (quoteResponse.containsKey('numberOfChunks') && quoteResponse.containsKey('chunkIntervalBlocks')) {
if (quoteResponse.containsKey('numberOfChunks') &&
quoteResponse.containsKey('chunkIntervalBlocks')) {
swapParams.addAll({
'numberOfChunks': quoteResponse['numberOfChunks'].toString(),
'chunkIntervalBlocks': quoteResponse['chunkIntervalBlocks'].toString(),
@@ -203,7 +198,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
final swapResponse = await _openDepositChannel(swapParams);
final id = '${swapResponse['issuedBlock']}-${swapResponse['network'].toString()}-${swapResponse['channelId']}';
final id =
'${swapResponse['issuedBlock']}-${swapResponse['network'].toString()}-${swapResponse['channelId']}';
ExchangeProviderLogger.logSuccess(
provider: description,
@@ -280,8 +276,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
final statusResponse = await _getStatus(statusParams);
if (statusResponse == null)
throw Exception('Trade not found for id: $id');
if (statusResponse == null) throw Exception('Trade not found for id: $id');
final status = statusResponse['status'];
final currentState = _determineState(status['state'].toString());
@@ -294,7 +289,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
final from = status['sourceAsset'].toString();
final to = status['destinationAsset'].toString();
final newTrade = Trade(
id: id,
from: _toCurrency(from),
@@ -304,8 +299,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
receiveAmount: amount,
state: currentState,
payoutAddress: status['destinationAddress'].toString(),
outputTransaction:
status['swapEgress']?['transactionReference']?.toString(),
outputTransaction: status['swapEgress']?['transactionReference']?.toString(),
isRefund: isRefund,
);
@@ -331,7 +325,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
return '$title.$tag';
}
String _normalizeNetworkName (String name) {
String _normalizeNetworkName(String name) {
final networkName = switch (name) {
'BITCOIN' => 'Bitcoin',
'ETHEREUM' => 'Ethereum',
@@ -344,7 +338,6 @@ class ChainflipExchangeProvider extends ExchangeProvider {
return networkName;
}
CryptoCurrency? _toCurrency(String name) {
final currency = switch (name) {
'btc.btc' => CryptoCurrency.btc,
@@ -372,8 +365,7 @@ class ChainflipExchangeProvider extends ExchangeProvider {
double _amountFromNative(String amount, CryptoCurrency currency) =>
double.parse(amount) / pow(10, currency.decimals);
Future<Map<String, dynamic>> _getAssets() async =>
_getRequest(_assetsPath, {});
Future<Map<String, dynamic>> _getAssets() async => _getRequest(_assetsPath, {});
Future<Map<String, dynamic>> _openDepositChannel(Map<String, String> params) async =>
_getRequest(_swapPath, params);
@@ -384,7 +376,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
final response = await ProxyWrapper().get(clearnetUri: uri);
if ((response.statusCode != 200) || (response.body.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
throw Exception(
'Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
}
return json.decode(response.body) as Map<String, dynamic>;
@@ -396,12 +389,13 @@ class ChainflipExchangeProvider extends ExchangeProvider {
final response = await ProxyWrapper().get(clearnetUri: uri);
if ((response.statusCode != 200) || (response.body.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
throw Exception(
'Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
}
final List<dynamic> jsonList = json.decode(response.body) as List<dynamic>;
final List<Map<String, dynamic>> quotes =
jsonList.map((e) => e as Map<String, dynamic>).toList();
jsonList.map((e) => e as Map<String, dynamic>).toList();
Map<String, dynamic> highestQuote = quotes.reduce((current, next) {
double currentAmount = current['egressAmount'] as double;
@@ -421,7 +415,8 @@ class ChainflipExchangeProvider extends ExchangeProvider {
if (response.statusCode == 404) return null;
if ((response.statusCode != 200) || (response.body.contains('error'))) {
throw Exception('Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
throw Exception(
'Unexpected response: ${response.statusCode} / ${uri.toString()} / ${response.body}');
}
return json.decode(response.body) as Map<String, dynamic>;
@@ -69,8 +69,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
for (int i = 0; i < 2; i++) {
final uri = Uri.https(apiBaseUrl, ratePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 200) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final minAmount = responseJSON['minAmount'];
@@ -92,13 +91,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) return 0.0;
@@ -118,12 +116,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
final uri = Uri.https(apiBaseUrl, ratePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode != 200) {
final message = responseJSON['message'] as String?;
ExchangeProviderLogger.logError(
provider: description,
function: 'fetchRate',
@@ -139,7 +137,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
'url': uri.toString(),
},
);
throw Exception(message);
}
@@ -194,12 +192,12 @@ class ExolixExchangeProvider extends ExchangeProvider {
final headers = {'Content-Type': 'application/json'};
final body = {
'coinFrom': _normalizeCurrency(_overrideFromCryptoCurrency(request.fromCurrency)),
'coinTo': _normalizeCurrency(_overrideToCryptoCurrency(request.toCurrency, request.toAddress)),
'coinTo':
_normalizeCurrency(_overrideToCryptoCurrency(request.toCurrency, request.toAddress)),
'networkFrom': _networkFor(request.fromCurrency),
'networkTo': _networkFor(request.toCurrency),
'withdrawalAddress': await _normalizeAddress(request.toAddress),
if (request.toAddressExtraId.isNotEmpty)
'withdrawalExtraId': request.toAddressExtraId,
if (request.toAddressExtraId.isNotEmpty) 'withdrawalExtraId': request.toAddressExtraId,
'refundAddress': await _normalizeAddress(request.refundAddress),
'rateType': _getRateType(isFixedRateMode),
'apiToken': apiKey,
@@ -221,7 +219,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final errors = responseJSON['error'] as Map<String, String>;
final errorMessage = errors.values.join(', ');
ExchangeProviderLogger.logError(
provider: description,
function: 'createTrade',
@@ -240,7 +238,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
'url': uri.toString(),
},
);
throw Exception(errorMessage);
}
@@ -326,7 +324,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
final findTradeByIdPath = '$transactionsPath/$id';
final uri = Uri.https(apiBaseUrl, findTradeByIdPath);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 404) throw TradeNotFoundException(id, provider: description);
if (response.statusCode == 400) {
@@ -346,7 +344,8 @@ class ExolixExchangeProvider extends ExchangeProvider {
final coinFrom = responseJSON['coinFrom']['coinCode'] as String;
final coinFromNetwork = responseJSON['coinFrom']['network'] as String?;
final _normalizedFromNetwork = _normalizeNetworkType(coinFromNetwork ?? '');
final fromTag = coinFrom.toUpperCase() == _normalizedFromNetwork.toUpperCase() ? null : coinFromNetwork;
final fromTag =
coinFrom.toUpperCase() == _normalizedFromNetwork.toUpperCase() ? null : coinFromNetwork;
final from = CryptoCurrency.safeParseCurrencyFromString(coinFrom, tag: fromTag);
// Parsing 'to' currency
@@ -438,7 +437,7 @@ class ExolixExchangeProvider extends ExchangeProvider {
switch (tag) {
case 'POLY':
return 'Polygon';
case 'ARB':
case 'ARB':
return 'Arbitrum';
default:
return tag;
@@ -446,17 +445,14 @@ class ExolixExchangeProvider extends ExchangeProvider {
}
Future<String> _normalizeAddress(String address) async {
if (address.startsWith('bitcoincash:'))
return address.replaceFirst('bitcoincash:', '');
if (address.startsWith('bitcoincash:')) return address.replaceFirst('bitcoincash:', '');
// Lightning addresses
if(address.contains("@"))
return await getBolt11FromLightingAddress(address) ?? address;
if (address.contains("@")) return await getBolt11FromLightingAddress(address) ?? address;
return address;
}
static double? _toDouble(dynamic value) {
if (value is int) {
return value.toDouble();
@@ -226,8 +226,7 @@ class JupiterExchangeProvider extends ExchangeProvider {
}) async {
try {
// must support both
if (!_isSolanaCurrency(request.fromCurrency) ||
!_isSolanaCurrency(request.toCurrency)) {
if (!_isSolanaCurrency(request.fromCurrency) || !_isSolanaCurrency(request.toCurrency)) {
throw 'not supported currencies';
}
@@ -92,8 +92,7 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
bool get supportsMemoOrDestinationTag => false;
@override
ExchangeProviderDescription get description =>
ExchangeProviderDescription.nearIntents;
ExchangeProviderDescription get description => ExchangeProviderDescription.nearIntents;
@override
Future<bool> checkIsAvailable() async => true;
@@ -132,8 +131,8 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
throw Exception('fetchRate: Unsupported currency pair');
}
final formattedAmount = AmountConverter.toBaseUnits(amount.toString(),
isFixedRateMode ? destinationToken.decimals : originToken.decimals);
final formattedAmount = AmountConverter.toBaseUnits(
amount.toString(), isFixedRateMode ? destinationToken.decimals : originToken.decimals);
final dummyAddrFrom = getNearDummyAddress(from);
final dummyAddrTo = getNearDummyAddress(to);
@@ -156,10 +155,8 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
}
final q = quote['quote'] as Map<String, dynamic>;
final amountIn =
double.tryParse(q['amountInFormatted']?.toString() ?? '0') ?? 0.0;
final amountOut =
double.tryParse(q['amountOutFormatted']?.toString() ?? '0') ?? 0.0;
final amountIn = double.tryParse(q['amountInFormatted']?.toString() ?? '0') ?? 0.0;
final amountOut = double.tryParse(q['amountOutFormatted']?.toString() ?? '0') ?? 0.0;
if (amountIn == 0) return 0.0;
@@ -214,24 +211,21 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
try {
final tokens = await _geSupportedTokens();
final originToken = currencyToNearAssetId(request.fromCurrency, tokens);
final destinationToken =
currencyToNearAssetId(request.toCurrency, tokens);
final destinationToken = currencyToNearAssetId(request.toCurrency, tokens);
if (originToken == null || destinationToken == null) {
throw Exception('Unsupported currency pair');
}
final rawAmountStr =
isFixedRateMode ? request.toAmount : request.fromAmount;
final rawAmountStr = isFixedRateMode ? request.toAmount : request.fromAmount;
final baseAmount = AmountConverter.toBaseUnits(
rawAmountStr,
isFixedRateMode
? request.toCurrency.decimals
: request.fromCurrency.decimals,
isFixedRateMode ? request.toCurrency.decimals : request.fromCurrency.decimals,
);
final depositMode = _memoRequiredCurrencies.contains(request.fromCurrency) ? "MEMO" : "SIMPLE";
final depositMode =
_memoRequiredCurrencies.contains(request.fromCurrency) ? "MEMO" : "SIMPLE";
final quote = await getSwapQuote(
dry: false,
@@ -271,11 +265,9 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
throw Exception('Failed to parse to currency from assetId: $toAssetId');
}
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency.$1,
tag: fromCurrency.$2);
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency.$1,
tag: toCurrency.$2);
final from =
CryptoCurrency.safeParseCurrencyFromString(fromCurrency.$1, tag: fromCurrency.$2);
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency.$1, tag: toCurrency.$2);
final trade = Trade(
id: depositAddress,
@@ -345,8 +337,7 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
final param = {'depositAddress': id};
final uri = Uri.https(_baseUrl, '$_versionPath$_statusPath', param);
final response =
await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
if (response.statusCode != 200) {
throw Exception(
@@ -358,16 +349,14 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
final statusRaw = (data['status'] as String?) ?? 'UNKNOWN';
final quoteResponse = data['quoteResponse'] as Map<String, dynamic>? ?? {};
final quoteRequest =
quoteResponse['quoteRequest'] as Map<String, dynamic>? ?? {};
final quoteRequest = quoteResponse['quoteRequest'] as Map<String, dynamic>? ?? {};
final refundTo = quoteRequest['refundTo'] as String? ?? '';
final recipient = quoteRequest['recipient'] as String? ?? '';
// Parsing 'from' currency
final originAssetId = quoteRequest['originAsset'] as String? ?? '';
final from =
_nearAssetIdToCurrency(originAssetId, await _geSupportedTokens());
final from = _nearAssetIdToCurrency(originAssetId, await _geSupportedTokens());
CryptoCurrency? coinFrom;
CryptoCurrency? coinTo;
@@ -377,11 +366,9 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
}
// Parsing 'to' currency
final destinationAssetId =
quoteRequest['destinationAsset'] as String? ?? '';
final destinationAssetId = quoteRequest['destinationAsset'] as String? ?? '';
final to =
_nearAssetIdToCurrency(destinationAssetId, await _geSupportedTokens());
final to = _nearAssetIdToCurrency(destinationAssetId, await _geSupportedTokens());
if (to != null) {
coinTo = CryptoCurrency.safeParseCurrencyFromString(to.$1, tag: to.$2);
@@ -393,16 +380,13 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
final depositAddress = quote['depositAddress'] as String?;
final depositMemo = quote['depositMemo'] as String?;
final depositAmount = swap['amountInFormatted']?.toString() ??
quote['amountInFormatted']?.toString() ??
'0';
final depositAmount =
swap['amountInFormatted']?.toString() ?? quote['amountInFormatted']?.toString() ?? '0';
final receiveAmount = swap['amountOutFormatted']?.toString() ??
quote['amountOutFormatted']?.toString();
final receiveAmount =
swap['amountOutFormatted']?.toString() ?? quote['amountOutFormatted']?.toString();
final originTxHash = (swap['originChainTxHashes'] as List?)
?.firstOrNull?['hash']
?.toString();
final originTxHash = (swap['originChainTxHashes'] as List?)?.firstOrNull?['hash']?.toString();
return Trade(
id: id,
@@ -487,8 +471,7 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
"deadline": _isoUtcDeadline,
if (connectedWallets != null) "connectedWallets": connectedWallets,
if (sessionId != null) "sessionId": sessionId,
if (virtualChainRecipient != null)
"virtualChainRecipient": virtualChainRecipient,
if (virtualChainRecipient != null) "virtualChainRecipient": virtualChainRecipient,
if (virtualChainRefundRecipient != null)
"virtualChainRefundRecipient": virtualChainRefundRecipient,
if (customRecipientMsg != null) "customRecipientMsg": customRecipientMsg,
@@ -568,24 +551,20 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
return token;
}
(String, String?)? _nearAssetIdToCurrency(
String assetId, List<Token> supported) {
(String, String?)? _nearAssetIdToCurrency(String assetId, List<Token> supported) {
if (supported.isEmpty) return null;
final token = supported.firstWhereOrNull((t) => t.assetId == assetId);
if (token == null) return null;
final title = token.symbol.toUpperCase()
.replaceAll(RegExp(r'\s*\([^)]*\)'), '');
final title = token.symbol.toUpperCase().replaceAll(RegExp(r'\s*\([^)]*\)'), '');
final normalizedNetwork = _normalizeNearBlockchainToTag(token.blockchain);
final isNativeAsset = assetId.contains(':native:coin');
final tag = isNativeAsset || normalizedNetwork == title
? null
: normalizedNetwork;
final tag = isNativeAsset || normalizedNetwork == title ? null : normalizedNetwork;
return (title, tag);
}
@@ -44,7 +44,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
const url = apiBaseUrl + permissionPath;
final uri = Uri.parse(url);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final error = responseJSON['error']['message'] as String;
@@ -74,7 +74,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final uri = Uri.parse(url);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -103,13 +102,12 @@ class SideShiftExchangeProvider extends ExchangeProvider {
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) return 0.0;
@@ -123,7 +121,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final uri = Uri.parse(url);
final response = await ProxyWrapper().get(clearnetUri: uri);
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode == 500) {
@@ -240,7 +238,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
headers: headers,
body: json.encode(body),
);
if (response.statusCode != 201) {
if (response.statusCode == 400) {
@@ -346,7 +343,7 @@ class SideShiftExchangeProvider extends ExchangeProvider {
final url = apiBaseUrl + orderPath + '/' + id;
final uri = Uri.parse(url);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 404) {
throw TradeNotFoundException(id, provider: description);
}
@@ -415,7 +412,6 @@ class SideShiftExchangeProvider extends ExchangeProvider {
headers: headers,
body: json.encode(body),
);
if (response.statusCode != 201) {
if (response.statusCode == 400) {
@@ -17,7 +17,6 @@ import 'package:cake_wallet/utils/exchange_provider_logger.dart';
class SimpleSwapExchangeProvider extends ExchangeProvider {
SimpleSwapExchangeProvider();
static final apiKey =
DeviceInfo.instance.isMobile ? secrets.simpleSwapApiKey : secrets.simpleSwapApiKeyDesktop;
static const apiAuthority = 'api.simpleswap.io';
@@ -63,7 +62,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
final uri = Uri.https(apiAuthority, rangePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 500) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -84,13 +82,12 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) return 0.0;
@@ -103,7 +100,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(apiAuthority, getEstimatePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.body == "null") {
ExchangeProviderLogger.logError(
@@ -123,7 +119,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
);
return 0.00;
}
final data = json.decode(response.body) as String;
final rate = double.parse(data) / amount;
@@ -190,7 +186,6 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
headers: headers,
body: json.encode(body),
);
if (response.statusCode != 200 && response.statusCode != 201) {
if (response.statusCode == 400) {
@@ -299,8 +294,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
final params = {'api_key': apiKey, 'id': id};
final uri = Uri.https(apiAuthority, getExchangePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 404) {
throw TradeNotFoundException(id, provider: description);
}
@@ -325,8 +319,7 @@ class SimpleSwapExchangeProvider extends ExchangeProvider {
final status = responseJSON['status'] as String;
final payoutAddress = responseJSON['address_to'] as String;
final fromParsed =
CryptoCurrency.safeParseCurrencyFromString(fromCurrency);
final fromParsed = CryptoCurrency.safeParseCurrencyFromString(fromCurrency);
final toParsed = CryptoCurrency.safeParseCurrencyFromString(toCurrency);
return Trade(
id: id,
@@ -19,7 +19,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
static final List<CryptoCurrency> _notSupportedAsSourceToken = [
CryptoCurrency.sol,
...CryptoCurrency.all.where(
(c) => (c.tag ?? '').toUpperCase() == 'SOL' || c.tag == CryptoCurrency.bnb.tag,
(c) => (c.tag ?? '').toUpperCase() == 'SOL' || c.tag == CryptoCurrency.bnb.tag,
),
];
@@ -58,8 +58,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
bool get supportsMemoOrDestinationTag => false;
@override
ExchangeProviderDescription get description =>
ExchangeProviderDescription.swapsXyz;
ExchangeProviderDescription get description => ExchangeProviderDescription.swapsXyz;
@override
Future<bool> checkIsAvailable() async => true;
@@ -101,8 +100,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final body = json.decode(res.body) as Map<String, dynamic>;
final paths =
(body['paths'] as List? ?? const []).cast<Map<String, dynamic>>();
final paths = (body['paths'] as List? ?? const []).cast<Map<String, dynamic>>();
if (paths.isEmpty) {
throw Exception('No paths for ${fromToUse.title} -> ${toToUse.title}');
}
@@ -121,18 +119,14 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
);
}
final supportsExactAmountIn =
path['supportsExactAmountIn'] as bool? ?? false;
final supportsExactAmountOut =
path['supportsExactAmountOut'] as bool? ?? false;
final supportsExactAmountIn = path['supportsExactAmountIn'] as bool? ?? false;
final supportsExactAmountOut = path['supportsExactAmountOut'] as bool? ?? false;
if (isFixedRateMode && !supportsExactAmountOut) {
throw Exception(
'This route does not support fixed receive (exact-amount-out)');
throw Exception('This route does not support fixed receive (exact-amount-out)');
}
if (!isFixedRateMode && !supportsExactAmountIn) {
throw Exception(
'This route does not support exact send (exact-amount-in)');
throw Exception('This route does not support exact send (exact-amount-in)');
}
Map<String, dynamic>? useLimits;
@@ -192,8 +186,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final res = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
if (res.statusCode != 200) return null;
final body = json.decode(res.body) as Map<String, dynamic>;
final paths =
(body['paths'] as List?)?.cast<Map<String, dynamic>>() ?? const [];
final paths = (body['paths'] as List?)?.cast<Map<String, dynamic>>() ?? const [];
if (paths.isEmpty) return null;
final p = paths.first;
return _PathInfo(
@@ -210,23 +203,18 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if(_notSupportedAsSourceToken.contains(from) || _notSupportedAsSourceToken.contains(to)) {
printV(
'fetchRate: source token ${from.title} is not supported as source token');
if (_notSupportedAsSourceToken.contains(from) || _notSupportedAsSourceToken.contains(to)) {
printV('fetchRate: source token ${from.title} is not supported as source token');
return 0.0;
}
final chains = await _geSupportedChain();
if (chains.isEmpty) return 0.0;
final srcChain = _findChainByCurrency(from, chains);
final dstChain = _findChainByCurrency(to, chains);
await _ensureTokensCached(
fromChain: srcChain, toChain: dstChain, from: from, to: to);
await _ensureTokensCached(fromChain: srcChain, toChain: dstChain, from: from, to: to);
final srcToken = _getTokenAddress(currency: from, chain: srcChain);
final dstToken = _getTokenAddress(currency: to, chain: dstChain);
@@ -252,8 +240,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
);
final params = {
'swapDirection':
isReceiveAmount ? 'exact-amount-out' : 'exact-amount-in',
'swapDirection': isReceiveAmount ? 'exact-amount-out' : 'exact-amount-in',
'srcToken': srcToken,
'dstToken': dstToken,
'srcChainId': '${srcChain.chainId}',
@@ -262,8 +249,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
};
final uri = Uri.https(_baseUrl, _getQuotePaths, params);
final response =
await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
if (response.statusCode != 200) {
printV('fetchRate failed: ${response.body}');
@@ -289,8 +275,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final sender = request.refundAddress.trim();
final recipient = request.toAddress.trim();
if (sender.isEmpty || recipient.isEmpty) {
throw Exception(
'Sender (refundAddress) or recipient (toAddress) is empty');
throw Exception('Sender (refundAddress) or recipient (toAddress) is empty');
}
final chains = await _geSupportedChain();
@@ -305,10 +290,8 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
to: request.toCurrency,
);
final srcToken =
_getTokenAddress(currency: request.fromCurrency, chain: srcChain);
final dstToken =
_getTokenAddress(currency: request.toCurrency, chain: dstChain);
final srcToken = _getTokenAddress(currency: request.fromCurrency, chain: srcChain);
final dstToken = _getTokenAddress(currency: request.toCurrency, chain: dstChain);
final amountStr = isFixedRateMode ? request.toAmount : request.fromAmount;
final rawAmount = double.tryParse(amountStr) ?? 0.0;
@@ -316,9 +299,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final formattedAmount = AmountConverter.toBaseUnits(
amountStr,
isFixedRateMode
? request.toCurrency.decimals
: request.fromCurrency.decimals,
isFixedRateMode ? request.toCurrency.decimals : request.fromCurrency.decimals,
);
final params = {
@@ -329,8 +310,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
'dstChainId': '${dstChain.chainId}',
'dstToken': dstToken,
'slippage': '300',
'swapDirection':
isFixedRateMode ? 'exact-amount-out' : 'exact-amount-in',
'swapDirection': isFixedRateMode ? 'exact-amount-out' : 'exact-amount-in',
'amount': formattedAmount,
'recipient': recipient,
};
@@ -375,18 +355,16 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final amtIn = (data['amountIn'] as Map?) ?? const {};
final amtInMax = (data['amountInMax'] as Map?) ?? const {};
final srcTokenAddr = amtIn['address']?.toString();
final srcTokenDecs =
(amtIn['decimals'] as num?)?.toInt() ?? request.fromCurrency.decimals;
final requiresTokenApproval =
data['requiresTokenApproval'] as bool? ?? false;
final srcTokenDecs = (amtIn['decimals'] as num?)?.toInt() ?? request.fromCurrency.decimals;
final requiresTokenApproval = data['requiresTokenApproval'] as bool? ?? false;
final reqAmountStr =
(amtInMax['amount'] ?? amtIn['amount'])?.toString() ?? '0';
final reqAmountStr = (amtInMax['amount'] ?? amtIn['amount'])?.toString() ?? '0';
final reqAmountRaw = reqAmountStr.replaceAll('n', '');
final needToRegisterInSwapXyz =
vmId == 'alt-vm' || bridgeIds.contains('alt-vm')
|| chainId == 'solana' || bridgeIds.contains('solana');
final needToRegisterInSwapXyz = vmId == 'alt-vm' ||
bridgeIds.contains('alt-vm') ||
chainId == 'solana' ||
bridgeIds.contains('solana');
final trade = Trade(
id: txId,
@@ -452,8 +430,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final List<dynamic> body = json.decode(res.body) as List<dynamic>;
if (body.isEmpty) return false;
final isSuccess =
(body[0] as Map<String, dynamic>)['success'] as bool? ?? false;
final isSuccess = (body[0] as Map<String, dynamic>)['success'] as bool? ?? false;
return isSuccess;
} catch (e) {
@@ -482,8 +459,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final error = data['error'] as Map<String, dynamic>?;
if (error != null) {
final code = error['code']?.toString() ?? 'unknown';
throw Exception(
'SwapXyzExchangeProvider findTradeById error: ($id) $code');
throw Exception('SwapXyzExchangeProvider findTradeById error: ($id) $code');
}
}
@@ -499,10 +475,8 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final payoutAddress = dstTransaction?['toAddress']?.toString();
final srcPaymentToken =
(srcTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
final dstPaymentToken =
(dstTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
final srcPaymentToken = (srcTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
final dstPaymentToken = (dstTransaction?['paymentToken'] as Map?)?.cast<String, dynamic>();
final fromSymbol = (srcPaymentToken?['symbol'] as String?) ?? '';
final toSymbol = (dstPaymentToken?['symbol'] as String?) ?? '';
@@ -523,8 +497,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
String? receiveAmount;
if (dstAmountRaw != null) {
final dstAmountMinimal = _stripN(dstAmountRaw);
receiveAmount =
AmountConverter.fromBaseUnits(dstAmountMinimal, dstDecimals);
receiveAmount = AmountConverter.fromBaseUnits(dstAmountMinimal, dstDecimals);
}
final srcAmountMinimal = _stripN(srcAmountRaw);
@@ -537,8 +510,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
final timestamp = srcTs ?? dstTs;
final createdAt = timestamp != null
? DateTime.fromMillisecondsSinceEpoch(timestamp * 1000, isUtc: true)
.toLocal()
? DateTime.fromMillisecondsSinceEpoch(timestamp * 1000, isUtc: true).toLocal()
: null;
return Trade(
@@ -581,8 +553,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
if (_supportedChainList.isNotEmpty) return _supportedChainList;
try {
final uri = Uri.https(_baseUrl, _getChainList);
final response =
await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
if (response.statusCode != 200) return [];
final data = json.decode(response.body) as List<dynamic>;
@@ -677,8 +648,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
// Case 1: String "all" -> cache empty list to indicate all tokens supported
if (tokensField is String) {
if (tokensField.toLowerCase() == 'all') {
_tokensCache[pathChainId] =
_tokensCache[pathChainId] ?? <TokenPathInfo>[];
_tokensCache[pathChainId] = _tokensCache[pathChainId] ?? <TokenPathInfo>[];
}
continue;
}
@@ -705,9 +675,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
// Merge by symbol, prefer entries that have a non-empty address/decimals
void _mergeCache(int chainId, List<TokenPathInfo> incoming) {
final existing = _tokensCache[chainId] ?? const <TokenPathInfo>[];
final bySymbol = <String, TokenPathInfo>{
for (final t in existing) t.symbol: t
};
final bySymbol = <String, TokenPathInfo>{for (final t in existing) t.symbol: t};
for (final t in incoming) {
final cur = bySymbol[t.symbol];
@@ -758,8 +726,7 @@ class SwapsXyzExchangeProvider extends ExchangeProvider {
return symbol;
}
Map<String, dynamic>? findTokenBySymbol(
{required String title, required List<dynamic> tokens}) {
Map<String, dynamic>? findTokenBySymbol({required String title, required List<dynamic> tokens}) {
final reqSymbol = title.toUpperCase();
for (final token in tokens) {
final map = token as Map<String, dynamic>;
@@ -69,8 +69,8 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
final normalized = _normalizeCurrency(from);
final coin = coinsInfo.cast<Map<String, dynamic>>().firstWhere(
(c) => (c['id']?.toString().toUpperCase() ?? '') == normalized,
orElse: () => <String, dynamic>{},
);
orElse: () => <String, dynamic>{},
);
if (coin.isEmpty) {
// Currency not supported by SwapTrade (e.g. USDC, DOGE).
@@ -88,19 +88,18 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) return 0.0;
if (isFixedRateMode && !supportsFixedRate) {
return 0.0;
}
if(from == CryptoCurrency.btcln || to == CryptoCurrency.btcln) return 0;
if (from == CryptoCurrency.btcln || to == CryptoCurrency.btcln) return 0;
final params = <String, dynamic>{};
final body = <String, String>{
@@ -116,7 +115,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
body: json.encode(body),
headers: _headers,
);
final responseBody = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode != 200) {
@@ -140,7 +139,11 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
final data = responseBody['data'] as Map<String, dynamic>;
double rate = double.parse(data['price'].toString());
final calculatedRate = rate > 0 ? isFixedRateMode ? amount / rate : rate / amount : 0.0;
final calculatedRate = rate > 0
? isFixedRateMode
? amount / rate
: rate / amount
: 0.0;
ExchangeProviderLogger.logSuccess(
provider: description,
@@ -208,7 +211,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
body: json.encode(body),
headers: _headers,
);
final responseBody = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode == 400 || responseBody["success"] == false) {
@@ -235,7 +238,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
'url': uri.toString(),
},
);
throw TradeNotCreatedException(description, description: error);
}
@@ -337,7 +340,7 @@ class SwapTradeExchangeProvider extends ExchangeProvider {
body: json.encode(body),
headers: _headers,
);
final responseBody = json.decode(response.body) as Map<String, dynamic>;
if (response.statusCode == 400 || responseBody["success"] == false) {
@@ -46,13 +46,12 @@ class ThorChainExchangeProvider extends ExchangeProvider {
Future<bool> checkIsAvailable() async => true;
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
if (amount == 0) return 0.0;
@@ -132,8 +131,6 @@ class ThorChainExchangeProvider extends ExchangeProvider {
required bool isFixedRateMode,
required bool isSendAll,
}) async {
final formattedFromAmount = double.parse(request.fromAmount);
final params = {
@@ -143,8 +140,9 @@ class ThorChainExchangeProvider extends ExchangeProvider {
'destination': _normalizeAddress(request.toAddress),
'affiliate': _affiliateName,
'affiliate_bps': _affiliateBps,
'refund_address':
isRefundAddressSupported.contains(request.fromCurrency) ? _normalizeAddress(request.refundAddress) : '',
'refund_address': isRefundAddressSupported.contains(request.fromCurrency)
? _normalizeAddress(request.refundAddress)
: '',
};
final responseJSON = await _getSwapQuote(params);
@@ -203,7 +201,6 @@ class ThorChainExchangeProvider extends ExchangeProvider {
final formattedId = id.startsWith('0x') ? id.substring(2) : id;
final uri = Uri.https(_baseNodeURL, '$_txInfoPath$formattedId');
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode == 404) {
throw Exception('Trade not found for id: $formattedId');
@@ -235,7 +232,8 @@ class ThorChainExchangeProvider extends ExchangeProvider {
: '';
final formattedToChain = CryptoCurrency.safeParseCurrencyFromString(toChain);
final toAssetWithChain = CryptoCurrency.safeParseCurrencyFromString(toAsset, walletCurrency: formattedToChain);
final toAssetWithChain =
CryptoCurrency.safeParseCurrencyFromString(toAsset, walletCurrency: formattedToChain);
final plannedOutTxs = responseJSON['planned_out_txs'] as List<dynamic>?;
final isRefund = plannedOutTxs?.any((tx) => tx['refund'] == true) ?? false;
@@ -257,39 +255,39 @@ class ThorChainExchangeProvider extends ExchangeProvider {
static Future<Map<String, String>?>? lookupAddressByName(String name) async {
final uri = Uri.https(_baseURL, '$_nameLookUpPath$name');
try {
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode != 200) {
return null;
}
final body = json.decode(response.body) as Map<String, dynamic>;
final entries = body['entries'] as List<dynamic>?;
if (entries == null || entries.isEmpty) {
return null;
}
Map<String, String> chainToAddressMap = {};
for (final entry in entries) {
final chain = entry['chain'] as String;
final address = entry['address'] as String;
chainToAddressMap[chain] = address;
}
return chainToAddressMap;
} catch (e) {
printV(e.toString());
return null;
}
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode != 200) {
return null;
}
final body = json.decode(response.body) as Map<String, dynamic>;
final entries = body['entries'] as List<dynamic>?;
if (entries == null || entries.isEmpty) {
return null;
}
Map<String, String> chainToAddressMap = {};
for (final entry in entries) {
final chain = entry['chain'] as String;
final address = entry['address'] as String;
chainToAddressMap[chain] = address;
}
return chainToAddressMap;
} catch (e) {
printV(e.toString());
return null;
}
}
Future<Map<String, dynamic>> _getSwapQuote(Map<String, String> params) async {
Uri uri = Uri.https(_baseNodeURL, _quotePath, params);
final response = await ProxyWrapper().get(clearnetUri: uri);
if (response.statusCode != 200) {
ExchangeProviderLogger.logError(
provider: description,
@@ -12,6 +12,7 @@ import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/utils/proxy_wrapper.dart';
import 'package:cake_wallet/utils/exchange_provider_logger.dart';
class XOSwapExchangeProvider extends ExchangeProvider {
XOSwapExchangeProvider() {
_addAppVersionHeader();
@@ -54,7 +55,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
'BASE': 'basemainnet',
'ARB': 'arbitrum',
};
static const supportedTags = [
'POL',
'ETH',
@@ -76,18 +77,21 @@ class XOSwapExchangeProvider extends ExchangeProvider {
'ARB',
];
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');
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';
@@ -116,7 +120,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
{'networks': normalizedNetwork, 'query': currency.title});
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
if (response.statusCode != 200) {
throw Exception('Failed to fetch assets for ${currency.title} on ${currency.tag}');
}
@@ -125,7 +129,6 @@ class XOSwapExchangeProvider extends ExchangeProvider {
if (decoded is! List) throw const FormatException('Unexpected response format');
final assets = decoded.map((e) => Map<String, dynamic>.from(e as Map)).toList();
final asset = assets.firstWhere(
(asset) => removeNonAlphanumeric((asset['symbol'] ?? '').toString()) == currency.title,
orElse: () => const {},
@@ -138,7 +141,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
}
}
String removeNonAlphanumeric(String str) => str.toUpperCase().replaceAll(RegExp(r'[^A-Z0-9]'), '');
String removeNonAlphanumeric(String str) =>
str.toUpperCase().replaceAll(RegExp(r'[^A-Z0-9]'), '');
Future<List<dynamic>> getRatesForPair({
required CryptoCurrency from,
@@ -169,8 +173,8 @@ class XOSwapExchangeProvider extends ExchangeProvider {
final rates = await getRatesForPair(from: from, to: to);
if (rates.isEmpty) throw Exception('No rates found for $from to $to');
double minLimit = double.infinity;
double maxLimit = 0;
double minLimit = double.infinity;
double maxLimit = 0;
for (var rate in rates) {
final double currentMin = double.parse(rate['min']['value'].toString());
@@ -186,13 +190,12 @@ class XOSwapExchangeProvider extends ExchangeProvider {
}
@override
Future<double> fetchRate({
required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount
}) async {
Future<double> fetchRate(
{required CryptoCurrency from,
required CryptoCurrency to,
required double amount,
required bool isFixedRateMode,
required bool isReceiveAmount}) async {
try {
final rates = await getRatesForPair(from: from, to: to);
if (rates.isEmpty) {
@@ -337,7 +340,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
final error = responseJSON['error'] ?? 'Unknown error';
final message = responseJSON['message'] ?? '';
ExchangeProviderLogger.logError(
provider: description,
function: 'createTrade',
@@ -356,7 +359,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
'url': uri.toString(),
},
);
throw Exception('$error\n$message');
}
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
@@ -456,7 +459,7 @@ class XOSwapExchangeProvider extends ExchangeProvider {
try {
final uri = Uri.https(_apiAuthority, '$_apiPath$_orders/$id');
final response = await ProxyWrapper().get(clearnetUri: uri, headers: _headers);
if (response.statusCode != 200) {
final responseJSON = json.decode(response.body) as Map<String, dynamic>;
if (responseJSON.containsKey('code') && responseJSON['code'] == 'NOT_FOUND') {
@@ -507,10 +510,10 @@ class XOSwapExchangeProvider extends ExchangeProvider {
toAssetTag = 'ETH';
toAssetBase = 'BASE';
}
final fromCurrency = CryptoCurrency.safeParseCurrencyFromString(fromAssetBase,tag: fromAssetTag);
final toCurrency = CryptoCurrency.safeParseCurrencyFromString(toAssetBase,tag: toAssetTag);
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>;
@@ -553,9 +556,6 @@ 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;
+3 -7
View File
@@ -48,12 +48,10 @@ class TradeLegacyAdapter extends TypeAdapter<TradeLegacy> {
chainId: fields[34] as int?,
fee: fields[35] as double?,
)
..providerRaw =
fields[1] == null ? 0 : fields[1] as int
..providerRaw = fields[1] == null ? 0 : fields[1] as int
..fromRaw = (fields[2] as int?) ?? -1
..toRaw = (fields[3] as int?) ?? -1
..stateRaw =
fields[4] == null ? '' : fields[4] as String;
..stateRaw = fields[4] == null ? '' : fields[4] as String;
}
@override
@@ -140,7 +138,5 @@ class TradeLegacyAdapter extends TypeAdapter<TradeLegacy> {
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is TradeLegacyAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
other is TradeLegacyAdapter && runtimeType == other.runtimeType && typeId == other.typeId;
}