diff --git a/src/components/common/ConnectWallet/WalletDetails.tsx b/src/components/common/ConnectWallet/WalletDetails.tsx index d92f842cfc..e353ae914b 100644 --- a/src/components/common/ConnectWallet/WalletDetails.tsx +++ b/src/components/common/ConnectWallet/WalletDetails.tsx @@ -1,28 +1,12 @@ import { Button, Typography } from '@mui/material' import type { ReactElement } from 'react' -import useOnboard, { connectWallet } from '@/hooks/wallets/useOnboard' -import { OVERVIEW_EVENTS } from '@/services/analytics/events/overview' import KeyholeIcon from '@/components/common/icons/KeyholeIcon' -import { trackEvent } from '@/services/analytics' -import { CodedException } from '@/services/exceptions' import type { ConnectedWallet } from '@/services/onboard' +import useConnectWallet from '@/components/common/ConnectWallet/useConnectWallet' const WalletDetails = ({ onConnect }: { onConnect?: (wallet?: ConnectedWallet) => void }): ReactElement => { - const onboard = useOnboard() - - const handleConnect = async () => { - if (!onboard) return - - // We `trackEvent` instead of using `` as it impedes styling - trackEvent(OVERVIEW_EVENTS.OPEN_ONBOARD) - - const result = await connectWallet(onboard) - - if (result instanceof CodedException) return - - onConnect?.(result) - } + const handleConnect = useConnectWallet(onConnect) return ( <> diff --git a/src/components/common/ConnectWallet/useConnectWallet.ts b/src/components/common/ConnectWallet/useConnectWallet.ts new file mode 100644 index 0000000000..e1ca2acecc --- /dev/null +++ b/src/components/common/ConnectWallet/useConnectWallet.ts @@ -0,0 +1,25 @@ +import useOnboard, { connectWallet } from '@/hooks/wallets/useOnboard' +import { OVERVIEW_EVENTS, trackEvent } from '@/services/analytics' +import { CodedException } from '@/services/exceptions' +import type { ConnectedWallet } from '@/services/onboard' + +const useConnectWallet = (onConnect?: (wallet?: ConnectedWallet) => void) => { + const onboard = useOnboard() + + const handleConnect = async () => { + if (!onboard) return + + // We `trackEvent` instead of using `` as it impedes styling + trackEvent(OVERVIEW_EVENTS.OPEN_ONBOARD) + + const result = await connectWallet(onboard) + + if (result instanceof CodedException) return + + onConnect?.(result) + } + + return handleConnect +} + +export default useConnectWallet diff --git a/src/components/dashboard/CreationDialog/index.tsx b/src/components/dashboard/CreationDialog/index.tsx index 56a828495d..ce583c98fb 100644 --- a/src/components/dashboard/CreationDialog/index.tsx +++ b/src/components/dashboard/CreationDialog/index.tsx @@ -7,6 +7,8 @@ import AppsIcon from '@/public/images/sidebar/apps.svg' import SettingsIcon from '@/public/images/sidebar/settings.svg' import BeamerIcon from '@/public/images/sidebar/whats-new.svg' import HelpCenterIcon from '@/public/images/sidebar/help-center.svg' +import { useRemoteSafeApps } from '@/hooks/safe-apps/useRemoteSafeApps' +import { useCurrentChain } from '@/hooks/useChains' const HintItem = ({ Icon, title, description }: { Icon: ElementType; title: string; description: string }) => { return ( @@ -25,6 +27,8 @@ const HintItem = ({ Icon, title, description }: { Icon: ElementType; title: stri const CreationDialog = () => { const [open, setOpen] = React.useState(true) + const [remoteSafeApps = []] = useRemoteSafeApps() + const chain = useCurrentChain() return ( @@ -33,14 +37,10 @@ const CreationDialog = () => { Welcome to your Safe! - Congratulations on creating the safest wallet in web3. Keep your assets safe and discover our app. + Congratulations on your first step to truly unlock ownership. Enjoy the experience and discover our app. - + { { diff --git a/src/components/new-safe/CreateSafe/index.tsx b/src/components/new-safe/CreateSafe/index.tsx index b37722545a..75335c7686 100644 --- a/src/components/new-safe/CreateSafe/index.tsx +++ b/src/components/new-safe/CreateSafe/index.tsx @@ -39,11 +39,11 @@ const staticHints: Record< steps: [ { title: 'Network fee', - text: 'Deploying your Safe requires the payment of the associated network fee with your connected wallet. An estmation will be provided in the last step.', + text: 'Deploying your Safe requires the payment of the associated network fee with your connected wallet. An estimation will be provided in the last step.', }, { title: 'Address book privacy', - text: 'The name of your Safe will be stored in a local address book and can be changed at a later stage. It will not be shared with us or any third party.', + text: 'The name of your Safe will be stored in a local address book on your device and can be changed at a later stage. It will not be shared with us or any third party.', }, ], }, @@ -53,11 +53,11 @@ const staticHints: Record< steps: [ { title: 'Flat hierarchy', - text: 'Every owner has the same rights within the Safe and can propose, sign and execute transactions.', + text: 'Every owner has the same rights within the Safe and can propose, sign and execute transactions that have the required confirmations.', }, { title: 'Managing Owners', - text: 'You can always change the amount of owners and required confirmations in your Safe at a later stage after creation.', + text: 'You can always change the number of owners and required confirmations in your Safe after creation.', }, { title: 'Safe Setup', @@ -88,7 +88,7 @@ const staticHints: Record< steps: [ { title: 'Wait for the creation', - text: 'Depending on network congestion, it can take some time until the transaction is successfully added to the network and picked up by our services.', + text: 'Depending on network usage, it can take some time until the transaction is successfully added to the blockchain and picked up by our services.', }, ], }, @@ -98,7 +98,7 @@ const staticHints: Record< steps: [ { title: 'Connect your Safe', - text: 'In our Safe Apps section you can connect your Safe to over 70 dApps directly or use Wallet Connect to interact with any application.', + text: 'In our Safe Apps section you can connect your Safe to over 70 dApps directly or via Wallet Connect to interact with any application.', }, ], }, @@ -121,13 +121,13 @@ const CreateSafe = () => { const CreateSafeSteps: TxStepperProps['steps'] = [ { title: 'Connect wallet', - subtitle: 'In order to create a Safe you need to connect a wallet', + subtitle: 'The connected wallet will pay the network fees for the Safe creation.', render: (data, onSubmit, onBack, setStep) => ( ), }, { - title: 'Select network and name Safe', + title: 'Select network and name your Safe', subtitle: 'Select the network on which to create your Safe', render: (data, onSubmit, onBack, setStep) => ( @@ -135,8 +135,7 @@ const CreateSafe = () => { }, { title: 'Owners and confirmations', - subtitle: - 'Here you can add owners to your Safe and determine how many owners need to confirm it before executing a transaction', + subtitle: 'Set the owner wallets of your Safe and how many need to confirm to execute a valid transaction.', render: (data, onSubmit, onBack, setStep) => ( { { title: 'Review', subtitle: - "You're about to create a new Safe and will have to confirm a transaction with your currently connected wallet", + "You're about to create a new Safe and will have to confirm the transaction with your connected wallet.", render: (data, onSubmit, onBack, setStep) => ( ), diff --git a/src/components/new-safe/steps/Step0/index.tsx b/src/components/new-safe/steps/Step0/index.tsx index 8f58ccc0f2..ee2864f922 100644 --- a/src/components/new-safe/steps/Step0/index.tsx +++ b/src/components/new-safe/steps/Step0/index.tsx @@ -1,23 +1,26 @@ import { useEffect } from 'react' -import { Box, Grid } from '@mui/material' +import { Box, Button, Grid, Typography } from '@mui/material' import useWallet from '@/hooks/wallets/useWallet' import { useCurrentChain } from '@/hooks/useChains' import { isPairingSupported } from '@/services/pairing/utils' import type { NewSafeFormData } from '@/components/new-safe/CreateSafe' import type { StepRenderProps } from '@/components/new-safe/CardStepper/useCardStepper' -import WalletDetails from '@/components/common/ConnectWallet/WalletDetails' -import PairingDetails from '@/components/common/PairingDetails' import useSyncSafeCreationStep from '@/components/new-safe/CreateSafe/useSyncSafeCreationStep' import layoutCss from '@/components/new-safe/CreateSafe/styles.module.css' import useLocalStorage from '@/services/local-storage/useLocalStorage' import { type PendingSafeData, SAFE_PENDING_CREATION_STORAGE_KEY } from '@/components/new-safe/steps/Step4' +import useConnectWallet from '@/components/common/ConnectWallet/useConnectWallet' +import KeyholeIcon from '@/components/common/icons/KeyholeIcon' +import PairingDescription from '@/components/common/PairingDetails/PairingDescription' +import PairingQRCode from '@/components/common/PairingDetails/PairingQRCode' const CreateSafeStep0 = ({ onSubmit, setStep }: StepRenderProps) => { const [pendingSafe] = useLocalStorage(SAFE_PENDING_CREATION_STORAGE_KEY) const wallet = useWallet() const chain = useCurrentChain() const isSupported = isPairingSupported(chain?.disabledWallets) + const handleConnect = useConnectWallet() useSyncSafeCreationStep(setStep) useEffect(() => { @@ -31,12 +34,22 @@ const CreateSafeStep0 = ({ onSubmit, setStep }: StepRenderProps - + + + + + {isSupported && ( - + + + Connect to Safe mobile + + )} diff --git a/src/components/new-safe/steps/Step2/index.tsx b/src/components/new-safe/steps/Step2/index.tsx index d3a9f814e6..b6d3bae20d 100644 --- a/src/components/new-safe/steps/Step2/index.tsx +++ b/src/components/new-safe/steps/Step2/index.tsx @@ -99,7 +99,7 @@ const CreateSafeStep2 = ({ Safe Mobile owner key (optional){' '} @@ -108,7 +108,7 @@ const CreateSafeStep2 = ({ - Use your mobile phone as your additional owner key + Use your mobile phone as an additional owner key @@ -117,7 +117,7 @@ const CreateSafeStep2 = ({ Threshold diff --git a/src/components/new-safe/steps/Step2/useSafeSetupHints.ts b/src/components/new-safe/steps/Step2/useSafeSetupHints.ts index e793865bdd..e824e652d6 100644 --- a/src/components/new-safe/steps/Step2/useSafeSetupHints.ts +++ b/src/components/new-safe/steps/Step2/useSafeSetupHints.ts @@ -13,7 +13,7 @@ export const useSafeSetupHints = ( if (threshold === 1) { safeSetupWarningSteps.push({ title: `1/${noOwners}`, - text: 'We recommend to use a threshold higher than one to prevent losing access to your safe in case one owner key gets compromised or lost', + text: 'We recommend using a threshold higher than one to prevent losing access to your Safe in case an owner key is lost or compromised.', }) } @@ -21,7 +21,7 @@ export const useSafeSetupHints = ( if (threshold === noOwners && noOwners > 1) { safeSetupWarningSteps.push({ title: `${noOwners}/${noOwners}`, - text: 'We recommend to use a threshold which is lower than the total number of owners of your Safe in case an owner loses access to their account and needs to be replaced.', + text: 'We recommend using a threshold which is lower than the total number of owners of your Safe in case an owner loses access to their account and needs to be replaced.', }) } diff --git a/src/components/new-safe/steps/Step3/index.tsx b/src/components/new-safe/steps/Step3/index.tsx index ee1c328f26..18e982dfd6 100644 --- a/src/components/new-safe/steps/Step3/index.tsx +++ b/src/components/new-safe/steps/Step3/index.tsx @@ -102,6 +102,8 @@ const CreateSafeStep3 = ({ data, onSubmit, onBack, setStep }: StepRenderProps ))} @@ -126,21 +128,20 @@ const CreateSafeStep3 = ({ data, onSubmit, onBack, setStep }: StepRenderProps - - - ≈ {totalFee} {chain?.nativeCurrency.symbol} - + <> + + + + ≈ {totalFee} {chain?.nativeCurrency.symbol} + + + + + You will have to confirm a transaction with your connected wallet. - + } /> - - - - You will have to confirm a transaction with your currently connected wallet. - - diff --git a/src/components/new-safe/steps/Step4/StatusMessage.tsx b/src/components/new-safe/steps/Step4/StatusMessage.tsx index be797e9d66..19f1d03660 100644 --- a/src/components/new-safe/steps/Step4/StatusMessage.tsx +++ b/src/components/new-safe/steps/Step4/StatusMessage.tsx @@ -3,36 +3,38 @@ import { SafeCreationStatus } from './useSafeCreation' import LoadingSpinner from '@/components/new-safe/steps/Step4/LoadingSpinner' const getStep = (status: SafeCreationStatus) => { + const ERROR_TEXT = 'Please cancel the process or retry the transaction.' + switch (status) { case SafeCreationStatus.AWAITING: return { - description: 'Step 1/2: Waiting for transaction confirmation.', + description: 'Waiting for transaction confirmation.', instruction: 'Please confirm the transaction with your connected wallet.', } case SafeCreationStatus.WALLET_REJECTED: return { description: 'Transaction was rejected.', - instruction: 'Please cancel or retry the Safe creation process.', + instruction: ERROR_TEXT, } case SafeCreationStatus.PROCESSING: return { - description: 'Step 2/2: Transaction is being executed.', + description: 'Transaction is being executed.', instruction: 'Please do not leave this page.', } case SafeCreationStatus.ERROR: return { description: 'There was an error.', - instruction: 'Please cancel or retry the Safe creation process.', + instruction: ERROR_TEXT, } case SafeCreationStatus.REVERTED: return { description: 'Transaction was reverted.', - instruction: 'Please cancel or retry the Safe creation process.', + instruction: ERROR_TEXT, } case SafeCreationStatus.TIMEOUT: return { description: 'Transaction was not found. Be aware that it might still be processed.', - instruction: 'Please cancel or retry the Safe creation process.', + instruction: ERROR_TEXT, } case SafeCreationStatus.SUCCESS: return { @@ -46,7 +48,7 @@ const getStep = (status: SafeCreationStatus) => { } case SafeCreationStatus.INDEX_FAILED: return { - description: 'Your Safe is created and will be indexed by our services shortly.', + description: 'Your Safe is created and will be picked up by our services shortly.', instruction: 'You can already open your Safe. It might take a moment until it becomes fully usable in the interface.', }