diff --git a/dapp/src/hooks/index.ts b/dapp/src/hooks/index.ts index 9584fa5eb..28bc42703 100644 --- a/dapp/src/hooks/index.ts +++ b/dapp/src/hooks/index.ts @@ -27,7 +27,6 @@ export { default as useMobileMode } from "./useMobileMode" export { default as useBitcoinRecoveryAddress } from "./useBitcoinRecoveryAddress" export { default as useIsFetchedWalletData } from "./useIsFetchedWalletData" export { default as useLocalStorage } from "./useLocalStorage" -export { default as useDetectReferral } from "./useDetectReferral" export { default as useReferral } from "./useReferral" export { default as useMats } from "./useMats" export { default as useIsEmbed } from "./useIsEmbed" diff --git a/dapp/src/hooks/useDetectReferral.ts b/dapp/src/hooks/useDetectReferral.ts deleted file mode 100644 index e32a457b6..000000000 --- a/dapp/src/hooks/useDetectReferral.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { useEffect } from "react" -import useReferral from "./useReferral" - -export default function useDetectReferral() { - const { detectReferral } = useReferral() - - useEffect(() => { - detectReferral() - }, [detectReferral]) -} diff --git a/dapp/src/hooks/useInitApp.ts b/dapp/src/hooks/useInitApp.ts index e87e8955a..caf792595 100644 --- a/dapp/src/hooks/useInitApp.ts +++ b/dapp/src/hooks/useInitApp.ts @@ -4,7 +4,6 @@ import { useAccountsChangedOKX } from "./orangeKit/useAccountsChangedOKX" import { useInitDataFromSdk, useInitializeAcreSdk } from "./sdk" import { useSentry } from "./sentry" import useDetectEmbed from "./useDetectEmbed" -import useDetectReferral from "./useDetectReferral" import { useDisconnectWallet } from "./useDisconnectWallet" import { useFetchBTCPriceUSD } from "./useFetchBTCPriceUSD" @@ -13,7 +12,6 @@ export function useInitApp() { // useDetectThemeMode() useSentry() useDetectEmbed() - useDetectReferral() useInitializeAcreSdk() useInitDataFromSdk() useFetchBTCPriceUSD() diff --git a/dapp/src/hooks/useLocalStorage.ts b/dapp/src/hooks/useLocalStorage.ts index d3d03e990..73272cecd 100644 --- a/dapp/src/hooks/useLocalStorage.ts +++ b/dapp/src/hooks/useLocalStorage.ts @@ -1,4 +1,7 @@ -import { useLocalStorage as useRehooksLocalStorage } from "@rehooks/local-storage" +import { + useLocalStorage as useRehooksLocalStorage, + writeStorage, +} from "@rehooks/local-storage" export const parseLocalStorageValue = (value: string | null | undefined) => { if ( @@ -12,6 +15,8 @@ export const parseLocalStorageValue = (value: string | null | undefined) => { return value } +export { writeStorage } + export const getLocalStorageItem = (key: string): string | undefined => { const value = localStorage.getItem(key) return parseLocalStorageValue(value) diff --git a/dapp/src/hooks/useReferral.ts b/dapp/src/hooks/useReferral.ts index d919850e9..4e6f7566c 100644 --- a/dapp/src/hooks/useReferral.ts +++ b/dapp/src/hooks/useReferral.ts @@ -1,52 +1,23 @@ import { env } from "#/constants" -import { referralProgram } from "#/utils" - import { useCallback, useMemo } from "react" -import { MODAL_TYPES } from "#/types" -import useIsEmbed from "./useIsEmbed" -import useLocalStorage from "./useLocalStorage" -import { useModal } from "./useModal" +import useLocalStorage, { writeStorage } from "./useLocalStorage" type UseReferralReturn = { referral: number | null - detectReferral: () => void resetReferral: () => void } +const LOCAL_STORAGE_KEY = "acre.referral" + +export const writeReferral = (value: string) => { + writeStorage(LOCAL_STORAGE_KEY, value) +} + export default function useReferral(): UseReferralReturn { const [referral, setReferral] = useLocalStorage( - "acre.referral", + LOCAL_STORAGE_KEY, env.REFERRAL, ) - const { openModal } = useModal() - const { isEmbed, embeddedApp } = useIsEmbed() - - const detectReferral = useCallback(() => { - const param = referralProgram.getReferralFromURL() - - if (isEmbed && embeddedApp) { - setReferral(referralProgram.getReferralByEmbeddedApp(embeddedApp)) - return - } - - if (param === null) { - setReferral(env.REFERRAL) - return - } - - const convertedReferral = Number(param) - - if (referralProgram.isValidReferral(convertedReferral)) { - setReferral(convertedReferral) - } else { - console.error("Incorrect referral") - setReferral(null) - openModal(MODAL_TYPES.UNEXPECTED_ERROR, { - withCloseButton: false, - closeOnEsc: false, - }) - } - }, [isEmbed, embeddedApp, openModal, setReferral]) const resetReferral = useCallback(() => { setReferral(env.REFERRAL) @@ -54,10 +25,9 @@ export default function useReferral(): UseReferralReturn { return useMemo( () => ({ - detectReferral, resetReferral, referral, }), - [detectReferral, resetReferral, referral], + [resetReferral, referral], ) } diff --git a/dapp/src/router/index.tsx b/dapp/src/router/index.tsx index 9d6a42b0f..351a8504e 100644 --- a/dapp/src/router/index.tsx +++ b/dapp/src/router/index.tsx @@ -12,6 +12,8 @@ import AccessPage from "#/pages/AccessPage" import WelcomePage from "#/pages/WelcomePage" import welcomePageLoader from "#/pages/WelcomePage/loader" import accessPageLoader from "#/pages/AccessPage/loader" +import { writeReferral } from "#/hooks/useReferral" +import { env } from "#/constants" import { routerPath } from "./path" const mainLayoutLoader: LoaderFunction = ({ request }) => { @@ -32,6 +34,24 @@ export const router = createBrowserRouter([ { path: "/", element: , + loader: ({ request }) => { + // TODO: display the error page/modal when the referral is invalid. + const referralCodeFromUrl = referralProgram.getReferralFromURL() + + const referralCode = referralProgram.isValidReferral(referralCodeFromUrl) + ? referralCodeFromUrl! + : env.REFERRAL + + writeReferral(referralCode.toString()) + + const embedApp = referralProgram.getEmbeddedApp(request.url) + if (referralProgram.isEmbedApp(embedApp)) { + writeReferral( + referralProgram.getReferralByEmbeddedApp(embedApp).toString(), + ) + } + return null + }, children: [ { index: true, diff --git a/dapp/src/utils/referralProgram.ts b/dapp/src/utils/referralProgram.ts index 36f48b9a3..82a3bfbc5 100644 --- a/dapp/src/utils/referralProgram.ts +++ b/dapp/src/utils/referralProgram.ts @@ -9,9 +9,23 @@ const EMBEDDED_APP_TO_REFERRAL: Record = { "ledger-live": 2083, } -const isValidReferral = (value: number) => { - const isInteger = Number.isInteger(value) - return isInteger && value >= 0 && value <= MAX_UINT16 +const isValidReferral = (value: unknown) => { + let valueAsNumber: number | undefined + + if (typeof value === "string") { + // Only digits w/o leading zeros. + const isNumber = /^(?:[1-9][0-9]*|0)$/.test(value) + valueAsNumber = isNumber ? Number(value) : undefined + } else if (typeof value === "number") { + valueAsNumber = value + } + + return ( + !!valueAsNumber && + Number.isInteger(valueAsNumber) && + valueAsNumber >= 0 && + valueAsNumber <= MAX_UINT16 + ) } const getReferralFromURL = () =>