Skip to content

Commit 0cf8043

Browse files
authored
refactor send validation and near token parsing (#3351)
* refactor send validation and near token parsing * fix exchange send validation[skip ci]
1 parent 49f5a24 commit 0cf8043

2 files changed

Lines changed: 74 additions & 49 deletions

File tree

lib/exchange/provider/near_Intents_exchange_provider.dart

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,15 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
271271
throw Exception('Failed to parse to currency from assetId: $toAssetId');
272272
}
273273

274-
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency.$1,
275-
tag: fromCurrency.$2);
276-
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency.$1,
277-
tag: toCurrency.$2);
274+
final from = CryptoCurrency.safeParseCurrencyFromString(fromCurrency.$1, tag: fromCurrency.$2);
275+
final to = CryptoCurrency.safeParseCurrencyFromString(toCurrency.$1, tag: toCurrency.$2);
278276

279277

280278
final trade = Trade(
281279
id: depositAddress,
282280
// Using deposit address as trade ID
283281
from: request.fromCurrency,
284-
to: request.toCurrency,
282+
to: request.fromCurrency,
285283
provider: description,
286284
providerName: title,
287285
state: TradeState.created,
@@ -575,10 +573,17 @@ class NearIntentsExchangeProvider extends ExchangeProvider {
575573
final token = supported.firstWhereOrNull((t) => t.assetId == assetId);
576574

577575
if (token == null) return null;
578-
final title = token.symbol;
576+
577+
final title = token.symbol.toUpperCase()
578+
.replaceAll(RegExp(r'\s*\([^)]*\)'), '');
579+
579580
final normalizedNetwork = _normalizeNearBlockchainToTag(token.blockchain);
580-
final tag =
581-
normalizedNetwork == title.toUpperCase() ? null : normalizedNetwork;
581+
582+
final isNativeAsset = assetId.contains(':native:coin');
583+
584+
final tag = isNativeAsset || normalizedNetwork == title
585+
? null
586+
: normalizedNetwork;
582587

583588
return (title, tag);
584589
}

lib/view_model/exchange/exchange_trade_view_model.dart

Lines changed: 61 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:async';
22

33
import 'package:cake_wallet/core/amount_parsing_proxy.dart';
4+
import 'package:cake_wallet/core/execution_state.dart';
45
import 'package:cake_wallet/entities/calculate_fiat_amount.dart';
56
import 'package:cake_wallet/entities/fiat_currency.dart';
67
import 'package:cake_wallet/exchange/exchange_provider_description.dart';
@@ -24,6 +25,7 @@ import 'package:cake_wallet/reactions/wallet_connect.dart';
2425
import 'package:cake_wallet/src/screens/exchange_trade/exchange_trade_item.dart';
2526
import 'package:cake_wallet/store/dashboard/fiat_conversion_store.dart';
2627
import 'package:cake_wallet/store/dashboard/trades_store.dart';
28+
import 'package:cake_wallet/utils/exchange_provider_logger.dart';
2729
import 'package:cake_wallet/utils/qr_util.dart';
2830
import 'package:cake_wallet/utils/token_utilities.dart';
2931
import 'package:cake_wallet/view_model/send/fees_view_model.dart';
@@ -48,7 +50,6 @@ abstract class ExchangeTradeViewModelBase with Store {
4850
required this.feesViewModel,
4951
required this.fiatConversionStore,
5052
}) : trade = tradesStore.trade!,
51-
isSendable = _checkIfCanSend(tradesStore, wallet),
5253
isSwapsXYZCanSendFromExternal = _checkIfSwapsXYZCanSendFromExternal(tradesStore.trade!, wallet),
5354
items = ObservableList<ExchangeTradeItem>() {
5455
setUpOutput();
@@ -115,12 +116,10 @@ abstract class ExchangeTradeViewModelBase with Store {
115116
@observable
116117
Trade trade;
117118

118-
@observable
119-
bool isSendable;
120-
121-
122119
bool isSwapsXYZCanSendFromExternal;
123120

121+
bool get isSendable => checkIfCanSend(trade, wallet) == null;
122+
124123
/// Providers that should hide the "send from external" button
125124
static const List<Type> _providersThatHideExternalSend = [
126125
JupiterExchangeProvider,
@@ -212,7 +211,13 @@ abstract class ExchangeTradeViewModelBase with Store {
212211

213212
@action
214213
Future<void> confirmSending() async {
215-
if (!isSendable) return;
214+
final canSendError = checkIfCanSend(trade, wallet);
215+
216+
if (canSendError != null) {
217+
sendViewModel.state = FailureState(canSendError);
218+
return;
219+
}
220+
216221

217222
final selected = trade.from;
218223
if (selected == null) {
@@ -348,48 +353,63 @@ abstract class ExchangeTradeViewModelBase with Store {
348353
);
349354
}
350355

351-
static bool _checkIfCanSend(TradesStore tradesStore, WalletBase wallet) {
352-
final trade = tradesStore.trade!;
353-
final tradeFrom = trade.from;
354-
355-
bool _sameCurrency(CryptoCurrency? a, CryptoCurrency? b) =>
356-
a != null && b != null && a.titleAndTagEqual(b);
357-
358-
bool _isEthToken() =>
359-
wallet.currency == CryptoCurrency.eth && tradeFrom?.tag == CryptoCurrency.eth.title;
356+
String? checkIfCanSend(Trade? trade, WalletBase wallet) {
357+
try {
360358

361-
bool _isPolygonToken() =>
362-
wallet.currency == CryptoCurrency.maticpoly &&
363-
tradeFrom?.tag == CryptoCurrency.maticpoly.tag;
359+
if (trade == null) throw Exception('Trade is null');
364360

365-
bool _isBaseToken() =>
366-
wallet.currency == CryptoCurrency.baseEth && tradeFrom?.tag == CryptoCurrency.baseEth.tag;
361+
final tradeFrom = trade.from;
362+
if (tradeFrom == null) throw Exception('Trade from currency is null');
367363

368-
bool _isArbitrumToken() =>
369-
wallet.currency == CryptoCurrency.arbEth &&
370-
(tradeFrom?.tag == CryptoCurrency.arbEth.tag ||
371-
tradeFrom?.title == CryptoCurrency.arbEth.tag); // This is to handle the CryptoCurrency.arb that doesn't have a tag but fully belongs to the Arbitrum chain
364+
bool _sameCurrency(CryptoCurrency a, CryptoCurrency b) => a.titleAndTagEqual(b);
372365

373-
bool _isTronToken() =>
374-
wallet.currency == CryptoCurrency.trx && tradeFrom?.tag == CryptoCurrency.trx.title;
366+
bool _isTokenBelongingToWallet(CryptoCurrency cur) {
367+
final chainTag = cur.tag ?? cur.title;
368+
return wallet.currency == cur &&
369+
tradeFrom.tag?.toUpperCase() == chainTag.toUpperCase();
370+
}
375371

376-
bool _isSplToken() =>
377-
wallet.currency == CryptoCurrency.sol && tradeFrom?.tag == CryptoCurrency.sol.title;
372+
final canSend = _sameCurrency(tradeFrom, wallet.currency) ||
373+
(_sameCurrency(tradeFrom, CryptoCurrency.btcln) &&
374+
wallet.currency == CryptoCurrency.btc) ||
375+
trade.provider == ExchangeProviderDescription.xmrto ||
376+
_isTokenBelongingToWallet(CryptoCurrency.eth) ||
377+
_isTokenBelongingToWallet(CryptoCurrency.maticpoly) ||
378+
_isTokenBelongingToWallet(CryptoCurrency.baseEth) ||
379+
_isTokenBelongingToWallet(CryptoCurrency.arbEth) ||
380+
_isTokenBelongingToWallet(CryptoCurrency.trx) ||
381+
_isTokenBelongingToWallet(CryptoCurrency.sol) ||
382+
_isTokenBelongingToWallet(CryptoCurrency.bnb);
383+
384+
if (!canSend) {
385+
throw Exception(
386+
'Wallet currency ${wallet.currency.title} does not match trade from currency ${tradeFrom.title} or is not a supported token for this wallet.',
387+
);
388+
}
378389

379-
bool _isBscToken() =>
380-
wallet.currency == CryptoCurrency.bnb && tradeFrom?.tag == CryptoCurrency.bnb.tag;
390+
return null;
391+
} catch (e, s) {
392+
final trade = tradesStore.trade;
393+
394+
ExchangeProviderLogger.logError(
395+
provider: trade?.provider,
396+
function: '_checkIfCanSend',
397+
error: e,
398+
stackTrace: s,
399+
requestData: {
400+
'tradeId': trade?.id,
401+
'tradeFrom': trade?.from?.title,
402+
'tradeFromTag': trade?.from?.tag,
403+
'tradeTo': trade?.to?.title,
404+
'tradeToTag': trade?.to?.tag,
405+
'walletName': wallet.name,
406+
'walletCurrency': wallet.currency.title,
407+
'walletCurrencyTag': wallet.currency.tag,
408+
},
409+
);
381410

382-
return _sameCurrency(tradeFrom, wallet.currency) ||
383-
(_sameCurrency(tradeFrom, CryptoCurrency.btcln) &&
384-
wallet.currency == CryptoCurrency.btc) ||
385-
tradesStore.trade!.provider == ExchangeProviderDescription.xmrto ||
386-
_isEthToken() ||
387-
_isPolygonToken() ||
388-
_isSplToken() ||
389-
_isTronToken() ||
390-
_isBaseToken() ||
391-
_isArbitrumToken() ||
392-
_isBscToken();
411+
return e.toString();
412+
}
393413
}
394414

395415
static bool _checkIfSwapsXYZCanSendFromExternal(Trade trade, WalletBase wallet) {

0 commit comments

Comments
 (0)