|
1 | 1 | import { subscribeKey as subKey } from 'valtio/vanilla/utils'; |
2 | 2 | import { proxy, subscribe as sub } from 'valtio/vanilla'; |
3 | | -import type { |
4 | | - OnRampPaymentMethod, |
5 | | - OnRampCountry, |
6 | | - OnRampFiatCurrency, |
7 | | - OnRampQuote, |
8 | | - OnRampFiatLimit, |
9 | | - OnRampCryptoCurrency, |
10 | | - OnRampServiceProvider, |
11 | | - OnRampError, |
12 | | - OnRampErrorTypeValues, |
13 | | - OnRampCountryDefaults |
| 3 | +import { |
| 4 | + type OnRampPaymentMethod, |
| 5 | + type OnRampCountry, |
| 6 | + type OnRampFiatCurrency, |
| 7 | + type OnRampQuote, |
| 8 | + type OnRampFiatLimit, |
| 9 | + type OnRampCryptoCurrency, |
| 10 | + type OnRampServiceProvider, |
| 11 | + type OnRampError, |
| 12 | + type OnRampErrorTypeValues, |
| 13 | + type OnRampCountryDefaults, |
| 14 | + BlockchainOnRampError |
14 | 15 | } from '../utils/TypeUtil'; |
15 | 16 |
|
16 | 17 | import { CoreHelperUtil } from '../utils/CoreHelperUtil'; |
@@ -115,27 +116,35 @@ export const OnRampController = { |
115 | 116 | }, |
116 | 117 |
|
117 | 118 | async setSelectedCountry(country: OnRampCountry, updateCurrency = true) { |
118 | | - state.selectedCountry = country; |
119 | | - state.loading = true; |
| 119 | + try { |
| 120 | + state.selectedCountry = country; |
| 121 | + state.loading = true; |
120 | 122 |
|
121 | | - if (updateCurrency) { |
122 | | - const currencyCode = |
123 | | - state.countriesDefaults?.find(d => d.countryCode === country.countryCode) |
124 | | - ?.defaultCurrencyCode || 'USD'; |
| 123 | + if (updateCurrency) { |
| 124 | + const currencyCode = |
| 125 | + state.countriesDefaults?.find(d => d.countryCode === country.countryCode) |
| 126 | + ?.defaultCurrencyCode || 'USD'; |
125 | 127 |
|
126 | | - const currency = state.paymentCurrencies?.find(c => c.currencyCode === currencyCode); |
| 128 | + const currency = state.paymentCurrencies?.find(c => c.currencyCode === currencyCode); |
127 | 129 |
|
128 | | - if (currency) { |
129 | | - this.setPaymentCurrency(currency); |
| 130 | + if (currency) { |
| 131 | + this.setPaymentCurrency(currency); |
| 132 | + } |
130 | 133 | } |
131 | | - } |
132 | 134 |
|
133 | | - await Promise.all([this.fetchPaymentMethods(), this.fetchCryptoCurrencies()]); |
134 | | - this.clearQuotes(); |
| 135 | + await Promise.all([this.fetchPaymentMethods(), this.fetchCryptoCurrencies()]); |
| 136 | + this.clearQuotes(); |
135 | 137 |
|
136 | | - state.loading = false; |
| 138 | + state.loading = false; |
137 | 139 |
|
138 | | - StorageUtil.setOnRampPreferredCountry(country); |
| 140 | + StorageUtil.setOnRampPreferredCountry(country); |
| 141 | + } catch (error) { |
| 142 | + state.loading = false; |
| 143 | + state.error = { |
| 144 | + type: OnRampErrorType.FAILED_TO_LOAD_COUNTRIES, |
| 145 | + message: 'Failed to load countries' |
| 146 | + }; |
| 147 | + } |
139 | 148 | }, |
140 | 149 |
|
141 | 150 | setSelectedPaymentMethod(paymentMethod: OnRampPaymentMethod) { |
@@ -395,40 +404,45 @@ export const OnRampController = { |
395 | 404 | } |
396 | 405 | }, |
397 | 406 |
|
398 | | - getQuotesDebounced: CoreHelperUtil.debounce(function () { |
399 | | - OnRampController.getQuotes(); |
400 | | - }, 500), |
401 | | - |
402 | 407 | async getQuotes() { |
403 | | - if (!state.paymentAmount || state.paymentAmount <= 0) { |
| 408 | + if (!this.canGenerateQuote()) { |
404 | 409 | this.clearQuotes(); |
405 | 410 |
|
406 | 411 | return; |
407 | 412 | } |
408 | 413 |
|
409 | | - state.quotesLoading = true; |
410 | | - state.selectedQuote = undefined; |
411 | | - state.selectedServiceProvider = undefined; |
412 | | - state.error = undefined; |
413 | | - |
414 | 414 | this.abortGetQuotes(false); |
415 | 415 | quotesAbortController = new AbortController(); |
416 | 416 | const currentSignal = quotesAbortController.signal; |
417 | 417 |
|
418 | 418 | try { |
| 419 | + if ( |
| 420 | + !state.selectedCountry?.countryCode || |
| 421 | + !state.purchaseCurrency?.currencyCode || |
| 422 | + !state.paymentCurrency?.currencyCode || |
| 423 | + !AccountController.state.address |
| 424 | + ) { |
| 425 | + throw new BlockchainOnRampError(OnRampErrorType.UNKNOWN, 'Invalid quote parameters'); |
| 426 | + } |
| 427 | + |
| 428 | + state.quotesLoading = true; |
| 429 | + state.selectedQuote = undefined; |
| 430 | + state.selectedServiceProvider = undefined; |
| 431 | + state.error = undefined; |
| 432 | + |
419 | 433 | const body = { |
420 | | - countryCode: state.selectedCountry?.countryCode!, |
421 | | - destinationCurrencyCode: state.purchaseCurrency?.currencyCode!, |
422 | | - sourceAmount: state.paymentAmount, |
423 | | - sourceCurrencyCode: state.paymentCurrency?.currencyCode!, |
424 | | - walletAddress: AccountController.state.address!, |
| 434 | + countryCode: state.selectedCountry.countryCode, |
| 435 | + destinationCurrencyCode: state.purchaseCurrency.currencyCode, |
| 436 | + sourceAmount: state.paymentAmount!, |
| 437 | + sourceCurrencyCode: state.paymentCurrency.currencyCode, |
| 438 | + walletAddress: AccountController.state.address, |
425 | 439 | excludeProviders: EXCLUDED_ONRAMP_PROVIDERS |
426 | 440 | }; |
427 | 441 |
|
428 | 442 | const response = await BlockchainApiController.getOnRampQuotes(body, currentSignal); |
429 | 443 |
|
430 | 444 | if (!response || !response.length) { |
431 | | - throw { code: OnRampErrorType.NO_VALID_QUOTES }; |
| 445 | + throw new BlockchainOnRampError(OnRampErrorType.NO_VALID_QUOTES, 'No valid quotes'); |
432 | 446 | } |
433 | 447 |
|
434 | 448 | const quotes = response.sort((a, b) => b.customerScore - a.customerScore); |
@@ -647,3 +661,8 @@ export const OnRampController = { |
647 | 661 | this.updateSelectedPurchaseCurrency(); |
648 | 662 | } |
649 | 663 | }; |
| 664 | + |
| 665 | +// Add getQuotesDebounced to the controller after definition to avoid circular reference |
| 666 | +(OnRampController as any).getQuotesDebounced = CoreHelperUtil.debounce(function () { |
| 667 | + OnRampController.getQuotes(); |
| 668 | +}, 500); |
0 commit comments