diff --git a/dapp/.env b/dapp/.env index fdb71b35d..977362387 100644 --- a/dapp/.env +++ b/dapp/.env @@ -18,13 +18,17 @@ VITE_GELATO_RELAY_API_KEY="htaJCy_XHj8WsE3w53WBMurfySDtjLP_TrNPPa6IPIc_" # this # Get the API key from: https://thegraph.com/studio/apikeys/. VITE_SUBGRAPH_API_KEY="" +# Posthog +VITE_POSTHOG_API_HOST="https://us.i.posthog.com" +VITE_POSTHOG_API_KEY="" + # Feature flags -VITE_FEATURE_FLAG_GAMIFICATION_ENABLED="false" VITE_FEATURE_FLAG_WITHDRAWALS_ENABLED="false" VITE_FEATURE_FLAG_OKX_WALLET_ENABLED="false" VITE_FEATURE_FLAG_XVERSE_WALLET_ENABLED="false" VITE_FEATURE_FLAG_ACRE_POINTS_ENABLED="true" VITE_FEATURE_FLAG_TVL_ENABLED="true" VITE_FEATURE_GATING_DAPP_ENABLED="true" +VITE_FEATURE_POSTHOG_ENABLED="true" VITE_FEATURE_MOBILE_MODE_ENABLED="true" diff --git a/dapp/package.json b/dapp/package.json index b384d7b43..3e094674f 100644 --- a/dapp/package.json +++ b/dapp/package.json @@ -40,6 +40,7 @@ "framer-motion": "^10.16.5", "luxon": "^3.5.0", "mustache": "^4.2.0", + "posthog-js": "^1.186.1", "react": "^18.2.0", "react-confetti-explosion": "^2.1.2", "react-dom": "^18.2.0", diff --git a/dapp/src/DApp.tsx b/dapp/src/DApp.tsx index 31255b53d..1fd0809c7 100644 --- a/dapp/src/DApp.tsx +++ b/dapp/src/DApp.tsx @@ -10,7 +10,7 @@ import GlobalStyles from "./components/GlobalStyles" import { DocsDrawerContextProvider, SidebarContextProvider, - WalletConnectionErrorContextProvider, + WalletConnectionAlertContextProvider, } from "./contexts" import { useInitApp } from "./hooks" import { router } from "./router" @@ -19,6 +19,7 @@ import getWagmiConfig from "./wagmiConfig" import queryClient from "./queryClient" import { delay, logPromiseFailure } from "./utils" import { AcreLogo } from "./assets/icons" +import PostHogProvider from "./posthog/PostHogProvider" function SplashPage() { return ( @@ -67,11 +68,13 @@ function DAppProviders() { - + - + + + - + diff --git a/dapp/src/assets/images/benefits/bibos-beehive.svg b/dapp/src/assets/images/benefits/bibos-beehive.svg deleted file mode 100644 index 784888e3c..000000000 --- a/dapp/src/assets/images/benefits/bibos-beehive.svg +++ /dev/null @@ -1,60 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dapp/src/assets/images/benefits/index.ts b/dapp/src/assets/images/benefits/index.ts deleted file mode 100644 index 072363998..000000000 --- a/dapp/src/assets/images/benefits/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export { default as rewardsBoostImage } from "#/assets/images/benefits/rewards-boost.svg" -export { default as seasonKeyImage } from "#/assets/images/benefits/season-key.svg" -export { default as rewardsBoostArrowImage } from "#/assets/images/benefits/rewards-boost-arrow.svg" -export { default as bibosBeehiveImage } from "#/assets/images/benefits/bibos-beehive.svg" diff --git a/dapp/src/assets/images/benefits/rewards-boost-arrow.svg b/dapp/src/assets/images/benefits/rewards-boost-arrow.svg deleted file mode 100644 index b8cb985cf..000000000 --- a/dapp/src/assets/images/benefits/rewards-boost-arrow.svg +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/dapp/src/assets/images/benefits/rewards-boost.svg b/dapp/src/assets/images/benefits/rewards-boost.svg deleted file mode 100644 index 70d7f5144..000000000 --- a/dapp/src/assets/images/benefits/rewards-boost.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/dapp/src/assets/images/benefits/season-key.svg b/dapp/src/assets/images/benefits/season-key.svg deleted file mode 100644 index e40917ff3..000000000 --- a/dapp/src/assets/images/benefits/season-key.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletAlert.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletAlert.tsx new file mode 100644 index 000000000..553d9ff56 --- /dev/null +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletAlert.tsx @@ -0,0 +1,99 @@ +import React from "react" +import { Box, Link, VStack } from "@chakra-ui/react" +import { AnimatePresence, Variants, motion } from "framer-motion" +import { EXTERNAL_HREF } from "#/constants" +import { + Alert, + AlertDescription, + AlertTitle, + AlertIcon, + AlertProps, +} from "../shared/Alert" + +export enum ConnectionAlert { + Rejected = "REJECTED", + NotSupported = "NOT_SUPPORTED", + NetworkMismatch = "NETWORK_MISMATCH", + InvalidSIWWSignature = "INVALID_SIWW_SIGNATURE", + Default = "DEFAULT", +} + +function ContactSupport() { + return ( + + If the problem persists, contact{" "} + + Acre support + + . + + ) +} + +const CONNECTION_ALERTS = { + [ConnectionAlert.Rejected]: { + title: "Wallet connection rejected.", + description: "If you encountered an error, please try again.", + }, + [ConnectionAlert.NotSupported]: { + title: "Not supported.", + description: + "Only Native SegWit, Nested SegWit, or Legacy addresses are supported. Please use a compatible address or switch to a different wallet.", + }, + [ConnectionAlert.NetworkMismatch]: { + title: "Incorrect network detected in your wallet.", + description: + "Please connect your wallet to the correct Bitcoin network and try again.", + }, + [ConnectionAlert.Default]: { + title: "Wallet connection failed. Please try again.", + description: , + }, + [ConnectionAlert.InvalidSIWWSignature]: { + title: "Invalid sign-in signature. Please try again.", + description: , + }, +} + +const collapseVariants: Variants = { + collapsed: { height: 0 }, + expanded: { height: "auto" }, +} + +type ConnectWalletAlertProps = AlertProps & { type?: ConnectionAlert } + +export default function ConnectWalletAlert(props: ConnectWalletAlertProps) { + const { type, status, ...restProps } = props + + const data = type ? CONNECTION_ALERTS[type] : undefined + + return ( + + {data && ( + + + + + {data.title} + {data.description} + + + + )} + + ) +} diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx index 0747fdc8e..b950b2b2c 100644 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx +++ b/dapp/src/components/ConnectWalletModal/ConnectWalletButton.tsx @@ -1,12 +1,12 @@ import React, { useCallback, useEffect, useRef, useState } from "react" -import { CONNECTION_ERRORS, ONE_SEC_IN_MILLISECONDS } from "#/constants" +import { ONE_SEC_IN_MILLISECONDS } from "#/constants" import { useAppDispatch, useIsEmbed, useModal, useSignMessageAndCreateSession, useWallet, - useWalletConnectionError, + useWalletConnectionAlert, } from "#/hooks" import { setIsSignedMessage } from "#/store/wallet" import { OrangeKitConnector, OrangeKitError, OnSuccessCallback } from "#/types" @@ -24,10 +24,12 @@ import { } from "@chakra-ui/react" import { IconArrowNarrowRight } from "@tabler/icons-react" import { AnimatePresence, Variants, motion } from "framer-motion" +import { usePostHogIdentity } from "#/hooks/posthog" import ArrivingSoonTooltip from "../ArrivingSoonTooltip" import { TextLg, TextMd } from "../shared/Typography" import ConnectWalletStatusLabel from "./ConnectWalletStatusLabel" import Spinner from "../shared/Spinner" +import { ConnectionAlert } from "./ConnectWalletAlert" type ConnectWalletButtonProps = { label: string @@ -66,15 +68,16 @@ export default function ConnectWalletButton({ } = useWallet() const { signMessageStatus, resetMessageStatus, signMessageAndCreateSession } = useSignMessageAndCreateSession() - const { connectionError, setConnectionError, resetConnectionError } = - useWalletConnectionError() + const { type, setConnectionAlert, resetConnectionAlert } = + useWalletConnectionAlert() const { closeModal } = useModal() const dispatch = useAppDispatch() const isMounted = useRef(false) + const { handleIdentification } = usePostHogIdentity() const [isLoading, setIsLoading] = useState(false) - const hasConnectionError = connectionError || connectionStatus === "error" + const hasConnectionError = type || connectionStatus === "error" const hasSignMessageErrorStatus = signMessageStatus === "error" const shouldShowStatuses = isSelected && !hasConnectionError const shouldShowRetryButton = address && hasSignMessageErrorStatus @@ -99,14 +102,14 @@ export default function ConnectWalletButton({ onDisconnect() console.error("Failed to sign siww message", error) - setConnectionError(CONNECTION_ERRORS.INVALID_SIWW_SIGNATURE) + setConnectionAlert(ConnectionAlert.InvalidSIWWSignature) } }, [ signMessageAndCreateSession, onSuccessSignMessage, onDisconnect, - setConnectionError, + setConnectionAlert, ], ) @@ -117,8 +120,11 @@ export default function ConnectWalletButton({ if (!btcAddress) return await handleSignMessageAndCreateSession(connector, btcAddress) + handleIdentification(btcAddress, { + connector: connectedConnector.id, + }) }, - [connector, handleSignMessageAndCreateSession], + [connector, handleSignMessageAndCreateSession, handleIdentification], ) const handleConnection = useCallback(() => { @@ -129,14 +135,19 @@ export default function ConnectWalletButton({ }, onError: (error: OrangeKitError) => { const errorData = orangeKit.parseOrangeKitConnectionError(error) - setConnectionError(errorData) + + if (errorData === ConnectionAlert.Default) { + console.error("Failed to connect", error) + } + + setConnectionAlert(errorData) }, }) }, [ onConnect, connector, onSuccessConnection, - setConnectionError, + setConnectionAlert, isReconnecting, ]) @@ -159,7 +170,7 @@ export default function ConnectWalletButton({ if (shouldShowStatuses) return if (!isReconnecting) onDisconnect() - resetConnectionError() + resetConnectionAlert() resetMessageStatus() const isInstalled = orangeKit.isWalletInstalled(connector) diff --git a/dapp/src/components/ConnectWalletModal/ConnectWalletErrorAlert.tsx b/dapp/src/components/ConnectWalletModal/ConnectWalletErrorAlert.tsx deleted file mode 100644 index 2e97b59ea..000000000 --- a/dapp/src/components/ConnectWalletModal/ConnectWalletErrorAlert.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from "react" -import { Box, VStack } from "@chakra-ui/react" -import { AnimatePresence, Variants, motion } from "framer-motion" -import { ConnectionErrorData } from "#/types" -import { - Alert, - AlertDescription, - AlertTitle, - AlertIcon, - AlertProps, -} from "../shared/Alert" - -type ConnectWalletErrorAlertProps = AlertProps & Partial - -const collapseVariants: Variants = { - collapsed: { height: 0 }, - expanded: { height: "auto" }, -} - -export default function ConnectWalletErrorAlert( - props: ConnectWalletErrorAlertProps, -) { - const { title, description, ...restProps } = props - - const shouldRender = !!(title && description) - - return ( - - {shouldRender && ( - - - - - {title} - {description} - - - - )} - - ) -} diff --git a/dapp/src/components/ConnectWalletModal/index.tsx b/dapp/src/components/ConnectWalletModal/index.tsx index 66816f2be..1653d1e11 100644 --- a/dapp/src/components/ConnectWalletModal/index.tsx +++ b/dapp/src/components/ConnectWalletModal/index.tsx @@ -5,13 +5,13 @@ import { useIsEmbed, useIsSignedMessage, useWallet, - useWalletConnectionError, + useWalletConnectionAlert, } from "#/hooks" import { OrangeKitConnector, BaseModalProps, OnSuccessCallback } from "#/types" import { wallets } from "#/constants" import withBaseModal from "../ModalRoot/withBaseModal" import ConnectWalletButton from "./ConnectWalletButton" -import ConnectWalletErrorAlert from "./ConnectWalletErrorAlert" +import ConnectWalletAlert from "./ConnectWalletAlert" export function ConnectWalletModalBase({ onSuccess, @@ -30,7 +30,7 @@ export function ConnectWalletModalBase({ })) const [selectedConnectorId, setSelectedConnectorId] = useState() - const { connectionError, resetConnectionError } = useWalletConnectionError() + const { type, status, resetConnectionAlert } = useWalletConnectionAlert() const isSignedMessage = useIsSignedMessage() const handleButtonOnClick = (connector: OrangeKitConnector) => { @@ -48,7 +48,7 @@ export function ConnectWalletModalBase({ {withCloseButton && ( { - resetConnectionError() + resetConnectionAlert() if (!isSignedMessage) { onDisconnect() @@ -59,7 +59,7 @@ export function ConnectWalletModalBase({ {`Select your ${isEmbed ? "account" : "wallet"}`} - + {enabledConnectors.map((connector) => ( { openModal(MODAL_TYPES.CONNECT_WALLET, { isReconnecting }) } + const handleDisconnectWallet = () => { + onDisconnect() + resetIdentity() + } + if (!address) { return (