Skip to content
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

Feat: Sygnum safe app recovery method [SW-168] #4166

Merged
merged 2 commits into from
Sep 19, 2024
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
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/building-your-application/configuring/typescript for more information.
12 changes: 0 additions & 12 deletions public/images/common/recovery_coincover.svg

This file was deleted.

12 changes: 1 addition & 11 deletions public/images/common/recovery_sygnum.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export enum SafeAppsTag {
SAFE_GOVERNANCE_APP = 'safe-governance-app',
WALLET_CONNECT = 'wallet-connect',
ONRAMP = 'onramp',
RECOVERY_SYGNUM = 'recovery-sygnum',
}

// Help Center
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Track from '@/components/common/Track'
import { RECOVERY_FEEDBACK_FORM, HelpCenterArticle } from '@/config/constants'
import { RECOVERY_FEEDBACK_FORM, HelpCenterArticle, SafeAppsTag } from '@/config/constants'
import { trackEvent } from '@/services/analytics'
import { RECOVERY_EVENTS } from '@/services/analytics/events/recovery'
import { type ChangeEvent, type ReactElement, useContext } from 'react'
Expand All @@ -26,18 +26,17 @@ import { UpsertRecoveryFlow } from '@/components/tx-flow/flows'
import ExternalLink from '@/components/common/ExternalLink'
import RecoveryCustomIcon from '@/public/images/common/recovery_custom.svg'
import RecoverySygnumIcon from '@/public/images/common/recovery_sygnum.svg'
import RecoveryCoincoverIcon from '@/public/images/common/recovery_coincover.svg'
import { TxModalContext } from '@/components/tx-flow'
import css from './styles.module.css'
import CheckIcon from '@/public/images/common/check.svg'

const SYGNUM_WAITLIST_LINK = 'https://wn2n6ocviur.typeform.com/to/cJbJW0KR'
const COINCOVER_WAITLIST_LINK = 'https://wn2n6ocviur.typeform.com/to/ijqSzOkr'
import { AppRoutes } from '@/config/routes'
import { useSearchParams } from 'next/navigation'
import { useRemoteSafeApps } from '@/hooks/safe-apps/useRemoteSafeApps'
import TxStatusChip from '@/components/transactions/TxStatusChip'

enum RecoveryMethod {
SelfCustody = 'SelfCustody',
Sygnum = 'Sygnum',
Coincover = 'Coincover',
}

enum FieldNames {
Expand All @@ -50,6 +49,9 @@ type Fields = {

export function ChooseRecoveryMethodModal({ open, onClose }: { open: boolean; onClose: () => void }): ReactElement {
const { setTxFlow } = useContext(TxModalContext)
const querySafe = useSearchParams().get('safe')
const [matchingApps] = useRemoteSafeApps(SafeAppsTag.RECOVERY_SYGNUM)
const hasSygnumApp = Boolean(matchingApps?.length)

const methods = useForm<Fields>({
defaultValues: {
Expand Down Expand Up @@ -124,53 +126,34 @@ export function ChooseRecoveryMethodModal({ open, onClose }: { open: boolean; on
<FormControlLabel
value={RecoveryMethod.Sygnum}
control={<Radio />}
disabled={!hasSygnumApp}
label={
<div className={css.method}>
<RecoverySygnumIcon style={{ display: 'block' }} />
<Typography fontWeight="bold" mb={1} mt={2}>
Sygnum
</Typography>
<List className={css.checkList}>
<ListItem>
<CheckIcon />
Regulated Swiss digital asset bank
</ListItem>
<ListItem>
<CheckIcon />
Ensure you (and only you) can recover
</ListItem>
<ListItem>
<CheckIcon />
Simple and efficient
</ListItem>
</List>
</div>
}
/>

<FormControlLabel
value={RecoveryMethod.Coincover}
control={<Radio />}
label={
<div className={css.method}>
<RecoveryCoincoverIcon style={{ display: 'block' }} />
<Typography fontWeight="bold" mb={1} mt={2}>
Coincover
Sygnum Web3 Recovery
</Typography>
<List className={css.checkList}>
<ListItem>
<CheckIcon />
World&apos;s #1 Recovery Solution
Your key. Your crypto. Your recovery
</ListItem>
<ListItem>
<CheckIcon />
Protected by Biometrics
Account recovery by your identity
</ListItem>
<ListItem>
<CheckIcon />
Lloyd’s of London Backed Tech
Regulated Swiss digital asset bank
</ListItem>
</List>

{!hasSygnumApp && (
<Box mt={2.5} sx={{ oopacity: 0.75 }}>
<TxStatusChip color="primary">Not available on this network</TxStatusChip>
</Box>
)}
</div>
}
/>
Expand Down Expand Up @@ -199,13 +182,18 @@ export function ChooseRecoveryMethodModal({ open, onClose }: { open: boolean; on
</Button>
</Track>
) : (
<Track {...RECOVERY_EVENTS.CONTINUE_TO_WAITLIST} label={currentType}>
<Track {...RECOVERY_EVENTS.SYGNUM_APP} label={currentType}>
<Link
href={currentType === RecoveryMethod.Sygnum ? SYGNUM_WAITLIST_LINK : COINCOVER_WAITLIST_LINK}
target="_blank"
href={{
pathname: AppRoutes.apps.open,
query: {
safe: querySafe,
appUrl: matchingApps?.[0]?.url,
},
}}
passHref
>
<Button variant="contained">Join waitlist</Button>
<Button variant="contained">Open App</Button>
</Link>
</Track>
)}
Expand Down
17 changes: 4 additions & 13 deletions src/services/analytics/events/recovery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,22 @@ export const RECOVERY_EVENTS = {
SETUP_RECOVERY: {
action: 'Start recovery setup',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
SELECT_RECOVERY_METHOD: {
action: 'Select recovery method',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
CONTINUE_WITH_RECOVERY: {
action: 'Continue with recovery method',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
CONTINUE_TO_WAITLIST: {
action: 'Continue to waitlist',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
SYGNUM_APP: {
action: 'Go to Sygnum app',
category: RECOVERY_CATEGORY,
},
RECOVERY_SETTINGS: {
action: 'Recovery settings',
Expand All @@ -37,42 +37,34 @@ export const RECOVERY_EVENTS = {
EDIT_RECOVERY: {
action: 'Start edit recovery',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
REMOVE_RECOVERY: {
action: 'Start recovery removal',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
START_RECOVERY: {
action: 'Start recovery proposal',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
CANCEL_RECOVERY: {
action: 'Start recovery cancellation',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
SHOW_ADVANCED: {
action: 'Show advanced recovery settings',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
DISMISS_PROPOSAL_CARD: {
action: 'Dismiss recovery proposal card',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
LEARN_MORE: {
action: 'Recovery info click',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
GO_BACK: {
action: 'Recovery cancellation back',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
GIVE_US_FEEDBACK: {
action: 'Recovery feedback click',
Expand All @@ -82,7 +74,6 @@ export const RECOVERY_EVENTS = {
CHECK_RECOVERY_PROPOSAL: {
action: 'Check recovery proposal',
category: RECOVERY_CATEGORY,
event: EventType.CLICK,
},
SUBMIT_RECOVERY_CREATE: {
action: 'Submit recovery setup',
Expand Down
Loading