Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions frontend/src/components/Ramp/Offramp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { RampTerms } from '../../RampTerms';
import { useValidateTerms } from '../../../stores/termsStore';
import { useRampModalActions } from '../../../stores/rampModalStore';
import { useInputAmount, useOnChainToken, useFiatToken } from '../../../stores/ramp/useRampFormStore';
import { useRampUrlParams } from '../../../hooks/useRampUrlParams';
import { useSetRampUrlParams } from '../../../hooks/useRampUrlParams';
import { RampFeeCollapse } from '../../RampFeeCollapse';
import { RampSubmitButtons } from '../../RampSubmitButtons';
import { useQuoteService } from '../../../hooks/ramp/useQuoteService';
Expand All @@ -44,7 +44,7 @@ export const Offramp = () => {
}, [toAmount, form]);

const { getCurrentErrorMessage } = useRampValidation();
const initializeFailedMessage = useInitializeFailedMessage()
const initializeFailedMessage = useInitializeFailedMessage();
const { onRampConfirm } = useRampSubmission();
const validateTerms = useValidateTerms();

Expand All @@ -58,7 +58,7 @@ export const Offramp = () => {
const fromToken = getOnChainTokenDetailsOrDefault(selectedNetwork, onChainToken);
const toToken = getAnyFiatTokenDetails(fiatToken);

useRampUrlParams({ form });
useSetRampUrlParams();

useEffect(() => {
if (!fromAmountFieldTouched || debouncedInputAmount !== inputAmount) return;
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/components/Ramp/Onramp/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { RampTerms } from '../../RampTerms';
import { useValidateTerms } from '../../../stores/termsStore';
import { useRampModalActions } from '../../../stores/rampModalStore';
import { useInputAmount, useOnChainToken, useFiatToken } from '../../../stores/ramp/useRampFormStore';
import { useRampUrlParams } from '../../../hooks/useRampUrlParams';
import { useSetRampUrlParams } from '../../../hooks/useRampUrlParams';
import { RampFeeCollapse } from '../../RampFeeCollapse';
import { RampSubmitButtons } from '../../RampSubmitButtons';
import { useInitializeFailedMessage } from '../../../stores/rampStore';
Expand All @@ -45,7 +45,7 @@ export const Onramp = () => {
}, [toAmount, form]);

const { getCurrentErrorMessage } = useRampValidation();
const initializeFailedMessage = useInitializeFailedMessage()
const initializeFailedMessage = useInitializeFailedMessage();
const validateTerms = useValidateTerms();
const { onRampConfirm } = useRampSubmission();

Expand All @@ -59,7 +59,7 @@ export const Onramp = () => {
const fromToken = getAnyFiatTokenDetails(fiatToken);
const toToken = getOnChainTokenDetailsOrDefault(selectedNetwork, onChainToken);

useRampUrlParams({ form });
useSetRampUrlParams();

useEffect(() => {
if (!fromAmountFieldTouched || debouncedInputAmount !== inputAmount) return;
Expand Down
24 changes: 6 additions & 18 deletions frontend/src/contexts/network.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,7 @@ import { WALLETCONNECT_ASSETHUB_ID } from '../constants/constants';
import { useRampActions } from '../stores/rampStore';
import { getNetworkId, isNetworkEVM, Networks } from 'shared';
import { useSep24Actions } from '../stores/sep24Store';

const getParamsNetwork = () => {
const params = new URLSearchParams(window.location.search);
const networkParam = params.get('network')?.toLowerCase();

if (networkParam) {
const matchedNetwork = Object.values(Networks).find((network) => network.toLowerCase() === networkParam);

if (matchedNetwork) {
return matchedNetwork;
}
}
return null;
};
import { useRampUrlParams } from '../hooks/useRampUrlParams';

interface NetworkContextType {
walletConnectPolkadotSelectedNetworkId: string;
Expand All @@ -43,14 +30,15 @@ interface NetworkProviderProps {
export const NetworkProvider = ({ children }: NetworkProviderProps) => {
const { state: selectedNetworkLocalStorageState, set: setSelectedNetworkLocalStorage } = useLocalStorage<Networks>({
key: LocalStorageKeys.SELECTED_NETWORK,
defaultValue: Networks.AssetHub,
defaultValue: Networks.Polygon,
});

const { network } = useRampUrlParams();

// We do this to ensure that the local storage value is always in lowercase. Previously the first letter was uppercase
const selectedNetworkLocalStorage = selectedNetworkLocalStorageState.toLowerCase() as Networks;

const paramsNetwork = getParamsNetwork();

const [selectedNetwork, setSelectedNetworkState] = useState<Networks>(paramsNetwork || selectedNetworkLocalStorage);
const [selectedNetwork, setSelectedNetworkState] = useState<Networks>(network || selectedNetworkLocalStorage);
const [networkSelectorDisabled, setNetworkSelectorDisabled] = useState(false);

const { resetRampState } = useRampActions();
Expand Down
7 changes: 7 additions & 0 deletions frontend/src/hooks/offramp/useRampService/useRegisterRamp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ export const useRegisterRamp = () => {
// Check if we can proceed with the registration process
const lockResult = checkLock();
if (!lockResult.canProceed) {
// Alternatively release locks if process was cancelled
// This will NOT clean the localStorage right after the process is cancelled
// but rather on the first checkLock() call after confirmation.
if (!rampStarted){
releaseSigningLock();
releaseLock();
}
return;
}

Expand Down
2 changes: 0 additions & 2 deletions frontend/src/hooks/ramp/useRampForm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ export const useRampForm = (): {
defaultValues: DEFAULT_RAMP_FORM_VALUES,
});

console.log('form', form.formState.errors);

const taxId = useTaxId();
const pixId = usePixId();
const inputAmount = useInputAmount();
Expand Down
138 changes: 117 additions & 21 deletions frontend/src/hooks/useRampUrlParams.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,124 @@
import { useEffect } from 'react';
import { UseFormReturn } from 'react-hook-form';
import { FiatToken } from 'shared';
import { RampFormValues } from './ramp/schema';
import { useEffect, useMemo, useRef } from 'react';
import { RampDirection } from '../components/RampToggle';
import { Networks, AssetHubToken, EvmToken, FiatToken, OnChainToken } from 'shared';
import { useRampDirectionToggle } from '../stores/rampDirectionStore';
import { useRampFormStoreActions } from '../stores/ramp/useRampFormStore';

interface UseRampUrlParamsProps {
form: UseFormReturn<RampFormValues, unknown, undefined>;
interface RampUrlParams {
ramp: RampDirection;
network?: Networks;
to?: string;
from?: string;
fromAmount?: string;
}

const defaultFiatTokenAmounts: Record<FiatToken, number> = { eurc: 20, ars: 20, brl: 5 };
function findFiatToken(fiatToken?: string): FiatToken | undefined {
if (!fiatToken) {
return undefined;
}

export const useRampUrlParams = ({ form }: UseRampUrlParamsProps) => {
useEffect(() => {
const params = new URLSearchParams(window.location.search);
const fiatTokenEntries = Object.entries(FiatToken);
const matchedFiatToken = fiatTokenEntries.find(([_, token]) => token.toLowerCase() === fiatToken);

if (!matchedFiatToken) {
return undefined;
}

const [_, tokenValue] = matchedFiatToken;

return tokenValue as FiatToken;
}

function findOnChainToken(tokenStr?: string, networkType?: Networks | string): OnChainToken | undefined {
if (!tokenStr || !networkType) {
return undefined;
}

const isAssetHub = networkType === Networks.AssetHub;

if (isAssetHub) {
const assetHubTokenEntries = Object.entries(AssetHubToken);
const matchedToken = assetHubTokenEntries.find(([_, token]) => token.toLowerCase() === tokenStr);

if (!matchedToken) {
return undefined;
}

const [_, tokenValue] = matchedToken;
return tokenValue as unknown as OnChainToken;
} else {
const evmTokenEntries = Object.entries(EvmToken);
const matchedToken = evmTokenEntries.find(([_, token]) => token.toLowerCase() === tokenStr);

if (!matchedToken) {
return undefined;
}

const [_, tokenValue] = matchedToken;
return tokenValue as OnChainToken;
}
}

function getNetworkFromParam(param?: string): Networks | undefined {
if (param) {
const matchedNetwork = Object.values(Networks).find((network) => network.toLowerCase() === param);
return matchedNetwork;
}
return undefined;
}

export const useRampUrlParams = (): RampUrlParams => {
const params = useMemo(() => new URLSearchParams(window.location.search), []);

const urlParams = useMemo(() => {
const rampParam = params.get('ramp')?.toLowerCase();
const networkParam = params.get('network')?.toLowerCase();
const toTokenParam = params.get('to')?.toLowerCase();
const fromTokenParam = params.get('from')?.toLowerCase();
const inputAmountParam = params.get('fromAmount');
const fiatToken = form.getValues('fiatToken');

if (inputAmountParam) {
const parsedAmount = Number(inputAmountParam);
if (Number.isFinite(parsedAmount) && !isNaN(parsedAmount) && parsedAmount >= 0) {
form.setValue('inputAmount', parsedAmount.toFixed(2));
}
} else if (fiatToken) {
const defaultAmount = defaultFiatTokenAmounts[fiatToken as FiatToken];
form.setValue('inputAmount', defaultAmount.toFixed(2));

const ramp = rampParam === 'buy' ? RampDirection.ONRAMP : RampDirection.OFFRAMP;

return {
ramp,
network: getNetworkFromParam(networkParam),
to: ramp === RampDirection.OFFRAMP ? findFiatToken(toTokenParam) : findOnChainToken(toTokenParam, networkParam),
from:
ramp === RampDirection.OFFRAMP ? findOnChainToken(fromTokenParam, networkParam) : findFiatToken(fromTokenParam),
fromAmount: inputAmountParam || undefined,
};
}, [params]);

return urlParams;
};

export const useSetRampUrlParams = () => {
const { ramp, to, from, fromAmount } = useRampUrlParams();

const onToggle = useRampDirectionToggle();

const { setFiatToken, setOnChainToken, setInputAmount } = useRampFormStoreActions();

const hasInitialized = useRef(false);

useEffect(() => {
if (hasInitialized.current) return;

onToggle(ramp);

if (to) {
ramp === RampDirection.OFFRAMP ? setFiatToken(to as FiatToken) : setOnChainToken(to as OnChainToken);
}
}, [form]);

if (from) {
ramp === RampDirection.OFFRAMP ? setOnChainToken(from as OnChainToken) : setFiatToken(from as FiatToken);
}

if (fromAmount) {
setInputAmount(fromAmount);
}

hasInitialized.current = true;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []); // Empty dependency array means run once on mount
};
Loading