diff --git a/src/components/scenes/RampCreateScene.tsx b/src/components/scenes/RampCreateScene.tsx index 997fb77a68f..e281096c0ee 100644 --- a/src/components/scenes/RampCreateScene.tsx +++ b/src/components/scenes/RampCreateScene.tsx @@ -32,8 +32,8 @@ import { import { useWatch } from '../../hooks/useWatch' import { lstrings } from '../../locales/strings' import type { - RampExchangeAmount, RampPlugin, + RampQouteAmount, RampQuote, RampQuoteRequest } from '../../plugins/ramps/rampPluginTypes' @@ -107,8 +107,8 @@ export const RampCreateScene: React.FC = (props: Props) => { ) // State for trade form - const [exchangeAmount, setExchangeAmount] = useState< - RampExchangeAmount | { empty: true } + const [amountQuery, setAmountQuery] = useState< + RampQouteAmount | { empty: true } >({ empty: true }) const [lastUsedInput, setLastUsedInput] = useState<'fiat' | 'crypto' | null>( null @@ -251,7 +251,7 @@ export const RampCreateScene: React.FC = (props: Props) => { if ( hasAppliedInitialAmount.current || amountTypeSupport.onlyCrypto || - !('empty' in exchangeAmount) || + !('empty' in amountQuery) || lastUsedInput != null || shouldShowRegionSelect ) { @@ -270,7 +270,7 @@ export const RampCreateScene: React.FC = (props: Props) => { ) hasAppliedInitialAmount.current = true - setExchangeAmount({ amount: initialFiat }) + setAmountQuery({ exchangeAmount: initialFiat }) setLastUsedInput('fiat') } @@ -287,7 +287,7 @@ export const RampCreateScene: React.FC = (props: Props) => { selectedFiatCurrencyCode, shouldShowRegionSelect, fiatUsdRate, - exchangeAmount, + amountQuery, direction ]) @@ -297,7 +297,7 @@ export const RampCreateScene: React.FC = (props: Props) => { selectedWallet == null || selectedCryptoCurrencyCode == null || lastUsedInput == null || - 'empty' in exchangeAmount || + 'empty' in amountQuery || countryCode === '' ) { return null @@ -316,14 +316,14 @@ export const RampCreateScene: React.FC = (props: Props) => { direction === 'sell' && lastUsedInput === 'crypto' && denomination != null && - !('max' in exchangeAmount) + !('max' in amountQuery || 'maxExchangeAmount' in amountQuery) ) { const tokenId: EdgeTokenId = selectedCrypto?.tokenId ?? null const nativeBalance = selectedWallet.balanceMap.get(tokenId) ?? '0' const walletCryptoAmount = convertNativeToDenomination( denomination.multiplier )(nativeBalance) - if (gt(exchangeAmount.amount, walletCryptoAmount)) return null + if (gt(amountQuery.exchangeAmount, walletCryptoAmount)) return null } return { @@ -331,7 +331,7 @@ export const RampCreateScene: React.FC = (props: Props) => { pluginId: selectedWallet.currencyInfo.pluginId, tokenId: selectedCrypto?.tokenId ?? null, displayCurrencyCode: selectedCryptoCurrencyCode, - exchangeAmount, + amountQuery, fiatCurrencyCode: selectedFiatCurrencyCode, amountType: lastUsedInput, direction, @@ -344,7 +344,7 @@ export const RampCreateScene: React.FC = (props: Props) => { selectedWallet, selectedCryptoCurrencyCode, selectedCrypto, - exchangeAmount, + amountQuery, selectedFiatCurrencyCode, lastUsedInput, countryCode, @@ -373,7 +373,11 @@ export const RampCreateScene: React.FC = (props: Props) => { // For Max flow, select the quote with the largest supported amount const maxQuoteForMaxFlow = React.useMemo(() => { - if (!('max' in exchangeAmount) || allQuotes.length === 0) return null + if ( + !('max' in amountQuery || 'maxExchangeAmount' in amountQuery) || + allQuotes.length === 0 + ) + return null const quotesWithAmounts = allQuotes.filter(rampQuoteHasAmounts) if (quotesWithAmounts.length === 0) return null @@ -384,7 +388,7 @@ export const RampCreateScene: React.FC = (props: Props) => { return gt(bAmount, aAmount) ? b : a }) return picked - }, [exchangeAmount, allQuotes, lastUsedInput]) + }, [amountQuery, allQuotes, lastUsedInput]) // Calculate exchange rate from best quote const quoteExchangeRate = React.useMemo(() => { @@ -415,18 +419,19 @@ export const RampCreateScene: React.FC = (props: Props) => { if (selectedWallet == null) return null if (selectedCrypto == null) return null if (denomination == null) return null - if ('empty' in exchangeAmount) return null - if ('max' in exchangeAmount) return null + if ('empty' in amountQuery) return null + if ('max' in amountQuery) return null + if ('maxExchangeAmount' in amountQuery) return null if (lastUsedInput == null) return null // Determine requested crypto amount let requestedCryptoAmount: string | null = null if (lastUsedInput === 'crypto') { - requestedCryptoAmount = exchangeAmount.amount + requestedCryptoAmount = amountQuery.exchangeAmount } else if (lastUsedInput === 'fiat') { if (quoteExchangeRate === 0) return null requestedCryptoAmount = div( - exchangeAmount.amount, + amountQuery.exchangeAmount, quoteExchangeRate.toString(), DECIMAL_PRECISION ) @@ -451,7 +456,7 @@ export const RampCreateScene: React.FC = (props: Props) => { selectedWallet, selectedCrypto, denomination, - exchangeAmount, + amountQuery, lastUsedInput, quoteExchangeRate ]) @@ -460,21 +465,21 @@ export const RampCreateScene: React.FC = (props: Props) => { const displayFiatAmount = React.useMemo(() => { // Don't show any value if fiat input is disabled if (amountTypeSupport.onlyCrypto) return '' - if ('empty' in exchangeAmount) return '' + if ('empty' in amountQuery) return '' - if ('max' in exchangeAmount) { + if ('max' in amountQuery || 'maxExchangeAmount' in amountQuery) { return maxQuoteForMaxFlow?.fiatAmount ?? '' } if (lastUsedInput === 'fiat') { // User entered fiat, show raw value (FilledTextInput will format it) - return exchangeAmount.amount + return amountQuery.exchangeAmount } else if (lastUsedInput === 'crypto') { // Avoid division by zero if (quoteExchangeRate === 0) return '' // User entered crypto, convert to fiat only if we have a quote return div( - mul(exchangeAmount.amount, quoteExchangeRate.toString()), + mul(amountQuery.exchangeAmount, quoteExchangeRate.toString()), '1', 2 ) @@ -484,7 +489,7 @@ export const RampCreateScene: React.FC = (props: Props) => { }, [ amountTypeSupport.onlyCrypto, maxQuoteForMaxFlow, - exchangeAmount, + amountQuery, lastUsedInput, quoteExchangeRate ]) @@ -492,18 +497,18 @@ export const RampCreateScene: React.FC = (props: Props) => { const displayCryptoAmount = React.useMemo(() => { // Don't show any value if crypto input is disabled if (amountTypeSupport.onlyFiat) return '' - if ('empty' in exchangeAmount || lastUsedInput === null) return '' + if ('empty' in amountQuery || lastUsedInput === null) return '' - if ('max' in exchangeAmount) { - return ( - maxQuoteForMaxFlow?.cryptoAmount ?? - (typeof exchangeAmount.max === 'string' ? exchangeAmount.max : '') - ) + if ('max' in amountQuery) { + return maxQuoteForMaxFlow?.cryptoAmount ?? '' + } + if ('maxExchangeAmount' in amountQuery) { + return maxQuoteForMaxFlow?.cryptoAmount ?? amountQuery.maxExchangeAmount } if (lastUsedInput === 'crypto') { // User entered crypto, show raw value (FilledTextInput will format it) - return exchangeAmount.amount + return amountQuery.exchangeAmount } else if (lastUsedInput === 'fiat') { // Avoid division by zero if (quoteExchangeRate === 0) return '' @@ -512,14 +517,18 @@ export const RampCreateScene: React.FC = (props: Props) => { ? mulToPrecision(denomination.multiplier) : DECIMAL_PRECISION // User entered fiat, convert to crypto only if we have a quote - return div(exchangeAmount.amount, quoteExchangeRate.toString(), decimals) + return div( + amountQuery.exchangeAmount, + quoteExchangeRate.toString(), + decimals + ) } else { return '' } }, [ amountTypeSupport.onlyFiat, maxQuoteForMaxFlow, - exchangeAmount, + amountQuery, lastUsedInput, quoteExchangeRate, denomination @@ -567,7 +576,7 @@ export const RampCreateScene: React.FC = (props: Props) => { // Clear amount and max state when switching crypto assets in sell mode setPendingMaxNav(false) if (direction === 'sell') { - setExchangeAmount({ empty: true }) + setAmountQuery({ empty: true }) setLastUsedInput(null) } @@ -599,7 +608,7 @@ export const RampCreateScene: React.FC = (props: Props) => { selectedWallet == null || selectedCryptoCurrencyCode == null || lastUsedInput == null || - 'empty' in exchangeAmount || + 'empty' in amountQuery || rampQuoteRequest == null ) { return @@ -636,12 +645,12 @@ export const RampCreateScene: React.FC = (props: Props) => { }, [bestQuote, selectedFiatCurrencyCode]) const handleFiatChangeText = useHandler((amount: string) => { - setExchangeAmount(amount === '' ? { empty: true } : { amount }) + setAmountQuery(amount === '' ? { empty: true } : { exchangeAmount: amount }) setLastUsedInput('fiat') }) const handleCryptoChangeText = useHandler((amount: string) => { - setExchangeAmount(amount === '' ? { empty: true } : { amount }) + setAmountQuery(amount === '' ? { empty: true } : { exchangeAmount: amount }) setLastUsedInput('crypto') }) @@ -667,11 +676,11 @@ export const RampCreateScene: React.FC = (props: Props) => { selectedCrypto.tokenId, denomination ) - setExchangeAmount({ - max: maxSpendExchangeAmount + setAmountQuery({ + maxExchangeAmount: maxSpendExchangeAmount }) } else { - setExchangeAmount({ + setAmountQuery({ max: true }) } @@ -680,10 +689,11 @@ export const RampCreateScene: React.FC = (props: Props) => { // Auto-navigate once a best quote arrives for the transient max flow React.useEffect(() => { const isMaxRequest = - rampQuoteRequest != null && 'max' in rampQuoteRequest.exchangeAmount + rampQuoteRequest != null && + ('max' in rampQuoteRequest.amountQuery || + 'maxExchangeAmount' in rampQuoteRequest.amountQuery) if ( pendingMaxNav && - 'max' in exchangeAmount && isMaxRequest && maxQuoteForMaxFlow != null && !isLoadingQuotes @@ -702,7 +712,7 @@ export const RampCreateScene: React.FC = (props: Props) => { navigation, amountTypeSupport.onlyCrypto, amountTypeSupport.onlyFiat, - exchangeAmount, + amountQuery, selectedWallet, selectedCrypto ]) @@ -722,7 +732,7 @@ export const RampCreateScene: React.FC = (props: Props) => { isResultLoading || allQuotes.length !== 0 || supportedPlugins.length === 0 || - 'empty' in exchangeAmount + 'empty' in amountQuery ) { return null } @@ -747,7 +757,7 @@ export const RampCreateScene: React.FC = (props: Props) => { isResultLoading, allQuotes.length, supportedPlugins.length, - exchangeAmount, + amountQuery, supportedPluginsError, quoteErrors, lastUsedInput, @@ -902,7 +912,7 @@ export const RampCreateScene: React.FC = (props: Props) => { {selectedCrypto == null || selectedWallet == null || denomination == null || - 'empty' in exchangeAmount || + 'empty' in amountQuery || lastUsedInput == null || (!isLoadingQuotes && !isFetchingQuotes && @@ -932,7 +942,7 @@ export const RampCreateScene: React.FC = (props: Props) => { // No other error to show (e.g., insufficient funds) errorForDisplay == null && // User has queried - !('empty' in exchangeAmount) && + !('empty' in amountQuery) && lastUsedInput != null && selectedWallet != null && selectedCryptoCurrencyCode != null ? ( @@ -968,7 +978,7 @@ export const RampCreateScene: React.FC = (props: Props) => { isResultLoading || selectedWallet == null || selectedCryptoCurrencyCode == null || - 'empty' in exchangeAmount || + 'empty' in amountQuery || lastUsedInput === null || supportedPlugins.length === 0 || allQuotes.length === 0 || diff --git a/src/plugins/ramps/banxa/banxaRampPlugin.ts b/src/plugins/ramps/banxa/banxaRampPlugin.ts index 713c4b393bf..82217eeacd4 100644 --- a/src/plugins/ramps/banxa/banxaRampPlugin.ts +++ b/src/plugins/ramps/banxa/banxaRampPlugin.ts @@ -890,13 +890,16 @@ export const banxaRampPlugin: RampPluginFactory = ( } = request const currencyPluginId = request.wallet.currencyInfo.pluginId - const isMaxAmount = 'max' in request.exchangeAmount + const isMaxAmount = + 'max' in request.amountQuery || + 'maxExchangeAmount' in request.amountQuery const exchangeAmount = - 'amount' in request.exchangeAmount ? request.exchangeAmount.amount : '' + 'exchangeAmount' in request.amountQuery + ? request.amountQuery.exchangeAmount + : '' const maxAmountLimit = - 'max' in request.exchangeAmount && - typeof request.exchangeAmount.max === 'string' - ? request.exchangeAmount.max + 'maxExchangeAmount' in request.amountQuery + ? request.amountQuery.maxExchangeAmount : undefined // Fetch provider configuration (cached or fresh) diff --git a/src/plugins/ramps/infinite/infiniteRampPlugin.ts b/src/plugins/ramps/infinite/infiniteRampPlugin.ts index 16927ee954f..54442d7f954 100644 --- a/src/plugins/ramps/infinite/infiniteRampPlugin.ts +++ b/src/plugins/ramps/infinite/infiniteRampPlugin.ts @@ -291,7 +291,7 @@ export const infiniteRampPlugin: RampPluginFactory = ( return { supported: true, - supportedAmountTypes: ['fiat'] + supportedAmountTypes: ['fiat', 'crypto'] } } catch (error) { console.error('Infinite: Error in checkSupport:', error) @@ -310,24 +310,14 @@ export const infiniteRampPlugin: RampPluginFactory = ( const currencyPluginId = request.wallet.currencyInfo.pluginId - // Only support fiat amounts for now - if (request.amountType !== 'fiat') { - throw new FiatProviderError({ - providerId: pluginId, - errorType: 'amountTypeUnsupported' - }) - } - - // Check if max amount requested - if ('max' in request.exchangeAmount) { - // TODO: Implement max amount logic when API supports it - return [] - } - - const fiatAmount = parseFloat(request.exchangeAmount.amount) - if (isNaN(fiatAmount) || fiatAmount <= 0) { - return [] - } + // Extract max amount flags + const isMaxAmount = + 'max' in request.amountQuery || + 'maxExchangeAmount' in request.amountQuery + const maxAmountLimit = + 'maxExchangeAmount' in request.amountQuery + ? request.amountQuery.maxExchangeAmount + : undefined // Get the Infinite network name const infiniteNetwork = getInfiniteNetwork(currencyPluginId) @@ -445,18 +435,95 @@ export const infiniteRampPlugin: RampPluginFactory = ( }) } - // Check amount limits based on direction and amount type - if (request.direction === 'buy') { - // For buy, we have fiat amount and need to check fiat limits - const fiatCurrency = currencies.currencies.find( - c => c.code === cleanFiatCode && c.type === 'fiat' - ) + const amountType = request.amountType + const isFiatAmountType = amountType === 'fiat' + const isCryptoAmountType = !isFiatAmountType + + // Get fiat currency for limit checking and max amount determination + const fiatCurrency = currencies.currencies.find( + c => c.code === cleanFiatCode && c.type === 'fiat' + ) + + if (fiatCurrency == null) { + throw new FiatProviderError({ + providerId: pluginId, + errorType: 'fiatUnsupported', + fiatCurrencyCode: cleanFiatCode, + paymentMethod: 'bank', + pluginDisplayName + }) + } + + const parseAmountString = (value?: string): number | undefined => { + if (value == null) return undefined + const parsed = parseFloat(value) + return Number.isFinite(parsed) ? parsed : undefined + } + + const maxAmountLimitValue = parseAmountString(maxAmountLimit) + const minFiatAmount = parseAmountString(fiatCurrency.minAmount) + const maxFiatAmount = parseAmountString(fiatCurrency.maxAmount) + const minCryptoAmount = parseAmountString(targetCurrency.minAmount) + const maxCryptoAmount = parseAmountString(targetCurrency.maxAmount) + + let fiatAmount: number | undefined + let cryptoAmount: number | undefined + + const amountString = + 'exchangeAmount' in request.amountQuery + ? request.amountQuery.exchangeAmount + : undefined + + const assertNumber = (value: number | undefined): value is number => + value != null && Number.isFinite(value) + + if (isMaxAmount) { + if (isFiatAmountType) { + if (!assertNumber(maxFiatAmount)) return [] + if (assertNumber(maxAmountLimitValue)) { + fiatAmount = Math.min(maxFiatAmount, maxAmountLimitValue) + + if (assertNumber(minFiatAmount) && fiatAmount < minFiatAmount) { + throw new FiatProviderError({ + providerId: pluginId, + errorType: 'underLimit', + errorAmount: minFiatAmount, + displayCurrencyCode: request.fiatCurrencyCode + }) + } + } else { + fiatAmount = maxFiatAmount + } + } else { + if (!assertNumber(maxCryptoAmount)) return [] + let amountToUse = maxCryptoAmount + if (assertNumber(maxAmountLimitValue)) { + amountToUse = Math.min(amountToUse, maxAmountLimitValue) + } + cryptoAmount = amountToUse + + if (assertNumber(minCryptoAmount) && cryptoAmount < minCryptoAmount) { + throw new FiatProviderError({ + providerId: pluginId, + errorType: 'underLimit', + errorAmount: minCryptoAmount, + displayCurrencyCode: request.displayCurrencyCode + }) + } + } + } else { + if (amountString == null) { + return [] + } + const parsedAmount = parseFloat(amountString) + if (!Number.isFinite(parsedAmount) || parsedAmount <= 0) { + return [] + } - if (fiatCurrency != null) { - const minFiatAmount = parseFloat(fiatCurrency.minAmount) - const maxFiatAmount = parseFloat(fiatCurrency.maxAmount) + if (isFiatAmountType) { + fiatAmount = parsedAmount - if (fiatAmount < minFiatAmount) { + if (assertNumber(minFiatAmount) && fiatAmount < minFiatAmount) { throw new FiatProviderError({ providerId: pluginId, errorType: 'underLimit', @@ -465,7 +532,7 @@ export const infiniteRampPlugin: RampPluginFactory = ( }) } - if (fiatAmount > maxFiatAmount) { + if (assertNumber(maxFiatAmount) && fiatAmount > maxFiatAmount) { throw new FiatProviderError({ providerId: pluginId, errorType: 'overLimit', @@ -473,53 +540,90 @@ export const infiniteRampPlugin: RampPluginFactory = ( displayCurrencyCode: request.fiatCurrencyCode }) } + } else { + cryptoAmount = parsedAmount + + if (assertNumber(minCryptoAmount) && cryptoAmount < minCryptoAmount) { + throw new FiatProviderError({ + providerId: pluginId, + errorType: 'underLimit', + errorAmount: minCryptoAmount, + displayCurrencyCode: request.displayCurrencyCode + }) + } + + if (assertNumber(maxCryptoAmount) && cryptoAmount > maxCryptoAmount) { + throw new FiatProviderError({ + providerId: pluginId, + errorType: 'overLimit', + errorAmount: maxCryptoAmount, + displayCurrencyCode: request.displayCurrencyCode + }) + } } - } else { - // For sell, we need to check crypto limits - // Since amountType is 'fiat', we don't have the crypto amount yet - // We'll need to fetch a quote first to know the crypto amount - // For now, skip the pre-check and let the API handle limit validation - // The API will return an error if the resulting crypto amount is out of bounds } + if (isFiatAmountType && fiatAmount == null) return [] + if (isCryptoAmountType && cryptoAmount == null) return [] + // Fetch quote from API const flow: InfiniteQuoteFlow = request.direction === 'buy' ? 'ONRAMP' : 'OFFRAMP' + const sourceParams = + request.direction === 'buy' + ? isFiatAmountType + ? { asset: cleanFiatCode, amount: fiatAmount! } + : { asset: cleanFiatCode } + : isCryptoAmountType + ? { + asset: targetCurrency.currencyCode, + network: infiniteNetwork, + amount: cryptoAmount! + } + : { + asset: targetCurrency.currencyCode, + network: infiniteNetwork + } + + const targetParams = + request.direction === 'buy' + ? { + asset: targetCurrency.currencyCode, + network: infiniteNetwork, + ...(isCryptoAmountType ? { amount: cryptoAmount! } : {}) + } + : isFiatAmountType + ? { asset: cleanFiatCode, amount: fiatAmount! } + : { asset: cleanFiatCode } + const quoteParams = { flow, - source: - request.direction === 'buy' - ? { asset: cleanFiatCode, amount: fiatAmount } - : { - asset: targetCurrency.currencyCode, - network: infiniteNetwork - // Don't provide amount for sell when we have fiat amount - }, - target: - request.direction === 'buy' - ? { asset: targetCurrency.currencyCode, network: infiniteNetwork } - : { asset: cleanFiatCode, amount: fiatAmount } // Provide target amount for sell + source: sourceParams, + target: targetParams } const quoteResponse = await infiniteApi.createQuote(quoteParams) + const responseCryptoAmount = + request.direction === 'buy' + ? quoteResponse.target.amount + : quoteResponse.source.amount + const responseFiatAmount = + request.direction === 'buy' + ? quoteResponse.source.amount + : quoteResponse.target.amount + // Convert to RampQuoteResult - map based on direction const quote: RampQuote = { pluginId, partnerIcon, pluginDisplayName, displayCurrencyCode: request.displayCurrencyCode, - cryptoAmount: - request.direction === 'buy' - ? quoteResponse.target.amount.toString() - : quoteResponse.source.amount.toString(), + cryptoAmount: (responseCryptoAmount ?? 0).toString(), isEstimate: false, fiatCurrencyCode: request.fiatCurrencyCode, - fiatAmount: - request.direction === 'buy' - ? quoteResponse.source.amount.toString() - : quoteResponse.target.amount.toString(), + fiatAmount: (responseFiatAmount ?? 0).toString(), direction: request.direction, regionCode: request.regionCode, paymentType: 'wire', // Infinite uses wire bank transfers @@ -543,8 +647,8 @@ export const infiniteRampPlugin: RampPluginFactory = ( // DEV ONLY: Clear auth key if amount is exactly 404 if ( ENABLE_DEV_TESTING_CAPABILITIES && - 'amount' in request.exchangeAmount && - request.exchangeAmount.amount === '404' + `exchangeAmount` in request.amountQuery && + request.amountQuery.exchangeAmount === '404' ) { await _devOnlyClearAuthKey(account, pluginId) } diff --git a/src/plugins/ramps/moonpay/moonpayRampPlugin.ts b/src/plugins/ramps/moonpay/moonpayRampPlugin.ts index 7d41c61c49d..bf72dc8f165 100644 --- a/src/plugins/ramps/moonpay/moonpayRampPlugin.ts +++ b/src/plugins/ramps/moonpay/moonpayRampPlugin.ts @@ -517,13 +517,16 @@ export const moonpayRampPlugin: RampPluginFactory = ( const { direction, regionCode, displayCurrencyCode, tokenId } = request const fiatCurrencyCode = ensureIsoPrefix(request.fiatCurrencyCode) - const isMaxAmount = 'max' in request.exchangeAmount + const isMaxAmount = + 'max' in request.amountQuery || + 'maxExchangeAmount' in request.amountQuery const exchangeAmountString = - 'amount' in request.exchangeAmount ? request.exchangeAmount.amount : '' + `exchangeAmount` in request.amountQuery + ? request.amountQuery.exchangeAmount + : '' const maxAmountLimitString = - 'max' in request.exchangeAmount && - typeof request.exchangeAmount.max === 'string' - ? request.exchangeAmount.max + 'maxExchangeAmount' in request.amountQuery + ? request.amountQuery.maxExchangeAmount : undefined // Fetch provider configuration (with caching) diff --git a/src/plugins/ramps/paybis/paybisRampPlugin.ts b/src/plugins/ramps/paybis/paybisRampPlugin.ts index bf5aadef0b7..feafc97390c 100644 --- a/src/plugins/ramps/paybis/paybisRampPlugin.ts +++ b/src/plugins/ramps/paybis/paybisRampPlugin.ts @@ -747,13 +747,16 @@ export const paybisRampPlugin: RampPluginFactory = ( } = request const currencyPluginId = request.wallet.currencyInfo.pluginId - const isMaxAmount = 'max' in request.exchangeAmount + const isMaxAmount = + 'max' in request.amountQuery || + 'maxExchangeAmount' in request.amountQuery const exchangeAmount = - 'amount' in request.exchangeAmount ? request.exchangeAmount.amount : '' + `exchangeAmount` in request.amountQuery + ? request.amountQuery.exchangeAmount + : '' const maxAmountLimit = - 'max' in request.exchangeAmount && - typeof request.exchangeAmount.max === 'string' - ? request.exchangeAmount.max + 'maxExchangeAmount' in request.amountQuery + ? request.amountQuery.maxExchangeAmount : undefined // Validate region restrictions diff --git a/src/plugins/ramps/rampPluginTypes.ts b/src/plugins/ramps/rampPluginTypes.ts index ef378c525c4..259b3568766 100644 --- a/src/plugins/ramps/rampPluginTypes.ts +++ b/src/plugins/ramps/rampPluginTypes.ts @@ -37,24 +37,39 @@ export interface RampSupportResult { supportedAmountTypes?: Array<'fiat' | 'crypto'> } -export type RampExchangeAmount = - | { - /** - * Requests a quote for the maximum amount that the provider supports. - * If a string amount is provided (in units of the amountType), then - * the quote amount must not exceed this amount. - * If `true` is provided then the maximum is the amount that the provider - * supports. - * */ - max: string | true - } - | { amount: string } +export type RampQouteAmount = + | RampQuoteMaxAmount + | RampQuoteMaxLimitAmount + | RampQuoteExactAmount + +interface RampQuoteMaxAmount { + /** + * Requests a quote for the maximum amount that the provider supports. + * */ + max: true +} +interface RampQuoteMaxLimitAmount { + /** + * Requests a quote for the maximum amount that the provider supports up to + * a specified limit. + */ + maxExchangeAmount: string +} +interface RampQuoteExactAmount { + /** + * Requests a quote for the exact amount provided. + * */ + exchangeAmount: string +} export interface RampQuoteRequest { wallet: EdgeCurrencyWallet tokenId: EdgeTokenId displayCurrencyCode: string - exchangeAmount: RampExchangeAmount + /** + * The amount parameter apart of the request query. + */ + amountQuery: RampQouteAmount fiatCurrencyCode: string amountType: 'fiat' | 'crypto' direction: 'buy' | 'sell' diff --git a/src/plugins/ramps/revolut/revolutRampPlugin.ts b/src/plugins/ramps/revolut/revolutRampPlugin.ts index a63acbc7239..27bbdcd11a9 100644 --- a/src/plugins/ramps/revolut/revolutRampPlugin.ts +++ b/src/plugins/ramps/revolut/revolutRampPlugin.ts @@ -191,13 +191,16 @@ export const revolutRampPlugin: RampPluginFactory = ( } = request const currencyPluginId = request.wallet.currencyInfo.pluginId - const isMaxAmount = 'max' in request.exchangeAmount + const isMaxAmount = + 'max' in request.amountQuery || + 'maxExchangeAmount' in request.amountQuery const exchangeAmount = - 'amount' in request.exchangeAmount ? request.exchangeAmount.amount : '' + `exchangeAmount` in request.amountQuery + ? request.amountQuery.exchangeAmount + : '' const maxAmountLimit = - 'max' in request.exchangeAmount && - typeof request.exchangeAmount.max === 'string' - ? request.exchangeAmount.max + 'maxExchangeAmount' in request.amountQuery + ? request.amountQuery.maxExchangeAmount : undefined // Constraints per request diff --git a/src/plugins/ramps/simplex/simplexRampPlugin.ts b/src/plugins/ramps/simplex/simplexRampPlugin.ts index b6f23806d1c..b9136c60458 100644 --- a/src/plugins/ramps/simplex/simplexRampPlugin.ts +++ b/src/plugins/ramps/simplex/simplexRampPlugin.ts @@ -480,13 +480,16 @@ export const simplexRampPlugin: RampPluginFactory = ( } = request const currencyPluginId = request.wallet.currencyInfo.pluginId - const isMaxAmount = 'max' in request.exchangeAmount + const isMaxAmount = + 'max' in request.amountQuery || + 'maxExchangeAmount' in request.amountQuery const exchangeAmount = - 'amount' in request.exchangeAmount ? request.exchangeAmount.amount : '' + `exchangeAmount` in request.amountQuery + ? request.amountQuery.exchangeAmount + : '' const maxAmountLimit = - 'max' in request.exchangeAmount && - typeof request.exchangeAmount.max === 'string' - ? request.exchangeAmount.max + 'maxExchangeAmount' in request.amountQuery + ? request.amountQuery.maxExchangeAmount : undefined // Validate direction