Skip to content
Open
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
3 changes: 3 additions & 0 deletions assets/img/icon-alert-triangle.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/img/icon-archive-download.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/img/icon-clock-outline.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/img/icon-multisig-group.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/img/icon-schedule-clock.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/img/icon-verified-shield.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions src/components/home-card/HomeCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {shouldScale} from '../../utils/helper-methods';
import {useTranslation} from 'react-i18next';
import {TouchableOpacity} from '@components/base/TouchableOpacity';
import ArrowRightSvg from '../../navigation/tabs/home/components/ArrowRightSvg';
import ThresholdBadge from '../threshold-badge/ThresholdBadge';
import MultisigBadge from '../multisig-badge/MultisigBadge';

interface BodyProps {
title?: string;
Expand All @@ -34,6 +36,8 @@ interface BodyProps {
percentageSuffix?: string;
hideKeyBalance: boolean;
pendingTssSession?: boolean;
tssMetadata?: {m: number; n: number};
isMultisig?: boolean;
}

interface HomeCardProps {
Expand Down Expand Up @@ -112,10 +116,16 @@ const HomeCard: React.FC<HomeCardProps> = ({body, footer, onCTAPress}) => {
percentageSuffix,
hideKeyBalance,
pendingTssSession,
tssMetadata,
isMultisig,
} = body;

const BodyComp = (
<View>
{tssMetadata ? (
<ThresholdBadge m={tssMetadata.m} n={tssMetadata.n} size={'card'} />
) : null}
{isMultisig ? <MultisigBadge size={'card'} /> : null}
{title && <CardBodyHeader>{title}</CardBodyHeader>}
{needsBackup && !pendingTssSession ? (
<Row>
Expand Down
37 changes: 37 additions & 0 deletions src/components/multisig-badge/MultisigBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react';
import {StyleProp, ViewStyle} from 'react-native';
import {useTheme} from 'styled-components/native';
import {useTranslation} from 'react-i18next';
import {SlateDark, White} from '../../styles/colors';
import MultisigIcon from '../../../assets/img/icon-multisig-group.svg';
import WalletTypeBadge, {
WalletTypeBadgeSize,
} from '../wallet-type-badge/WalletTypeBadge';

interface Props {
size?: WalletTypeBadgeSize;
style?: StyleProp<ViewStyle>;
}

const MultisigBadge: React.FC<Props> = ({size = 'list', style}) => {
const {t} = useTranslation();
const theme = useTheme();
const iconSize = size === 'card' ? 20 : 16;

return (
<WalletTypeBadge
size={size}
style={style}
icon={
<MultisigIcon
width={iconSize}
height={iconSize}
color={theme.dark ? White : SlateDark}
/>
}
label={t('Multisig')}
/>
);
};

export default MultisigBadge;
40 changes: 40 additions & 0 deletions src/components/threshold-badge/ThresholdBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React from 'react';
import {StyleProp, ViewStyle} from 'react-native';
import {useTheme} from 'styled-components/native';
import {useTranslation} from 'react-i18next';
import {SlateDark, White} from '../../styles/colors';
import VerifiedShieldIcon from '../../../assets/img/icon-verified-shield.svg';
import WalletTypeBadge, {
WalletTypeBadgeSize,
} from '../wallet-type-badge/WalletTypeBadge';

interface Props {
m: number;
n: number;
size?: WalletTypeBadgeSize;
style?: StyleProp<ViewStyle>;
}

const ThresholdBadge: React.FC<Props> = ({m, n, size = 'list', style}) => {
const {t} = useTranslation();
const theme = useTheme();
const iconSize =
size === 'card' ? {width: 11, height: 13} : {width: 9, height: 11};

return (
<WalletTypeBadge
size={size}
style={style}
icon={
<VerifiedShieldIcon
width={iconSize.width}
height={iconSize.height}
color={theme.dark ? White : SlateDark}
/>
}
label={`${t('Threshold')} ${m}/${n}`}
/>
);
};

export default ThresholdBadge;
47 changes: 47 additions & 0 deletions src/components/wallet-type-badge/WalletTypeBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React, {ReactNode} from 'react';
import {StyleProp, ViewStyle} from 'react-native';
import styled from 'styled-components/native';
import {BaseText} from '../styled/Text';
import {LightBlack, Slate30, SlateDark} from '../../styles/colors';

export type WalletTypeBadgeSize = 'list' | 'card';

interface Props {
icon: ReactNode;
label: string;
size?: WalletTypeBadgeSize;
style?: StyleProp<ViewStyle>;
}

const Container = styled.View`
flex-direction: row;
align-items: center;
align-self: flex-start;
gap: 4px;
border-width: 1px;
border-color: ${({theme: {dark}}) => (dark ? LightBlack : Slate30)};
border-radius: 16px;
padding: 4px 8px;
`;

const Label = styled(BaseText)<{size: WalletTypeBadgeSize}>`
font-style: normal;
font-weight: 400;
font-size: ${({size}) => (size === 'card' ? 13 : 12)}px;
line-height: ${({size}) => (size === 'card' ? 20 : 15)}px;
color: ${({theme: {dark}}) => (dark ? Slate30 : SlateDark)};
`;

const WalletTypeBadge: React.FC<Props> = ({
icon,
label,
size = 'list',
style,
}) => (
<Container style={style}>
{icon}
<Label size={size}>{label}</Label>
</Container>
);

export default WalletTypeBadge;
5 changes: 5 additions & 0 deletions src/navigation/tabs/home/components/Crypto.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ import {t} from 'i18next';
import {Analytics} from '../../../../store/analytics/analytics.effects';
import AddSvg from './AddSvg';
import {isTSSKey} from '../../../../store/wallet/effects/tss-send/tss-send';
import {IsShared} from '../../../../store/wallet/effects/transactions/transactions';
import {logManager} from '../../../../managers/LogManager';
import {WalletScreens} from '../../../../navigation/wallet/WalletGroup';
import {IsVMChain} from '../../../../store/wallet/utils/currency';
Expand Down Expand Up @@ -297,6 +298,8 @@ export const createHomeCardList = ({

const fullWalletObj = key?.wallets?.[0];
const hasPendingTssSession = fullWalletObj?.pendingTssSession;
const tssMetadata = key.wallets?.find(w => w.tssKeyId)?.tssMetadata;
const isMultisig = !!key.wallets?.some(w => IsShared(w));

return {
id: key.id,
Expand All @@ -311,6 +314,8 @@ export const createHomeCardList = ({
needsBackup={!backupComplete}
context={context}
pendingTssSession={hasPendingTssSession}
tssMetadata={tssMetadata}
isMultisig={isMultisig}
onPress={
onPress
? () => {
Expand Down
23 changes: 22 additions & 1 deletion src/navigation/tabs/home/components/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import ArrowRightSvg from './ArrowRightSvg';
import {TouchableOpacity} from '@components/base/TouchableOpacity';
import {maskIfHidden} from '../../../../utils/hideBalances';
import {isUnitedKingdomCountry} from '../../../../store/location/location.effects';
import ThresholdBadge from '../../../../components/threshold-badge/ThresholdBadge';
import MultisigBadge from '../../../../components/multisig-badge/MultisigBadge';

interface WalletCardComponentProps {
wallets: Wallet[];
Expand All @@ -45,6 +47,8 @@ interface WalletCardComponentProps {
hideKeyBalance: boolean;
context?: 'keySelector';
pendingTssSession?: boolean;
tssMetadata?: {m: number; n: number};
isMultisig?: boolean;
}

export const HeaderImg = styled.View`
Expand Down Expand Up @@ -203,6 +207,8 @@ const WalletCardComponent: React.FC<WalletCardComponentProps> = ({
layout,
context,
pendingTssSession,
tssMetadata,
isMultisig,
}) => {
const {t} = useTranslation();
const defaultAltCurrency = useAppSelector(({APP}) => APP.defaultAltCurrency);
Expand Down Expand Up @@ -253,7 +259,20 @@ const WalletCardComponent: React.FC<WalletCardComponentProps> = ({
<NeedBackupText>{t('Needs Backup')}</NeedBackupText>
</NeedBackupRow>
) : (
<ListIconRow>{SupportedNetworkIcons}</ListIconRow>
<ListIconRow>
{SupportedNetworkIcons}
{tssMetadata ? (
<ThresholdBadge
m={tssMetadata.m}
n={tssMetadata.n}
size={'list'}
style={{marginLeft: 4}}
/>
) : null}
{isMultisig ? (
<MultisigBadge size={'list'} style={{marginLeft: 4}} />
) : null}
</ListIconRow>
)}
<KeyName>{keyName}</KeyName>
</ListLeftColumn>
Expand Down Expand Up @@ -303,6 +322,8 @@ const WalletCardComponent: React.FC<WalletCardComponentProps> = ({
needsBackup,
hideKeyBalance,
pendingTssSession,
tssMetadata,
isMultisig,
}}
footer={CardFooter}
onCTAPress={onPress}
Expand Down
38 changes: 0 additions & 38 deletions src/navigation/tabs/settings/components/Crypto.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import {Analytics} from '../../../../store/analytics/analytics.effects';
import {
setCustomizeNonce,
setQueuedTransactions,
setTssEnabled,
setUseUnconfirmedFunds,
} from '../../../../store/wallet/wallet.actions';

Expand All @@ -32,11 +31,6 @@ const Crypto = () => {
const queuedTransactions = useAppSelector(
({WALLET}) => WALLET.queuedTransactions,
);
const tssEnabled = useAppSelector(({WALLET}) => WALLET.tssEnabled);
const isInternalUser = useAppSelector(({APP, BITPAY_ID}) => {
const user = BITPAY_ID.user[APP.network];
return !!user?.email?.endsWith('@bitpay.com');
});
const navigation = useNavigation();

const handleToggleUnconfirmedFunds = useCallback(
Expand Down Expand Up @@ -75,18 +69,6 @@ const Crypto = () => {
[dispatch],
);

const handleToggleTssEnabled = useCallback(
(value: boolean) => {
dispatch(setTssEnabled(value));
dispatch(
Analytics.track('Set TSS Enabled', {
tssEnabled: value,
}),
);
},
[dispatch],
);

return (
<SettingsComponent>
<Setting
Expand Down Expand Up @@ -143,26 +125,6 @@ const Crypto = () => {
)}
</InfoDescription>
</Info>
{isInternalUser ? (
<>
<Hr />
<Setting activeOpacity={1}>
<SettingTitle>{t('Enable TSS Wallets')}</SettingTitle>
<ToggleSwitch
onChange={handleToggleTssEnabled}
isEnabled={tssEnabled}
/>
</Setting>
<Info>
<InfoTriangle />
<InfoDescription>
{t(
'If enabled, you will be able to create and join TSS (Threshold Signature Scheme) wallets. This is an experimental feature.',
)}
</InfoDescription>
</Info>
</>
) : null}
</SettingsComponent>
);
};
Expand Down
Loading
Loading