fix: better handle exchange url launching

OmarHatem committed Oct 31, 2025 at 15:00 UTC f5119d262ad15be5964fbc3095bd0ea093853d62
4 files changed +40 -18
lib/buy/sell_buy_states.dart
+5 -1
@@ -17,4 +17,8 @@ class BuySellQuotLoading extends BuySellQuotLoadingState {}
17
18 class BuySellQuotLoaded extends BuySellQuotLoadingState {}
19
20 -class BuySellQuotFailed extends BuySellQuotLoadingState {}
\ No newline at end of file
20 +class BuySellQuotFailed extends BuySellQuotLoadingState {
21 + final String? errorMessage;
22 +
23 + BuySellQuotFailed({this.errorMessage});
24 +}
\ No newline at end of file
lib/core/wallet_loading_service.dart
+5 -1
@@ -131,7 +131,11 @@ class WalletLoadingService {
131 alertContent: S.of(context).corrupted_seed_notice,
132 leftButtonText: S.of(context).cancel,
133 rightButtonText: S.of(context).show_seed,
134 - actionLeftButton: () => Navigator.of(context).pop(),
134 + actionLeftButton: () {
135 + if (context.mounted && Navigator.of(context).canPop()) {
136 + Navigator.of(context).pop();
137 + }
138 + },
139 actionRightButton: () => showSeedsPopup(context, msg),
140 );
141 });
lib/src/screens/buy/buy_sell_page.dart
+5 -4
@@ -148,7 +148,7 @@ class BuySellPage extends BasePage {
148 bottomSection: Observer(
149 builder: (_) => Column(
150 children: [
151 - if (buySellViewModel.isBuySellQuotFailed)
151 + if (buySellViewModel.isBuySellQuoteFailed)
152 Padding(
153 padding: EdgeInsets.only(bottom: 15),
154 child: Row(
@@ -166,7 +166,8 @@ class BuySellPage extends BasePage {
166 Expanded(
167 flex: 8,
168 child: Text(
169 - S.of(context).buy_sell_pair_is_not_supported_warning,
169 + buySellViewModel.buySellQuoteFailedError ??
170 + S.of(context).buy_sell_pair_is_not_supported_warning,
171 textAlign: TextAlign.center,
172 softWrap: true,
173 overflow: TextOverflow.ellipsis,
@@ -188,9 +189,9 @@ class BuySellPage extends BasePage {
189 },
190 color: Theme.of(context).colorScheme.primary,
191 textColor: Theme.of(context).colorScheme.onPrimary,
191 - isDisabled: buySellViewModel.isBuySellQuotFailed,
192 + isDisabled: buySellViewModel.isBuySellQuoteFailed,
193 isLoading:
193 - !buySellViewModel.isReadyToTrade && !buySellViewModel.isBuySellQuotFailed,
194 + !buySellViewModel.isReadyToTrade && !buySellViewModel.isBuySellQuoteFailed,
195 ),
196 ],
197 ),
lib/view_model/buy/buy_sell_view_model.dart
+25 -12
@@ -157,7 +157,12 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
157 }
158
159 @computed
160 - bool get isBuySellQuotFailed => buySellQuotState is BuySellQuotFailed;
160 + bool get isBuySellQuoteFailed => buySellQuotState is BuySellQuotFailed;
161 +
162 + @computed
163 + String? get buySellQuoteFailedError => buySellQuotState is BuySellQuotFailed
164 + ? (buySellQuotState as BuySellQuotFailed).errorMessage
165 + : null;
166
167 @action
168 void reset() {
@@ -201,10 +206,10 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
206
207 final enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0;
208
204 - if (!isReadyToTrade && !isBuySellQuotFailed) {
209 + if (!isReadyToTrade && !isBuySellQuoteFailed) {
210 cryptoAmount = S.current.fetching;
211 return;
207 - } else if (isBuySellQuotFailed) {
212 + } else if (isBuySellQuoteFailed) {
213 cryptoAmount = '';
214 return;
215 }
@@ -232,10 +237,10 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
237
238 final enteredAmount = double.tryParse(amount.replaceAll(',', '.')) ?? 0;
239
235 - if (!isReadyToTrade && !isBuySellQuotFailed) {
240 + if (!isReadyToTrade && !isBuySellQuoteFailed) {
241 fiatAmount = S.current.fetching;
242 return;
238 - } else if (isBuySellQuotFailed) {
243 + } else if (isBuySellQuoteFailed) {
244 fiatAmount = '';
245 return;
246 }
@@ -478,12 +483,20 @@ abstract class BuySellViewModelBase extends WalletChangeListenerViewModel with S
483 @action
484 Future<void> launchTrade(BuildContext context) async {
485 final provider = selectedQuote!.provider;
481 - await provider.launchProvider(
482 - context: context,
483 - quote: selectedQuote!,
484 - amount: amount,
485 - isBuyAction: isBuyAction,
486 - cryptoCurrencyAddress: cryptoCurrencyAddress,
487 - );
486 + try {
487 + await provider.launchProvider(
488 + context: context,
489 + quote: selectedQuote!,
490 + amount: amount,
491 + isBuyAction: isBuyAction,
492 + cryptoCurrencyAddress: cryptoCurrencyAddress,
493 + );
494 + } catch (e) {
495 + if (e.toString().contains("403")) {
496 + buySellQuotState = BuySellQuotFailed(errorMessage: "Using Tor is not supported");
497 + } else {
498 + buySellQuotState = BuySellQuotFailed(errorMessage: "Something went wrong please try again later");
499 + }
500 + }
501 }
502 }