Skip to content

Create new production release #615

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
May 2, 2025
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export class BrlaTeleportPhaseHandler extends BasePhaseHandler {

// Add delay to ensure the transaction is settled
await new Promise((resolve) => setTimeout(resolve, 12000)); // 12 seconds, 2 moonbeam blocks.

} catch (balanceCheckError) {
if (balanceCheckError instanceof Error) {
if (balanceCheckError.message === 'Balance did not meet the limit within the specified time') {
Expand Down
4 changes: 2 additions & 2 deletions api/src/api/services/ramp/quote.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ import { calculateTotalReceive, calculateTotalReceiveOnramp } from '../../helper
import { createOnrampRouteParams, getRoute } from '../transactions/squidrouter/route';
import { parseContractBalanceResponse, stringifyBigWithSignificantDecimals } from '../../helpers/contracts';
import { MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS, MOONBEAM_EPHEMERAL_STARTING_BALANCE_UNITS_ETHEREUM } from '../../../constants/constants';
import { multiplyByPowerOfTen } from '../../services/pendulum/helpers';
import { multiplyByPowerOfTen } from "../pendulum/helpers";
/**
* Trims trailing zeros from a decimal string, keeping at least two decimal places.
* @param decimalString - The decimal string to format
* @returns Formatted string with unnecessary trailing zeros removed but at least two decimal places
*/
function trimTrailingZeros(decimalString: string): string {
if (!decimalString.includes('.')) {
if (!decimalString?.includes('.')) {
return `${decimalString}.00`;
}

Expand Down
15 changes: 10 additions & 5 deletions frontend/src/components/AssetNumericInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface AssetNumericInputProps {
onChange?: (e: ChangeEvent) => void;
disabled?: boolean;
readOnly?: boolean;
loading?: boolean;
registerInput: UseFormRegisterReturn<keyof RampFormValues>;
id: string;
}
Expand All @@ -35,10 +36,14 @@ export const AssetNumericInput: FC<AssetNumericInputProps> = ({
<AssetButton disabled={rest.disabled} assetIcon={assetIcon} tokenSymbol={tokenSymbol} onClick={onClick} />
</div>

<NumericInput
register={registerInput}
additionalStyle={cn('text-right text-lg', rest.readOnly && 'text-xl')}
{...rest}
/>
{rest.loading ? (
<div className="loading loading-bars loading-md ml-auto mr-4"></div>
) : (
<NumericInput
register={registerInput}
additionalStyle={cn('text-right text-lg', rest.readOnly && 'text-xl')}
{...rest}
/>
)}
</div>
);
6 changes: 5 additions & 1 deletion frontend/src/components/Ramp/Offramp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { RampSubmitButtons } from '../../RampSubmitButtons';
import { useQuoteService } from '../../../hooks/ramp/useQuoteService';
import { useTranslation } from 'react-i18next';
import { useInitializeFailedMessage } from '../../../stores/rampStore';
import { useQuoteLoading } from '../../../stores/ramp/useQuoteStore';

export const Offramp = () => {
const { t } = useTranslation();
Expand All @@ -37,6 +38,8 @@ export const Offramp = () => {
const debouncedInputAmount = useDebouncedValue(inputAmount, 1000);
const { outputAmount: toAmount } = useQuoteService(debouncedInputAmount, onChainToken, fiatToken);

const quoteLoading = useQuoteLoading();

// TODO: This is a hack to get the output amount to the form
useEffect(() => {
form.setValue('outputAmount', toAmount?.toString() || '0');
Expand Down Expand Up @@ -96,13 +99,14 @@ export const Offramp = () => {
assetIcon={toToken.fiat.assetIcon}
tokenSymbol={toToken.fiat.symbol}
onClick={() => openTokenSelectModal('to')}
loading={quoteLoading}
registerInput={form.register('outputAmount')}
disabled={!toAmount}
readOnly={true}
id="outputAmount"
/>
),
[toToken.fiat.assetIcon, toToken.fiat.symbol, form, toAmount, openTokenSelectModal],
[toToken.fiat.assetIcon, toToken.fiat.symbol, quoteLoading, form, toAmount, openTokenSelectModal],
);

const handleConfirm = useCallback(() => {
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/components/Ramp/Onramp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { useInputAmount, useOnChainToken, useFiatToken } from '../../../stores/r
import { RampFeeCollapse } from '../../RampFeeCollapse';
import { RampSubmitButtons } from '../../RampSubmitButtons';
import { useInitializeFailedMessage } from '../../../stores/rampStore';
import { useQuoteLoading } from '../../../stores/ramp/useQuoteStore';

export const Onramp = () => {
const { t } = useTranslation();
Expand All @@ -33,6 +34,7 @@ export const Onramp = () => {
const inputAmount = useInputAmount();
const onChainToken = useOnChainToken();
const fiatToken = useFiatToken();
const quoteLoading = useQuoteLoading();

const debouncedInputAmount = useDebouncedValue(inputAmount, 1000);

Expand Down Expand Up @@ -95,12 +97,13 @@ export const Onramp = () => {
tokenSymbol={toToken.assetSymbol}
onClick={() => openTokenSelectModal('to')}
registerInput={form.register('outputAmount')}
loading={quoteLoading}
disabled={!toAmount}
readOnly={true}
id="outputAmount"
/>
),
[toToken, form, toAmount, openTokenSelectModal],
[toToken.networkAssetIcon, toToken.assetSymbol, form, quoteLoading, toAmount, openTokenSelectModal],
);

const handleConfirm = useCallback(() => {
Expand Down
13 changes: 10 additions & 3 deletions frontend/src/components/RampSubmitButtons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { useRampDirection } from '../../stores/rampDirectionStore';
import { RampDirection } from '../RampToggle';
import { useTranslation } from 'react-i18next';
import { useWidgetMode } from '../../hooks/useWidgetMode';
import { useQuoteStore } from '../../stores/ramp/useQuoteStore';


interface RampSubmitButtonsProps {
toAmount?: Big;
Expand All @@ -24,12 +26,16 @@ export const RampSubmitButtons: FC<RampSubmitButtonsProps> = ({ toAmount }) => {
const executionInput = useRampExecutionInput()
const initializeFailedMessage = useInitializeFailedMessage();
const isRampSummaryDialogVisible = useRampSummaryVisible();
const inputAmount = useInputAmount();
const fiatToken = useFiatToken();
const onChainToken = useOnChainToken();
const rampDirection = useRampDirection();
const isWidgetMode = useWidgetMode();


const inputAmount = useInputAmount();
const { quote } = useQuoteStore();
const quoteInputAmount = quote?.inputAmount;

const handleCompareFeesClick = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
Expand All @@ -55,8 +61,9 @@ export const RampSubmitButtons: FC<RampSubmitButtonsProps> = ({ toAmount }) => {
return t('components.swapSubmitButton.confirm');
};

const isSubmitButtonDisabled = Boolean(getCurrentErrorMessage()) || !toAmount || !!initializeFailedMessage;
const isSubmitButtonPending = isRampSummaryDialogVisible || Boolean(executionInput);
const isQuoteOutdated = !!quoteInputAmount && !!inputAmount && !(Big(quoteInputAmount).eq(Big(inputAmount)))
const isSubmitButtonDisabled = Boolean(getCurrentErrorMessage()) || !toAmount || !!initializeFailedMessage || isQuoteOutdated;
const isSubmitButtonPending = isRampSummaryDialogVisible || Boolean(executionInput) || isQuoteOutdated;

return (
<div className="flex gap-3 mt-5">
Expand Down
6 changes: 2 additions & 4 deletions frontend/src/hooks/ramp/useRampValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,15 +136,15 @@ function validateOfframp(
function validateTokenAvailability(
t: TFunction<'translation', undefined>,
fiatToken: FiatToken,
trackEvent: (event: TrackableEvent) => void
trackEvent: (event: TrackableEvent) => void,
): string | null {
if (isFiatTokenDisabled(fiatToken)) {
const reason = getTokenDisabledReason(fiatToken);
trackEvent({
event: 'token_unavailable',
token: fiatToken,
});
return t(reason)
return t(reason);
}
return null;
}
Expand Down Expand Up @@ -201,13 +201,11 @@ export const useRampValidation = () => {
}

if (validationError) return validationError;
if (quoteLoading) return t('components.swap.validation.calculatingQuote');

return null;
}, [
isDisconnected,
isOnramp,
quoteLoading,
t,
inputAmount,
fromToken,
Expand Down
15 changes: 14 additions & 1 deletion frontend/src/sections/FeeComparison/index.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import { useTranslation, Trans } from 'react-i18next';
import { Trans, useTranslation } from 'react-i18next';

import { FeeComparisonTable } from './FeeComparisonTable';

import { useFeeComparisonStore } from '../../stores/feeComparison';
import { useEffect, useRef } from 'react';
import { useRampDirection } from '../../stores/rampDirectionStore';
import { RampDirection } from '../../components/RampToggle';

export const FeeComparison = () => {
const ref = useRef<HTMLDivElement>(null);
const { t } = useTranslation();
const { setFeeComparisonRef } = useFeeComparisonStore();
const rampDirecton = useRampDirection();

useEffect(() => {
setFeeComparisonRef(ref);
}, [setFeeComparisonRef]);

if (rampDirecton === RampDirection.ONRAMP) {
// We don't want to show the fee comparison section on the onramp page for now
return (
<section
ref={ref}
className="py-4 mt-10 mb-24 bg-[radial-gradient(at_74%_98%,theme(colors.blue.900),theme(colors.blue.950),theme(colors.blue.950))]"
/>
);
}

return (
<section
ref={ref}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@
"components": {
"airdropBanner": {
"title": "Special offer",
"description": "Deposit R$5 or €10 to Get 20 USDT for FREE!",
"description": "Buy or Sell just R$5 or €10 - get 20 USDT for FREE",
"button": "More info",
"list": {
"1": "Buy or sell from just R$5 (PIX) or €10 (SEPA) - quick, easy, and no hidden fees.",
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/translations/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@
"components": {
"airdropBanner": {
"title": "Oferta especial",
"description": "Deposite R$5 ou €10 para receber 20 USDT de graça!",
"description": "Compre ou venda apenas R$5 ou €10 - receba 20 USDT de graça!",
"button": "Mais informações",
"list": {
"1": "Compre ou venda de R$5 (PIX) ou €10 (SEPA) - rápido, fácil e sem taxas ocultas.",
Expand Down
Loading