diff --git a/src/assets/images/2of3Vault.svg b/src/assets/images/2of3Vault.svg new file mode 100644 index 0000000000..215288acfb --- /dev/null +++ b/src/assets/images/2of3Vault.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/3of5Vault.svg b/src/assets/images/3of5Vault.svg new file mode 100644 index 0000000000..f54b222cbb --- /dev/null +++ b/src/assets/images/3of5Vault.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/collaborativeGreen.svg b/src/assets/images/collaborativeGreen.svg new file mode 100644 index 0000000000..7814af73f7 --- /dev/null +++ b/src/assets/images/collaborativeGreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/createVault1.svg b/src/assets/images/createVault1.svg new file mode 100644 index 0000000000..cdd4f304c2 --- /dev/null +++ b/src/assets/images/createVault1.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/createVault2.svg b/src/assets/images/createVault2.svg new file mode 100644 index 0000000000..fa58effd43 --- /dev/null +++ b/src/assets/images/createVault2.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/createWallet.svg b/src/assets/images/createWallet.svg new file mode 100644 index 0000000000..63a485ea9d --- /dev/null +++ b/src/assets/images/createWallet.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/createWalletIllustration.svg b/src/assets/images/createWalletIllustration.svg new file mode 100644 index 0000000000..8082efb8b8 --- /dev/null +++ b/src/assets/images/createWalletIllustration.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/helpGreen.svg b/src/assets/images/helpGreen.svg new file mode 100644 index 0000000000..213d83a520 --- /dev/null +++ b/src/assets/images/helpGreen.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/assets/images/importGreen.svg b/src/assets/images/importGreen.svg new file mode 100644 index 0000000000..0c112ba376 --- /dev/null +++ b/src/assets/images/importGreen.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/plusRound.svg b/src/assets/images/plusRound.svg new file mode 100644 index 0000000000..fa4079bfd7 --- /dev/null +++ b/src/assets/images/plusRound.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/setting_backup.svg b/src/assets/images/setting_backup.svg new file mode 100644 index 0000000000..352c3fa6c3 --- /dev/null +++ b/src/assets/images/setting_backup.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/setting_backup_light.svg b/src/assets/images/setting_backup_light.svg new file mode 100644 index 0000000000..1ee5f096f7 --- /dev/null +++ b/src/assets/images/setting_backup_light.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/src/assets/images/setting_gear.svg b/src/assets/images/setting_gear.svg new file mode 100644 index 0000000000..054f900d65 --- /dev/null +++ b/src/assets/images/setting_gear.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/setting_gear_light.svg b/src/assets/images/setting_gear_light.svg new file mode 100644 index 0000000000..29711e4b97 --- /dev/null +++ b/src/assets/images/setting_gear_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/setting_inheritance.svg b/src/assets/images/setting_inheritance.svg new file mode 100644 index 0000000000..50ff73e95d --- /dev/null +++ b/src/assets/images/setting_inheritance.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/setting_inheritance_light.svg b/src/assets/images/setting_inheritance_light.svg new file mode 100644 index 0000000000..a0ae27e55b --- /dev/null +++ b/src/assets/images/setting_inheritance_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/setting_tip.svg b/src/assets/images/setting_tip.svg new file mode 100644 index 0000000000..d305616bec --- /dev/null +++ b/src/assets/images/setting_tip.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/setting_usdt.svg b/src/assets/images/setting_usdt.svg new file mode 100644 index 0000000000..549a5e7e4c --- /dev/null +++ b/src/assets/images/setting_usdt.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/setting_usdt_light.svg b/src/assets/images/setting_usdt_light.svg new file mode 100644 index 0000000000..878b91a593 --- /dev/null +++ b/src/assets/images/setting_usdt_light.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/updateScheme.svg b/src/assets/images/updateScheme.svg new file mode 100644 index 0000000000..c8e5576839 --- /dev/null +++ b/src/assets/images/updateScheme.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/components/FAB.tsx b/src/components/FAB.tsx new file mode 100644 index 0000000000..a433cefb29 --- /dev/null +++ b/src/components/FAB.tsx @@ -0,0 +1,34 @@ +import { Box } from 'native-base'; +import React from 'react'; +import { StyleSheet, TouchableOpacity } from 'react-native'; +import { wp } from 'src/constants/responsive'; +import Colors from 'src/theme/Colors'; + +export const FAB = ({ icon, onPress }) => { + return ( + + {icon} + + ); +}; + +const styles = StyleSheet.create({ + container: { + height: wp(56), + width: wp(56), + borderRadius: wp(56), + backgroundColor: Colors.primaryGreen, + // position + position: 'absolute', + bottom: wp(16), + right: 0, + justifyContent: 'center', + alignItems: 'center', + // shadow + shadowColor: '#000', + shadowOffset: { width: 0, height: 4 }, + shadowOpacity: 0.25, + shadowRadius: 6, + elevation: 8, + }, +}); diff --git a/src/components/HomeScreenHeader.tsx b/src/components/HomeScreenHeader.tsx index abd2ca942e..86767eb11a 100644 --- a/src/components/HomeScreenHeader.tsx +++ b/src/components/HomeScreenHeader.tsx @@ -30,15 +30,10 @@ import ThemedColor from './ThemedColor/ThemedColor'; interface HomeScreenHeaderProps { colorMode: string; - circleIconWrapper: React.ReactNode; title: string; } -const HomeScreenHeader: React.FC = ({ - colorMode, - circleIconWrapper, - title, -}) => { +const HomeScreenHeader: React.FC = ({ colorMode, title }) => { const navigation = useNavigation(); const dispatch = useDispatch(); const { uaiStack } = useUaiStack(); @@ -89,8 +84,7 @@ const HomeScreenHeader: React.FC = ({ }), [uaiType.RECOVERY_PHRASE_HEALTH_CHECK]: () => { if (backupHistory.length === 0) { - navigtaion.navigate('Home', { - selectedOption: 'More', + navigtaion.navigate('BackupSettingsScreen', { isUaiFlow: true, }); } else { @@ -171,18 +165,14 @@ const HomeScreenHeader: React.FC = ({ - - {circleIconWrapper} - - {capitalizeEachWord(title === walletTranslation.more ? common.moreOptions : title)} - - - + + {capitalizeEachWord(title)} + { const { colorMode } = useColorMode(); const isDarkMode = colorMode === 'dark'; const { translations } = useContext(LocalizationContext); const { wallet: walletTranslation } = translations; - const selectedFooterColor = ThemedColor({ name: 'footer_selected_option' }); const menuOptions = [ { - name: walletTranslation.homeWallets, + name: walletTranslation.title, defaultIcon: , selectedIcon: , }, @@ -44,7 +42,7 @@ const MenuFooter = ({ selectedOption, onOptionChange }) => { return ( { onOptionChange(option.name)} - style={[styles.menuItem]} + style={[ + styles.menuItem, + selectedOption === option.name && { backgroundColor: Colors.primaryGreen }, + ]} > {selectedOption === option.name ? option.selectedIcon : option.defaultIcon} - - {option.name} - ))} @@ -81,11 +72,11 @@ export default MenuFooter; const styles = StyleSheet.create({ container: { - width: '100%', - minHeight: hp(85), - borderRadius: 20, - paddingHorizontal: wp(10), - paddingTop: hp(10), + width: '95%', + alignSelf: 'center', + borderRadius: screenWidth * 0.6, + paddingVertical: hp(9), + marginBottom: Platform.select({ ios: hp(35), android: hp(10) }), borderWidth: 1, }, menuWrapper: { @@ -95,9 +86,9 @@ const styles = StyleSheet.create({ }, menuItem: { alignItems: 'center', - paddingVertical: hp(5), - paddingHorizontal: wp(10), - borderRadius: 10, + paddingVertical: wp(11), + paddingHorizontal: wp(27), + borderRadius: 100, }, iconContainer: { width: wp(20), diff --git a/src/components/ThemedSvg.tsx/ThemedIcons.js b/src/components/ThemedSvg.tsx/ThemedIcons.js index e01cd4c29d..a21b167430 100644 --- a/src/components/ThemedSvg.tsx/ThemedIcons.js +++ b/src/components/ThemedSvg.tsx/ThemedIcons.js @@ -410,25 +410,25 @@ const themeIcons = { }, footer_more: { DARK: MoreWhite, - LIGHT: MoreGreen, + LIGHT: MoreWhite, PRIVATE: PrivateMoreLight, PRIVATE_LIGHT: PrivateMoreLight, }, footer_concierge: { DARK: ConceirgeWhite, - LIGHT: ConciergeIcon, + LIGHT: ConceirgeWhite, PRIVATE: PrivateConciergeLight, PRIVATE_LIGHT: PrivateConciergeLight, }, footer_Key: { DARK: KeyWhite, - LIGHT: KeyGreen, + LIGHT: KeyWhite, PRIVATE: PrivateKeyGold, PRIVATE_LIGHT: PrivateKeyGold, }, footer_Wallet: { DARK: WalletWhite, - LIGHT: WalletIcon, + LIGHT: WalletWhite, PRIVATE: PrivateWalletLight, PRIVATE_LIGHT: PrivateWalletLight, }, @@ -1130,6 +1130,12 @@ const themeIcons = { PRIVATE: CoinsIcon, PRIVATE_LIGHT: CoinsIconPrivate, }, + wallet_quorum_plus_icon: { + DARK: Plus, + LIGHT: PlusGreenIcon, + PRIVATE: Plus, + PRIVATE_LIGHT: Plus, + }, }; export default themeIcons; diff --git a/src/constants/Fonts.js b/src/constants/Fonts.js index ceabb4c640..bcb7f5eab3 100644 --- a/src/constants/Fonts.js +++ b/src/constants/Fonts.js @@ -2,6 +2,7 @@ export default { InterLight: 'Inter-Light', InterLightItalic: 'Inter-LightItalic', InterRegular: 'Inter-Regular', + InterMedium: 'Inter-Medium', InterItalic: 'Inter-Italic', LoraMedium: 'Lora-Medium', LoraMediumItalic: 'Lora-MediumItalic', diff --git a/src/context/Localization/language/en.json b/src/context/Localization/language/en.json index 10d8cd8264..372677c55f 100644 --- a/src/context/Localization/language/en.json +++ b/src/context/Localization/language/en.json @@ -42,7 +42,7 @@ "connect": "Connect", "disconnect": "Disconnect", "delete": "Delete", - "tips": "Tips and Tools", + "tips": "Tips", "recentTransactions": "Recent Transactions", "viewAll": "View All", "addNewWalletOrImport": "Add a new wallet or import one", @@ -56,6 +56,7 @@ "addNow": "Add Now", "needMoreHelp": "Need more help?", "reinstate": "Reinstate", + "reinstateDesc": "Re-enable access to this wallet and its funds.", "of": "of", "CANARY": "Canary", "buyBitCoin": "Buy Bitcoin", @@ -275,6 +276,7 @@ "discountDetails": "Discount Details" }, "wallet": { + "title": "Secure", "Createwallet": "Create a wallet", "hardwareShopWallet": "Shop for Hardware Wallets", "AddWallet": "Add a Wallet", @@ -449,6 +451,7 @@ "walletWithFamily": "Create wallet with family and friends", "addNewWallet": "Add a New Wallet", "createOrImportWallet": "Create a new wallet or import existing one", + "restoreWalletUsingBackup": "Restore wallet using backup or keys.", "collaborativeSessionExists": "Collaborative wallet setup session already exists", "collaborativeSessionExistsDesc": "You already have a collaborative wallet setup session in progress, would you like to continue the session or start a new one?", "customWalletDesc": "Setup your wallet quorum", @@ -517,7 +520,22 @@ "verifySubtitle": "Scan the signed message from your hardware wallet", "sendBitcoin": "Send Bitcoin", "receiveBitcoin": "Receive Bitcoin", - "buyBitCoin": "Buy Bitcoin with Ramp" + "buyBitCoin": "Buy Bitcoin with Ramp", + "hotWallet": "Hot Wallet", + "hotWalletDesc": "Daily use, keys on the device", + "coldStorage": "Cold Storage", + "coldStorageDesc": "Use hardware wallet, keep offline.", + "multiKeyAdvanced": "Multi-Key / Advanced", + "multiKeyAdvancedDesc": "Use multiple keys, miniscript or import a descriptor.", + "simpleMultiKey": "Simple Multi-Key", + "simpleMultiKeyDesc": "A wallet that needs 2 approvals out of 3 to spend your funds securely.", + "strongMultiKey": "Strong Multi-key", + "strongMultiKeyDesc": "A secure wallet that needs 3 approvals out of 5 to unlock and spend.", + "advanceCustomSetup": "Advance / Custom setup", + "createFirstWalletTitle": "Let's Create Your First Wallet", + "createFirstWalletSubtitle": "Create or import your first wallet. Your keys stay in your control", + "helpMeDecide": "Help me Decide", + "AddUSDTWallet": "Add USDT Wallet" }, "vault": { "Addsigner": "Add a Signer", @@ -873,7 +891,7 @@ "VersionHistory": "Version History", "VersionHistorySubTitle": "View the app version history", "GeneralPreferences": "General Preferences", - "General": "General ", + "General": "General Setting", "CurrencyDefaultsSubtitle": "Set preferred defaults", "appSetting": "App Settings", "appSettingDesc": "Configure your app settings", diff --git a/src/context/Localization/language/es.json b/src/context/Localization/language/es.json index 10d8cd8264..372677c55f 100644 --- a/src/context/Localization/language/es.json +++ b/src/context/Localization/language/es.json @@ -42,7 +42,7 @@ "connect": "Connect", "disconnect": "Disconnect", "delete": "Delete", - "tips": "Tips and Tools", + "tips": "Tips", "recentTransactions": "Recent Transactions", "viewAll": "View All", "addNewWalletOrImport": "Add a new wallet or import one", @@ -56,6 +56,7 @@ "addNow": "Add Now", "needMoreHelp": "Need more help?", "reinstate": "Reinstate", + "reinstateDesc": "Re-enable access to this wallet and its funds.", "of": "of", "CANARY": "Canary", "buyBitCoin": "Buy Bitcoin", @@ -275,6 +276,7 @@ "discountDetails": "Discount Details" }, "wallet": { + "title": "Secure", "Createwallet": "Create a wallet", "hardwareShopWallet": "Shop for Hardware Wallets", "AddWallet": "Add a Wallet", @@ -449,6 +451,7 @@ "walletWithFamily": "Create wallet with family and friends", "addNewWallet": "Add a New Wallet", "createOrImportWallet": "Create a new wallet or import existing one", + "restoreWalletUsingBackup": "Restore wallet using backup or keys.", "collaborativeSessionExists": "Collaborative wallet setup session already exists", "collaborativeSessionExistsDesc": "You already have a collaborative wallet setup session in progress, would you like to continue the session or start a new one?", "customWalletDesc": "Setup your wallet quorum", @@ -517,7 +520,22 @@ "verifySubtitle": "Scan the signed message from your hardware wallet", "sendBitcoin": "Send Bitcoin", "receiveBitcoin": "Receive Bitcoin", - "buyBitCoin": "Buy Bitcoin with Ramp" + "buyBitCoin": "Buy Bitcoin with Ramp", + "hotWallet": "Hot Wallet", + "hotWalletDesc": "Daily use, keys on the device", + "coldStorage": "Cold Storage", + "coldStorageDesc": "Use hardware wallet, keep offline.", + "multiKeyAdvanced": "Multi-Key / Advanced", + "multiKeyAdvancedDesc": "Use multiple keys, miniscript or import a descriptor.", + "simpleMultiKey": "Simple Multi-Key", + "simpleMultiKeyDesc": "A wallet that needs 2 approvals out of 3 to spend your funds securely.", + "strongMultiKey": "Strong Multi-key", + "strongMultiKeyDesc": "A secure wallet that needs 3 approvals out of 5 to unlock and spend.", + "advanceCustomSetup": "Advance / Custom setup", + "createFirstWalletTitle": "Let's Create Your First Wallet", + "createFirstWalletSubtitle": "Create or import your first wallet. Your keys stay in your control", + "helpMeDecide": "Help me Decide", + "AddUSDTWallet": "Add USDT Wallet" }, "vault": { "Addsigner": "Add a Signer", @@ -873,7 +891,7 @@ "VersionHistory": "Version History", "VersionHistorySubTitle": "View the app version history", "GeneralPreferences": "General Preferences", - "General": "General ", + "General": "General Setting", "CurrencyDefaultsSubtitle": "Set preferred defaults", "appSetting": "App Settings", "appSettingDesc": "Configure your app settings", diff --git a/src/hooks/useSettingKeeper.tsx b/src/hooks/useSettingKeeper.tsx index e8139e0c78..3409b4916f 100644 --- a/src/hooks/useSettingKeeper.tsx +++ b/src/hooks/useSettingKeeper.tsx @@ -270,13 +270,6 @@ export const useSettingKeeper = () => { onPress: () => navigation.navigate('ChangeLanguage'), isDiamond: false, }, - { - title: settings.appSetting, - description: settings.appSettingDesc, - icon: , - onPress: () => navigation.navigate('SettingApp'), - isDiamond: false, - }, ].filter(Boolean); const keysAndwallet = [ { @@ -331,13 +324,6 @@ export const useSettingKeeper = () => { onPress: () => navigation.navigate('SafeKeepingTips'), isDiamond: false, }, - { - title: signerText.inheritanceDocuments, - description: signerText.bitcoinSecurity, - icon: , - onPress: () => navigation.dispatch(CommonActions.navigate('InheritanceDocumentScreen')), - isDiamond: false, - }, ]; const appSetting = [ { diff --git a/src/navigation/Navigator.tsx b/src/navigation/Navigator.tsx index 412810611c..9ed7b6babd 100644 --- a/src/navigation/Navigator.tsx +++ b/src/navigation/Navigator.tsx @@ -128,7 +128,6 @@ import ContactDetails from 'src/screens/SigningDevices/ContactDetails'; import ShareQR from 'src/screens/SigningDevices/ShareQR'; import ScanNode from 'src/screens/AppSettings/Node/ScanNode'; import NotificationsCenter from 'src/screens/Home/Notifications/NotificationsCenter'; -import SettingsApp from 'src/screens/Home/components/Settings/AppSettings'; import InheritanceDocumentScreen from 'src/screens/Home/components/Settings/InheritanceDocumentScreen'; import HardwareWallet from 'src/screens/Hardware/Hardware'; import SpendingLimit from 'src/screens/Vault/SpendingLimit'; @@ -166,6 +165,11 @@ import { SwapHistoryDetail } from 'src/screens/Home/components/buyBtc/Swap/SwapH import { SwapAllHistory } from 'src/screens/Home/components/buyBtc/Swap/SwapAllHistory'; import { TipBottomSheet } from 'src/components/Modal/TipBottomSheet'; import { SendTip } from 'src/screens/Send/SendTip'; +import { AddNewMultiKeyWallet } from 'src/screens/AddWalletScreen/AddNewMultiKeyWallet'; +import { SelectWalletType } from 'src/screens/AddWalletScreen/SelectWalletType'; +import { AppTipsScreen } from 'src/screens/Home/components/Settings/AppTipsScreen'; +import { BackupSettingsScreen } from 'src/screens/Home/components/Settings/BackupSettinsScreen'; +import { GeneralSettingsScreen } from 'src/screens/Home/components/Settings/GeneralSettingsScreen'; function LoginStack() { const Stack = createNativeStackNavigator(); @@ -321,7 +325,8 @@ function AppStack() { - + + @@ -362,6 +367,9 @@ function AppStack() { + + + ); diff --git a/src/navigation/types.ts b/src/navigation/types.ts index 0568b2b74a..2b68dfcb20 100644 --- a/src/navigation/types.ts +++ b/src/navigation/types.ts @@ -182,6 +182,11 @@ export type AppStackParams = { CloudBackupPassword: undefined; ImportedWalletSetup: undefined; SendTip: undefined; + AddNewMultiKeyWallet: undefined; + SelectWalletType: undefined; + AppTipsScreen: undefined; + BackupSettingsScreen: undefined; + GeneralSettingsScreen: undefined; }; // Usage: diff --git a/src/screens/AddWalletScreen/AddNewMultiKeyWallet.tsx b/src/screens/AddWalletScreen/AddNewMultiKeyWallet.tsx new file mode 100644 index 0000000000..a3a0f5ec13 --- /dev/null +++ b/src/screens/AddWalletScreen/AddNewMultiKeyWallet.tsx @@ -0,0 +1,193 @@ +import { Box, useColorMode } from 'native-base'; +import React, { useContext, useState } from 'react'; +import ScreenWrapper from 'src/components/ScreenWrapper'; +import { Pressable, StyleSheet, TouchableOpacity } from 'react-native'; +import Text from 'src/components/KeeperText'; +import { CommonActions } from '@react-navigation/native'; +import WalletHeader from 'src/components/WalletHeader'; +import { hp, wp } from 'src/constants/responsive'; +import Colors from 'src/theme/Colors'; +import IconArrow from 'src/assets/images/icon_arrow_grey.svg'; +import IconArrowWhite from 'src/assets/images/icon_arrow_white.svg'; +import Vault2of3 from 'src/assets/images/2of3Vault.svg'; +import Vault3of5 from 'src/assets/images/3of5Vault.svg'; +import GreenArrow from 'src/assets/images/icon_arrow.svg'; +import GreenArrowLight from 'src/assets/images/icon_arrow_white.svg'; +import { LocalizationContext } from 'src/context/Localization/LocContext'; +import { useDispatch } from 'react-redux'; +import { resetCollaborativeSession } from 'src/store/reducers/vaults'; +import { useAppSelector } from 'src/store/hooks'; +import KeeperModal from 'src/components/KeeperModal'; +import CollaborativeIcon from 'src/assets/images/collaborativeGreen.svg'; + +export const AddNewMultiKeyWallet = ({ navigation, route }) => { + const { vaultId } = route.params || {}; + const { colorMode } = useColorMode(); + const isDarkMode = colorMode === 'dark'; + const { translations } = useContext(LocalizationContext); + const { wallet: walletTranslations, vault: vaultText, common } = translations; + const dispatch = useDispatch(); + const { collaborativeSession } = useAppSelector((state) => state.vault); + const [collabSessionExistsModalVisible, setCollabSessionExistsModalVisible] = useState(false); + + const handleCollaborativeWalletCreation = () => { + if (Object.keys(collaborativeSession.signers).length > 0) { + setCollabSessionExistsModalVisible(true); + } else { + dispatch(resetCollaborativeSession()); + setTimeout(() => { + navigation.navigate('SetupCollaborativeWallet'); + }, 500); // delaying navigation by 0.5 second to ensure collaborative session reset + } + }; + + const CREATE_WALLET_OPTIONS = [ + { + icon: , + title: walletTranslations.simpleMultiKey, + subtitle: walletTranslations.simpleMultiKeyDesc, + onPress: () => + navigation.dispatch( + CommonActions.navigate({ + name: 'AddSigningDevice', + params: { + scheme: { m: 2, n: 3 }, + currentBlockHeight: null, + hasInitialTimelock: false, + isNewSchemeFlow: true, + vaultId, + }, + }) + ), + id: '2Of3', + }, + { + icon: , + title: walletTranslations.strongMultiKey, + subtitle: walletTranslations.strongMultiKeyDesc, + onPress: () => + navigation.dispatch( + CommonActions.navigate({ + name: 'AddSigningDevice', + params: { + scheme: { m: 3, n: 5 }, + currentBlockHeight: null, + hasInitialTimelock: false, + isNewSchemeFlow: true, + vaultId, + }, + }) + ), + id: '3Of5', + }, + !vaultId && { + icon: , + title: vaultText.collaborativeWallet, + subtitle: walletTranslations.walletWithFamily, + onPress: handleCollaborativeWalletCreation, + id: 'collaborative', + }, + ].filter(Boolean); + + return ( + + + + {CREATE_WALLET_OPTIONS.map((option, index) => ( + + ))} + navigation.navigate('AddNewWallet', { vaultId })}> + + + {walletTranslations.advanceCustomSetup} + + {isDarkMode ? : } + + + + setCollabSessionExistsModalVisible(false)} + title={walletTranslations.collaborativeSessionExists} + subTitle={walletTranslations.collaborativeSessionExistsDesc} + buttonText={common.continueSession} + secondaryButtonText={common.startNew} + secondaryCallback={() => { + setCollabSessionExistsModalVisible(false); + dispatch(resetCollaborativeSession()); + setTimeout(() => { + navigation.navigate('SetupCollaborativeWallet'); + }, 500); + }} + buttonCallback={() => { + setCollabSessionExistsModalVisible(false); + navigation.navigate('SetupCollaborativeWallet'); + }} + /> + + ); +}; + +const OptionItem = ({ option, colorMode }) => { + return ( + + + + {option.icon} + + + {option.title} + + + {option.subtitle} + + + + {colorMode === 'dark' ? : } + + + ); +}; + +const styles = StyleSheet.create({ + addWalletOptionsList: { + gap: wp(15), + marginTop: hp(30), + flex: 1, + }, + optionCTR: { + flexDirection: 'row', + padding: hp(20), + alignItems: 'center', + gap: wp(16), + borderRadius: 12, + borderWidth: 1.2, + }, + optionTitle: { + marginBottom: hp(4), + }, + optionRow: { + flexDirection: 'row', + gap: wp(14), + flex: 1, + flexGrow: 1, + }, + suggestionCtr: { + flexDirection: 'row', + justifyContent: 'center', + alignItems: 'center', + borderRadius: 10, + paddingVertical: hp(15), + marginTop: hp(10), + marginBottom: hp(40), + }, + suggestionTxt: { textAlign: 'center', marginRight: wp(6) }, +}); diff --git a/src/screens/AddWalletScreen/AddNewWallet.tsx b/src/screens/AddWalletScreen/AddNewWallet.tsx index 7ddd3d2c85..7217a1a996 100644 --- a/src/screens/AddWalletScreen/AddNewWallet.tsx +++ b/src/screens/AddWalletScreen/AddNewWallet.tsx @@ -5,19 +5,14 @@ import { LocalizationContext } from 'src/context/Localization/LocContext'; import { Pressable, StyleSheet, TouchableOpacity, Vibration } from 'react-native'; import Text from 'src/components/KeeperText'; import KeeperModal from 'src/components/KeeperModal'; -import ImportWalletIcon from 'src/assets/images/vault_icon.svg'; -import AdvanceCustomizationIcon from 'src/assets/images/other_light.svg'; import { CommonActions } from '@react-navigation/native'; import WalletHeader from 'src/components/WalletHeader'; import { hp, windowWidth, wp } from 'src/constants/responsive'; -import NewWalletIcon from 'src/assets/images/wallet-white-small.svg'; import Buttons from 'src/components/Buttons'; import DashedCta from 'src/components/DashedCta'; import CheckIcon from 'src/assets/images/planCheckMarkSelected.svg'; import CheckDarkIcon from 'src/assets/images/check-dark-icon.svg'; import usePlan from 'src/hooks/usePlan'; -import { SubscriptionTier } from 'src/models/enums/SubscriptionTier'; -import UpgradeSubscription from '../InheritanceToolsAndTips/components/UpgradeSubscription'; import { MiniscriptTypes } from 'src/services/wallets/enums'; import WalletUtilities from 'src/services/wallets/operations/utils'; import useVault from 'src/hooks/useVault'; @@ -54,9 +49,7 @@ export function NumberInput({ value, onDecrease, onIncrease }) { backgroundColor={isDarkMode ? Colors.primaryCream : Colors.secondaryLightGrey} /> - - + - + ); @@ -66,8 +59,6 @@ function AddNewWallet({ navigation, route }) { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); const { vault: vaultTranslations, common, wallet: walletText, error: errorText } = translations; - const [selectedWalletType, setSelectedWalletType] = useState(''); - const [customConfigModalVisible, setCustomConfigModalVisible] = useState(false); const [showEnhancedOptionsModal, setShowEnhancedOptionsModal] = useState(false); const { vaultId } = route.params || {}; const DashedCtaTextColor = ThemedColor({ name: 'DashedCtaTextColor' }); @@ -113,39 +104,6 @@ function AddNewWallet({ navigation, route }) { } }, [inheritanceKeySelected, emergencyKeySelected, initialTimelockSelected]); - const CREATE_WALLET_OPTIONS = [ - { - icon: , - title: walletText.Singlekey, - onPress: () => { - Vibration.vibrate(50); - setScheme({ m: 1, n: 1 }); - setSelectedWalletType('singleKey'); - }, - id: 'singleKey', - }, - { - icon: , - title: walletText.multikey2of3, - onPress: () => { - Vibration.vibrate(50); - setScheme({ m: 2, n: 3 }); - setSelectedWalletType('2Of3'); - }, - id: '2Of3', - }, - { - icon: , - title: walletText.multikey3of5, - onPress: () => { - Vibration.vibrate(50); - setScheme({ m: 3, n: 5 }); - setSelectedWalletType('3Of5'); - }, - id: '3Of5', - }, - ]; - const onDecreaseM = () => { if (scheme.m > 1) { Vibration.vibrate(50); @@ -173,61 +131,68 @@ function AddNewWallet({ navigation, route }) { return ( - + - {CREATE_WALLET_OPTIONS.map((option, index) => ( - - ))} - { - setCustomConfigModalVisible(true); - }} - > - + - - {walletText.selectCustomSetup}{' '} - {selectedWalletType === 'custom' ? `: ${scheme.m} of ${scheme.n}` : ''} - - - + {walletText.totalKeys} + + + {walletText.maxNumberofKeys} + + + + {vaultTranslations.requiredKeys} + + + {vaultTranslations.minimumNumberOfKeysToSignATransaction} + + + - setShowEnhancedOptionsModal(true)} - icon={} - iconWidth={22} - iconHeight={20} - cardStyles={styles.enhancedVaultsCustomStyles} - titleSize={15} - borderColor={DashedCtaBorderColor} - /> + {/* Disabled miniscript options during vault upgrade */} + {!vaultId && ( + setShowEnhancedOptionsModal(true)} + icon={} + iconWidth={22} + iconHeight={20} + cardStyles={styles.enhancedVaultsCustomStyles} + titleSize={15} + borderColor={DashedCtaBorderColor} + /> + )} { if (scheme.m === 1 && emergencyKeySelected) { showToast( @@ -254,59 +219,6 @@ function AddNewWallet({ navigation, route }) { fullWidth /> - setCustomConfigModalVisible(false)} - title={walletText.customWalletTitle} - subTitle={walletText.customWalletDesc} - textColor={`${colorMode}.textGreen`} - subTitleColor={`${colorMode}.modalSubtitleBlack`} - buttonText={common.confirm} - buttonCallback={() => { - setCustomConfigModalVisible(false); - setSelectedWalletType('custom'); - }} - Content={() => { - return ( - - - {walletText.totalKeys} - - - {walletText.maxNumberofKeys} - - - - {vaultTranslations.requiredKeys} - - - {vaultTranslations.minimumNumberOfKeysToSignATransaction} - - - - ); - }} - /> setShowEnhancedOptionsModal(false)} @@ -322,28 +234,6 @@ function AddNewWallet({ navigation, route }) { ); } -const OptionItem = ({ option, colorMode, active }) => { - const borderColor = active ? `${colorMode}.dashedButtonBorderColor` : `${colorMode}.separator`; - return ( - - - - {option.icon} - - - - {option.title} - - - - - ); -}; - const EnhancedSecurityModal = ({ isVisible, onClose, @@ -399,18 +289,6 @@ const EnhancedSecurityModal = ({ Content={() => { return ( - {!isOnL3Above && ( - - { - onClose(); - }} - /> - - )} setPendingInheritanceKeySelected(!pendingInheritanceKeySelected)} @@ -581,13 +459,7 @@ const styles = StyleSheet.create({ marginTop: hp(30), flex: 1, }, - optionIconCtr: { - height: hp(35), - width: wp(35), - alignItems: 'center', - justifyContent: 'center', - borderRadius: 100, - }, + optionCTR: { flexDirection: 'row', paddingHorizontal: wp(15), @@ -639,28 +511,15 @@ const styles = StyleSheet.create({ gap: 10, width: windowWidth * 0.88, }, - upgradeButtonCustomStyles: { - container: { - borderTopWidth: 0, - justifyContent: 'space-between', - }, - learnMoreContainer: { - paddingVertical: hp(3), - paddingHorizontal: wp(14), - fontSize: 13, - }, - unlockAtText: { - fontSize: 15, - verticalAlign: 'bottom', - }, - }, button: { paddingVertical: 10, paddingHorizontal: 20, + alignItems: 'center', + justifyContent: 'center', }, buttonText: { fontSize: 37, - lineHeight: hp(36), + lineHeight: hp(30), textAlign: 'center', verticalAlign: 'middle', }, diff --git a/src/screens/AddWalletScreen/SelectWalletType.tsx b/src/screens/AddWalletScreen/SelectWalletType.tsx new file mode 100644 index 0000000000..df6f7a0234 --- /dev/null +++ b/src/screens/AddWalletScreen/SelectWalletType.tsx @@ -0,0 +1,260 @@ +import { Box, useColorMode } from 'native-base'; +import React, { useContext, useEffect, useState } from 'react'; +import { StyleSheet, TouchableOpacity } from 'react-native'; +import ScreenWrapper from 'src/components/ScreenWrapper'; +import WalletHeader from 'src/components/WalletHeader'; +import { LocalizationContext } from 'src/context/Localization/LocContext'; + +import IconArrow from 'src/assets/images/icon_arrow_grey.svg'; +import IconArrowWhite from 'src/assets/images/icon_arrow_white.svg'; +import { CommonActions, useNavigation } from '@react-navigation/native'; +import Text from 'src/components/KeeperText'; +import { hp, wp } from 'src/constants/responsive'; +import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import ImportWallet from 'src/assets/images/import.svg'; +import ImportWalletGreen from 'src/assets/images/importGreen.svg'; +import CreateWalletIcon from 'src/assets/images/createWallet.svg'; +import CreateVaultIcon from 'src/assets/images/createVault1.svg'; +import CreateMultiVaultIcon from 'src/assets/images/createVault2.svg'; +import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; +import useWallets from 'src/hooks/useWallets'; +import { DerivationPurpose, WalletType } from 'src/services/wallets/enums'; +import { NewWalletInfo } from 'src/store/sagas/wallets'; +import WalletUtilities from 'src/services/wallets/operations/utils'; +import { useAppSelector } from 'src/store/hooks'; +import { getCosignerDetails } from 'src/services/wallets/factories/WalletFactory'; +import { setupKeeperSigner } from 'src/hardware/signerSetup'; +import { useDispatch } from 'react-redux'; +import { addSigningDevice } from 'src/store/sagaActions/vaults'; +import { addNewWallets } from 'src/store/sagaActions/wallets'; +import { useQuery } from '@realm/react'; +import { RealmSchema } from 'src/storage/realm/enum'; +import { getJSONFromRealmObject } from 'src/storage/realm/utils'; +import { resetRealyWalletState } from 'src/store/reducers/bhr'; +import useToastMessage from 'src/hooks/useToastMessage'; +import ToastErrorIcon from 'src/assets/images/toast_error.svg'; + +export const SelectWalletType = ({ navigation, route }) => { + const { colorMode } = useColorMode(); + const { translations } = useContext(LocalizationContext); + const { wallet: walletText } = translations; + const { vaultId } = route.params || {}; + return ( + + + + + + + {!vaultId && ( + navigation.navigate('VaultConfigurationCreation')} /> + )} + + + ); +}; + +export const SelectWalletTypeCards = ({ vaultId = null }) => { + const { colorMode } = useColorMode(); + const { translations } = useContext(LocalizationContext); + const { wallet: walletText } = translations; + const navigation = useNavigation(); + const [loading, setLoading] = useState(false); + const { wallets } = useWallets({ getAll: true }); + const { bitcoinNetworkType } = useAppSelector((state) => state.settings); + const dispatch = useDispatch(); + const { primaryMnemonic } = useQuery(RealmSchema.KeeperApp).map(getJSONFromRealmObject)[0]; + const { relayWalletUpdate, relayWalletError, realyWalletErrorMessage } = useAppSelector( + (state) => state.bhr + ); + const { showToast } = useToastMessage(); + + useEffect(() => { + if (relayWalletUpdate) { + dispatch(resetRealyWalletState()); + setLoading(false); + navigation.dispatch( + CommonActions.reset({ + index: 1, + routes: [{ name: 'Home' }], + }) + ); + } + if (relayWalletError) { + showToast(realyWalletErrorMessage || walletText.walletCreationFailed, ); + setLoading(false); + dispatch(resetRealyWalletState()); + } + }, [relayWalletUpdate, relayWalletError]); + + const createNewHotWallet = () => { + setLoading(true); + setTimeout(() => { + try { + let lastInstanceNum = -1; + wallets.forEach((wallet) => { + if (wallet.type === WalletType.DEFAULT) { + // improves the instance number generation logic(accounts for deleted wallets as well) + lastInstanceNum = Math.max(lastInstanceNum, wallet.derivationDetails.instanceNum); + } + }); + const newWallet: NewWalletInfo = { + walletType: WalletType.DEFAULT, + walletDetails: { + name: `Mobile Wallet ${lastInstanceNum == -1 ? '' : lastInstanceNum + 2}`, + description: '', + derivationPath: WalletUtilities.getDerivationPath( + false, + bitcoinNetworkType, + 0, + DerivationPurpose.BIP84 + ), + instanceNum: lastInstanceNum + 1, + }, + }; + getCosignerDetails(primaryMnemonic as string, lastInstanceNum + 1).then((cosigner) => { + const hw = setupKeeperSigner(cosigner); + if (hw) { + dispatch(addSigningDevice([hw.signer])); + } + }); + dispatch(addNewWallets([newWallet])); + } catch (error) { + console.log('Error'); + setLoading(false); + } + }, 0); + }; + + const createNewVault = () => { + navigation.dispatch( + CommonActions.navigate({ + name: 'AddSigningDevice', + params: { + scheme: { m: 1, n: 1 }, + currentBlockHeight: null, + hasInitialTimelock: false, + isNewSchemeFlow: true, + vaultId, + }, + }) + ); + }; + + const OPTIONS = [ + !vaultId && { + title: walletText.hotWallet, + subtitle: walletText.hotWalletDesc, + icon: , + onPress: createNewHotWallet, + id: 'newWallet', + }, + { + title: walletText.coldStorage, + subtitle: walletText.coldStorageDesc, + icon: , + onPress: createNewVault, + id: 'newVault', + }, + { + title: walletText.multiKeyAdvanced, + subtitle: walletText.multiKeyAdvancedDesc, + icon: , + onPress: () => + navigation.dispatch(CommonActions.navigate('AddNewMultiKeyWallet', { vaultId })), + id: 'newMultiVault', + }, + ].filter(Boolean); + + return ( + <> + + {OPTIONS.map((option, index) => ( + + ))} + + ); +}; + +const OptionItem = ({ option, colorMode }) => { + return ( + + + + {option.icon} + + + {option.title} + + + {option.subtitle} + + + + {colorMode === 'dark' ? : } + + + ); +}; + +const ImportWalletCta = ({ onPress }) => { + const { colorMode } = useColorMode(); + const isDarkMode = colorMode === 'dark'; + const { translations } = useContext(LocalizationContext); + const { wallet: walletText } = translations; + const bg = ThemedColor({ name: 'dashed_CTA_background' }); + return ( + + + + {isDarkMode ? : } + + + + + {walletText.ImportAWallet} + + + {walletText.restoreWalletUsingBackup} + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + justifyContent: 'space-between', + flex: 1, + }, + cardsList: { gap: hp(8), marginTop: hp(20) }, + optionCTR: { + flexDirection: 'row', + padding: hp(20), + alignItems: 'center', + gap: wp(16), + borderRadius: 12, + borderWidth: 1.2, + }, + optionTitle: { + marginBottom: hp(4), + }, + optionRow: { + flexDirection: 'row', + gap: wp(14), + flex: 1, + flexGrow: 1, + }, + ImportCtr: { + borderRadius: 11, + borderWidth: 1, + borderStyle: 'dashed', + flexDirection: 'row', + padding: wp(20), + }, +}); diff --git a/src/screens/Home/HomeScreen.tsx b/src/screens/Home/HomeScreen.tsx index bd93b1f04a..fd31932df5 100644 --- a/src/screens/Home/HomeScreen.tsx +++ b/src/screens/Home/HomeScreen.tsx @@ -38,9 +38,7 @@ function NewHomeScreen({ route }) { const { showToast } = useToastMessage(); const { translations } = useContext(LocalizationContext); const { home: homeTranslation, wallet: walletText, buyBTC: buyBTCText } = translations; - const [selectedOption, setSelectedOption] = useState( - selectedOptionFromRoute || walletText.homeWallets - ); + const [selectedOption, setSelectedOption] = useState(selectedOptionFromRoute || walletText.title); useEffect(() => { if (selectedOptionFromRoute && selectedOptionFromRoute !== selectedOption) { @@ -50,7 +48,7 @@ function NewHomeScreen({ route }) { const getContent = () => { switch (selectedOption) { - case walletText.homeWallets: + case walletText.title: return { content: ( @@ -137,7 +135,7 @@ function NewHomeScreen({ route }) { } }; - const { content, icon } = getContent(); + const { content } = getContent(); useEffect(() => { if (relayWalletError) { @@ -167,7 +165,7 @@ function NewHomeScreen({ route }) { setElectrumErrorVisible={setElectrumErrorVisible} /> - + {content} { primary: { text: common.continue, cta: () => { - navigtaion.navigate('AddNewWallet'); + navigtaion.dispatch(CommonActions.navigate('SelectWalletType')); }, }, }, @@ -154,8 +154,7 @@ const Card = memo(({ uai }: CardProps) => { text: common.backup, cta: () => { if (backupHistory.length === 0) { - navigtaion.navigate('Home', { - selectedOption: 'More', + navigtaion.navigate('BackupSettingsScreen', { isUaiFlow: true, }); } else { diff --git a/src/screens/Home/components/BalanceComponent.tsx b/src/screens/Home/components/BalanceComponent.tsx index 1b4fe33b70..00472d0da8 100644 --- a/src/screens/Home/components/BalanceComponent.tsx +++ b/src/screens/Home/components/BalanceComponent.tsx @@ -9,7 +9,14 @@ import { useAppSelector } from 'src/store/hooks'; import { setCurrencyKind } from 'src/store/reducers/settings'; import Colors from 'src/theme/Colors'; -function BalanceComponent({ balance, isShowAmount, setIsShowAmount, BalanceFontSize, wallet }) { +function BalanceComponent({ + balance, + isShowAmount, + setIsShowAmount, + BalanceFontSize, + wallet, + ctrStyle = undefined, +}) { const dispatch = useDispatch(); const { currencyKind } = useAppSelector((state) => state.settings); @@ -35,7 +42,7 @@ function BalanceComponent({ balance, isShowAmount, setIsShowAmount, BalanceFontS }; return ( - + diff --git a/src/screens/Home/components/CurrencyInfo.tsx b/src/screens/Home/components/CurrencyInfo.tsx index 5cde046bb0..1914b32781 100644 --- a/src/screens/Home/components/CurrencyInfo.tsx +++ b/src/screens/Home/components/CurrencyInfo.tsx @@ -19,6 +19,7 @@ interface ICurrencyInfo { balanceMaxWidth?: number; wallet?: any; variation?: 'light' | 'green' | 'dark' | 'grey' | 'slateGreen' | 'richBlack'; + medium?: boolean; } function CurrencyInfo({ hideAmounts, @@ -30,6 +31,7 @@ function CurrencyInfo({ balanceMaxWidth, wallet, variation = 'grey', + medium = false, }: ICurrencyInfo) { const { getSatUnit, getBalance, getCurrencyIcon } = useBalance(); return ( @@ -45,6 +47,7 @@ function CurrencyInfo({ color={color} style={{ fontSize, paddingVertical: 5, maxWidth: balanceMaxWidth || null }} bold={bold} + medium={medium} numberOfLines={1} testID="text_balance" > diff --git a/src/screens/Home/components/Keys/ManageKeys.tsx b/src/screens/Home/components/Keys/ManageKeys.tsx index 051b26e4a1..46534c28eb 100644 --- a/src/screens/Home/components/Keys/ManageKeys.tsx +++ b/src/screens/Home/components/Keys/ManageKeys.tsx @@ -18,6 +18,9 @@ import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityI import { SignerType } from 'src/services/wallets/enums'; import { setShowTipModal } from 'src/store/reducers/settings'; import config from 'src/utils/service-utilities/config'; +import { FAB } from 'src/components/FAB'; +import Plus from 'src/assets/images/plusRound.svg'; +import { wp } from 'src/constants/responsive'; const ManageKeys = ({ addedSigner }) => { const { colorMode } = useColorMode(); @@ -96,26 +99,39 @@ const ManageKeys = ({ addedSigner }) => { }, []); return ( - - - - - ( - - )} - /> + <> + + + + + ( + + )} + /> - - {inProgress && } - + + {inProgress && } + + + } /> + + ); }; @@ -124,6 +140,7 @@ export default ManageKeys; const styles = StyleSheet.create({ containerWrapper: { paddingHorizontal: '4.5%', + flex: 1, }, contentContainer: { flexDirection: 'row', diff --git a/src/screens/Home/components/Keys/SignerList.tsx b/src/screens/Home/components/Keys/SignerList.tsx index 0aa58f14aa..58b70acd79 100644 --- a/src/screens/Home/components/Keys/SignerList.tsx +++ b/src/screens/Home/components/Keys/SignerList.tsx @@ -21,7 +21,7 @@ import { RealmSchema } from 'src/storage/realm/enum'; import { getJSONFromRealmObject } from 'src/storage/realm/utils'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; -const SignerList = ({ navigation, handleModalOpen }) => { +const SignerList = ({ navigation, handleModalOpen, showAddSigner = true }) => { const { signers } = useSigners('', false); const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); @@ -94,17 +94,19 @@ const SignerList = ({ navigation, handleModalOpen }) => { /> ); })} - } - iconWidth={33} - iconHeight={30} - customStyle={customStyle} - /> + {showAddSigner && ( + } + iconWidth={33} + iconHeight={30} + customStyle={customStyle} + /> + )} { + const { colorMode } = useColorMode(); + const { translations } = useContext(LocalizationContext); + const { common } = translations; + const { Tips } = useSettingKeeper(); + + return ( + + + + + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { flex: 1 }, + header: { + marginBottom: 18, + }, +}); diff --git a/src/screens/Home/components/Settings/BackupSettinsScreen.tsx b/src/screens/Home/components/Settings/BackupSettinsScreen.tsx new file mode 100644 index 0000000000..e4314735a3 --- /dev/null +++ b/src/screens/Home/components/Settings/BackupSettinsScreen.tsx @@ -0,0 +1,59 @@ +import { Box, useColorMode } from 'native-base'; +import React, { useContext, useEffect } from 'react'; +import { StyleSheet } from 'react-native'; +import ScreenWrapper from 'src/components/ScreenWrapper'; +import WalletHeader from 'src/components/WalletHeader'; +import SettingCard from './Component/SettingCard'; +import { useSettingKeeper } from 'src/hooks/useSettingKeeper'; +import { LocalizationContext } from 'src/context/Localization/LocContext'; +import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; +import { useAppSelector } from 'src/store/hooks'; +import SettingModal from './Component/SettingModal'; + +export const BackupSettingsScreen = ({ navigation, route }) => { + const { colorMode } = useColorMode(); + const { translations } = useContext(LocalizationContext); + const { inheritancePlanning } = translations; + const { BackAndRecovery, DeleteBackupModal, confirmPass, setConfirmPass } = useSettingKeeper(); + const { backupAllLoading } = useAppSelector((state) => state.bhr); + + const isUaiFlow: boolean = route.params?.isUaiFlow ?? false; + + useEffect(() => { + return () => { + if (isUaiFlow) { + navigation.setParams({ isUaiFlow: false }); + } + }; + }, []); + + return ( + + + + + + + + + {DeleteBackupModal} + + + ); +}; + +const styles = StyleSheet.create({ + container: { flex: 1 }, + header: { + marginBottom: 18, + }, +}); diff --git a/src/screens/Home/components/Settings/AppSettings.tsx b/src/screens/Home/components/Settings/GeneralSettingsScreen.tsx similarity index 85% rename from src/screens/Home/components/Settings/AppSettings.tsx rename to src/screens/Home/components/Settings/GeneralSettingsScreen.tsx index cfe93dcc7f..3b58dd45d1 100644 --- a/src/screens/Home/components/Settings/AppSettings.tsx +++ b/src/screens/Home/components/Settings/GeneralSettingsScreen.tsx @@ -1,31 +1,33 @@ import { Box, useColorMode } from 'native-base'; import React, { useContext, useState } from 'react'; -import { Alert, Pressable, StyleSheet } from 'react-native'; +import { Alert, Pressable, ScrollView, StyleSheet } from 'react-native'; import ScreenWrapper from 'src/components/ScreenWrapper'; import WalletHeader from 'src/components/WalletHeader'; -import { LocalizationContext } from 'src/context/Localization/LocContext'; import SettingCard from './Component/SettingCard'; import { useSettingKeeper } from 'src/hooks/useSettingKeeper'; -import { hp, wp } from 'src/constants/responsive'; -import Text from 'src/components/KeeperText'; -import CheckBoxActive from 'src/assets/images/checkbox_active.svg'; -import CheckBoxInactive from 'src/assets/images/checkbox_inactive.svg'; -import KeeperModal from 'src/components/KeeperModal'; -import Buttons from 'src/components/Buttons'; -import { NetworkType } from 'src/services/wallets/enums'; -import { useAppSelector } from 'src/store/hooks'; +import { LocalizationContext } from 'src/context/Localization/LocContext'; +import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import { useDispatch } from 'react-redux'; -import { changeBitcoinNetwork } from 'src/store/sagaActions/settings'; -import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; +import { useAppSelector } from 'src/store/hooks'; import useToastMessage from 'src/hooks/useToastMessage'; +import { NetworkType } from 'src/services/wallets/enums'; +import { changeBitcoinNetwork } from 'src/store/sagaActions/settings'; import TickIcon from 'src/assets/images/tick_icon.svg'; import ToastErrorIcon from 'src/assets/images/toast_error.svg'; -import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; +import KeeperModal from 'src/components/KeeperModal'; +import CheckBoxActive from 'src/assets/images/checkbox_active.svg'; +import CheckBoxInactive from 'src/assets/images/checkbox_inactive.svg'; +import Text from 'src/components/KeeperText'; +import { hp, wp } from 'src/constants/responsive'; +import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; +import Buttons from 'src/components/Buttons'; -const SettingsApp = () => { +export const GeneralSettingsScreen = () => { const { colorMode } = useColorMode(); + const { translations } = useContext(LocalizationContext); + const { settings,common } = translations; + const { General, keysAndwallet,appSetting:settingsList} = useSettingKeeper(); const dispatch = useDispatch(); - const { settings, common } = useContext(LocalizationContext).translations; const { bitcoinNetworkType } = useAppSelector((state) => state.settings); const { showToast } = useToastMessage(); const [networkModeModal, setNetworkModeModal] = useState(false); @@ -33,7 +35,7 @@ const SettingsApp = () => { const [loading, setLoading] = useState(false); let appSetting = [ - ...useSettingKeeper().appSetting, + ...settingsList, { title: settings.networkModeTitle, description: settings.networkModeSubTitle, @@ -87,19 +89,36 @@ const SettingsApp = () => { return ( + - + - + + - - + + { @@ -136,13 +155,10 @@ const SettingsApp = () => { )} /> - ); }; -export default SettingsApp; - const styles = StyleSheet.create({ container: { flex: 1 }, header: { @@ -162,6 +178,7 @@ const styles = StyleSheet.create({ }, }); + const OptionItem = ({ option, colorMode, active }) => ( ( -); +); \ No newline at end of file diff --git a/src/screens/Home/components/Settings/keeperSettings.tsx b/src/screens/Home/components/Settings/keeperSettings.tsx index 6871ed065c..63ea411f81 100644 --- a/src/screens/Home/components/Settings/keeperSettings.tsx +++ b/src/screens/Home/components/Settings/keeperSettings.tsx @@ -1,11 +1,10 @@ -import { Box, ScrollView, useColorMode } from 'native-base'; -import React, { useContext, useEffect } from 'react'; +import { Box, Pressable, useColorMode } from 'native-base'; +import React, { useContext, useState } from 'react'; import Colors from 'src/theme/Colors'; import PlebContainer from './Component/PlebContainer'; import { LocalizationContext } from 'src/context/Localization/LocContext'; -import SettingCard from './Component/SettingCard'; import NavButton from 'src/components/NavButton'; -import { Pressable, StyleSheet } from 'react-native'; +import { FlatList, StyleSheet, TouchableOpacity } from 'react-native'; import openLink from 'src/utils/OpenLink'; import config, { KEEPER_WEBSITE_BASE_URL } from 'src/utils/service-utilities/config'; import Text from 'src/components/KeeperText'; @@ -17,150 +16,256 @@ import Telegram from 'src/assets/images/Telegram.svg'; import TelegramDark from 'src/assets/images/Telegram-white.svg'; import { hp, windowWidth, wp } from 'src/constants/responsive'; import { CommonActions, useNavigation } from '@react-navigation/native'; -import SettingModal from './Component/SettingModal'; -import { useSettingKeeper } from 'src/hooks/useSettingKeeper'; -import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; -import { useAppSelector } from 'src/store/hooks'; import { setShowTipModal } from 'src/store/reducers/settings'; import { useDispatch } from 'react-redux'; import SupportDeveloperIcon from 'src/assets/images/supportDeveloper.svg'; +import { screenWidth } from 'react-native-gifted-charts/src/utils'; +import TipsIcon from 'src/assets/images/setting_tip.svg'; +import InheritanceIcon from 'src/assets/images/setting_inheritance.svg'; +import InheritanceIconLight from 'src/assets/images/setting_inheritance_light.svg'; +import BackupIcon from 'src/assets/images/setting_backup.svg'; +import BackupIconLight from 'src/assets/images/setting_backup_light.svg'; +import GearIcon from 'src/assets/images/setting_gear.svg'; +import GearIconLight from 'src/assets/images/setting_gear_light.svg'; +import UsdtIcon from 'src/assets/images/setting_usdt.svg'; +import UsdtIconLight from 'src/assets/images/setting_usdt_light.svg'; +import Fonts from 'src/constants/Fonts'; +import { FAB } from 'src/components/FAB'; +import KeeperModal from 'src/components/KeeperModal'; +import NewWalletIcon from 'src/assets/images/wallet-white-small.svg'; +import ImportWalletIcon from 'src/assets/images/import.svg'; +import { useUSDTWallets } from 'src/hooks/useUSDTWallets'; +import { USDTWalletType } from 'src/services/wallets/factories/USDTWalletFactory'; +import TickIcon from 'src/assets/images/icon_tick.svg'; +import useToastMessage from 'src/hooks/useToastMessage'; +import ToastErrorIcon from 'src/assets/images/toast_error.svg'; +import CircleIconWrapper from 'src/components/CircleIconWrapper'; -const KeeperSettings = ({ route }) => { +const KeeperSettings = () => { const { colorMode } = useColorMode(); + const isDarKMode = colorMode === 'dark'; const navigation = useNavigation(); const { translations } = useContext(LocalizationContext); - const { signer: signerText, inheritancePlanning, settings, common } = translations; const { - BackAndRecovery, - General, - keysAndwallet, - Tips, - confirmPass, - setConfirmPass, - planData, - DeleteBackupModal, - } = useSettingKeeper(); + settings, + common, + signer: signerText, + inheritancePlanning, + wallet: walletText, + home, + } = translations; + const dispatch = useDispatch(); + const [createUsdtWallet, setCreateUsdtWallet] = useState(false); + const { createWallet } = useUSDTWallets(); + const { showToast } = useToastMessage(); + + const cardItems = [ + { + title: signerText.inheritanceDocuments, + icon: isDarKMode ? : , + onPress: () => navigation.dispatch(CommonActions.navigate('InheritanceDocumentScreen')), + }, + { + title: inheritancePlanning.backupRecovery, + icon: isDarKMode ? : , + onPress: () => navigation.dispatch(CommonActions.navigate('BackupSettingsScreen')), + }, + { + title: settings.General, + icon: isDarKMode ? : , + onPress: () => navigation.dispatch(CommonActions.navigate('GeneralSettingsScreen')), + }, + { + title: walletText.AddUSDTWallet, + icon: isDarKMode ? : , + onPress: () => setCreateUsdtWallet(true), + }, + ]; - const isUaiFlow: boolean = route.params?.isUaiFlow ?? false; + const importUSDTWallet = async (mnemonic) => { + try { + const { newWallet, error } = await createWallet({ + type: USDTWalletType.IMPORTED, + name: 'USDT Wallet', + description: 'Imported USDT Wallet', + importDetails: { + mnemonic, + }, + }); - useEffect(() => { - return () => { - if (isUaiFlow) { - navigation.setParams({ isUaiFlow: false }); + if (newWallet) { + showToast('USDT wallet imported successfully!', ); + setTimeout(() => { + navigation.dispatch( + CommonActions.navigate({ + name: 'Home', + params: { selectedOption: walletText.title }, + }) + ); + }, 900); + } else { + throw new Error(error); } - }; - }, []); // Empty dependency array means this runs once on mount + } catch (err) { + showToast(`Failed to import USDT wallet: ${err.message}`, ); + } + }; - const { backupAllLoading } = useAppSelector((state) => state.bhr); - const dispatch = useDispatch(); + const CREATE_USDT_WALLET_OPTIONS = [ + { + title: walletText.createWallet, + subtitle: 'Create a new USDT wallet', + icon: , + onPress: () => { + navigation.dispatch(CommonActions.navigate('addUsdtWallet')); + setCreateUsdtWallet(false); + }, + id: 'usdtnewWallet', + }, + { + title: home.ImportWallet, + subtitle: walletText.restoreExistingWallet, + icon: , + onPress: () => { + setCreateUsdtWallet(false); + navigation.dispatch( + CommonActions.navigate({ + name: 'EnterSeedScreen', + params: { + isImport: true, + isUSDTWallet: true, + importSeedCta: importUSDTWallet, + }, + }) + ); + }, + id: 'usdtimportWallet', + }, + ]; return ( - - - dispatch(setShowTipModal({ status: true, address: config.ADDRESS.settings })) - } - icon={} - showDot={false} - /> - - - - - - - : } - heading="Telegram" - link="https://telegram.me/bitcoinkeeper" + <> + + + + dispatch(setShowTipModal({ status: true, address: config.ADDRESS.settings })) + } + icon={} + showDot={false} /> - : } - heading="Twitter" - link="https://twitter.com/bitcoinKeeper_" - /> - : } - heading="Nostr" - link="https://primal.net/p/npub1mlzukkwhuhl3y7wd6kw20fz6s99l8d0uqtj4sskhvaaud8rwcuuszt2t6p" + + { + return ( + + {item.icon} + + {item.title} + + + ); + }} + numColumns={2} /> + + + : } + heading="Telegram" + link="https://telegram.me/bitcoinkeeper" + /> + : } + heading="Twitter" + link="https://twitter.com/bitcoinKeeper_" + /> + : } + heading="Nostr" + link="https://primal.net/p/npub1mlzukkwhuhl3y7wd6kw20fz6s99l8d0uqtj4sskhvaaud8rwcuuszt2t6p" + /> + - - {common.disclaimer} - + + {common.disclaimer} + - - openLink(`${KEEPER_WEBSITE_BASE_URL}/terms-of-service/`)} - testID="btn_termsCondition" - > - + openLink(`${KEEPER_WEBSITE_BASE_URL}/terms-of-service/`)} + testID="btn_termsCondition" > - {common.TermsConditions} - - - | - openLink(`${KEEPER_WEBSITE_BASE_URL}/privacy-policy/`)} - testID="btn_privacyPolicy" - > - + {common.TermsConditions} + + + | + openLink(`${KEEPER_WEBSITE_BASE_URL}/privacy-policy/`)} + testID="btn_privacyPolicy" > - {common.PrivacyPolicy} - - + + {common.PrivacyPolicy} + + + - + navigation.dispatch(CommonActions.navigate('AppTipsScreen'))} + icon={} + /> + + setCreateUsdtWallet(false)} + textColor={`${colorMode}.textGreen`} + subTitleColor={`${colorMode}.modalSubtitleBlack`} + showCloseIcon + Content={() => ( + + {CREATE_USDT_WALLET_OPTIONS.map((option, index) => ( + + ))} + + )} /> - {DeleteBackupModal} - - + ); }; export default KeeperSettings; const styles = StyleSheet.create({ + ctr: { flex: 1, justifyContent: 'space-between' }, bottomNav: { width: windowWidth * 0.88, flexDirection: 'row', @@ -185,4 +290,85 @@ const styles = StyleSheet.create({ textAlign: 'center', marginVertical: hp(10), }, + // ---- + columnGap: { gap: 10 }, + column: { + justifyContent: 'space-between', + }, + cardCtr: { + width: windowWidth * 0.89, + alignSelf: 'center', + }, + card: { + width: (screenWidth - 60) / 2, + paddingHorizontal: wp(13), + paddingVertical: wp(26), + alignItems: 'flex-start', + borderRadius: 10, + position: 'relative', + borderWidth: 1, + }, + cardIcon: { + height: wp(40), + width: wp(40), + borderRadius: 40, + backgroundColor: 'rgba(47, 79, 79, 0.1)', + alignItems: 'center', + justifyContent: 'center', + }, + cardText: { + fontSize: 12, + fontFamily: Fonts.InterMedium, + width: '100%', + gap: 2, + marginTop: hp(12), + }, + // -- + optionTitle: { + marginBottom: hp(5), + }, + optionCTR: { + flexDirection: 'row', + paddingHorizontal: wp(15), + paddingVertical: hp(22), + alignItems: 'center', + gap: wp(16), + borderRadius: 12, + borderWidth: 1, + }, + addWalletOptionsList: { + gap: wp(15), + marginBottom: hp(10), + }, }); + +const OptionItem = ({ option, colorMode }) => { + return ( + + + + + + {option.title} + + + {option.subtitle} + + + + + ); +}; \ No newline at end of file diff --git a/src/screens/Home/components/Wallet/HomeWallet.tsx b/src/screens/Home/components/Wallet/HomeWallet.tsx index 40a78aa4a1..569cbfba4b 100644 --- a/src/screens/Home/components/Wallet/HomeWallet.tsx +++ b/src/screens/Home/components/Wallet/HomeWallet.tsx @@ -1,7 +1,6 @@ import { Box, useColorMode, View } from 'native-base'; import React, { useContext, useState, useEffect } from 'react'; -import { FlatList, StyleSheet, TouchableOpacity } from 'react-native'; -import DashedCta from 'src/components/DashedCta'; +import { FlatList, Pressable, StyleSheet, TouchableOpacity } from 'react-native'; import WalletCard from './WalletCard'; import Colors from 'src/theme/Colors'; import useWallets from 'src/hooks/useWallets'; @@ -10,39 +9,32 @@ import { Wallet } from 'src/services/wallets/interfaces/wallet'; import { Vault } from 'src/services/wallets/interfaces/vault'; import useWalletAsset from 'src/hooks/useWalletAsset'; -import { EntityKind, VisibilityType, WalletType } from 'src/services/wallets/enums'; -import { useNavigation, useFocusEffect, CommonActions } from '@react-navigation/native'; -import KeeperModal from 'src/components/KeeperModal'; +import { EntityKind, VaultType, VisibilityType } from 'src/services/wallets/enums'; +import { useNavigation, CommonActions } from '@react-navigation/native'; import Text from 'src/components/KeeperText'; -import { hp, windowWidth, wp } from 'src/constants/responsive'; - -import NewWalletIcon from 'src/assets/images/wallet-white-small.svg'; -import ImportWalletIcon from 'src/assets/images/import.svg'; -import CollaborativeWalletIcon from 'src/assets/images/collaborative_vault_white.svg'; +import { hp, wp } from 'src/constants/responsive'; import { useAppSelector } from 'src/store/hooks'; -import { resetCollaborativeSession } from 'src/store/reducers/vaults'; import { useDispatch } from 'react-redux'; -import { autoSyncWallets, refreshWallets } from 'src/store/sagaActions/wallets'; +import { autoSyncWallets } from 'src/store/sagaActions/wallets'; import { RefreshControl } from 'react-native'; import { ELECTRUM_CLIENT } from 'src/services/electrum/client'; import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; -import CircleIconWrapper from 'src/components/CircleIconWrapper'; -import ThemedColor from 'src/components/ThemedColor/ThemedColor'; -import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import { LocalizationContext } from 'src/context/Localization/LocContext'; -import BitCoinWalletLogo from 'src/assets/images/bitcoin-wallet-logo.svg'; -import UsdtWalletLogo from 'src/assets/images/usdt-wallet-logo.svg'; import { useUSDTWallets } from 'src/hooks/useUSDTWallets'; import { getAvailableBalanceUSDTWallet, USDTWallet, - USDTWalletSupportedNetwork, - USDTWalletType, } from 'src/services/wallets/factories/USDTWalletFactory'; import useToastMessage from 'src/hooks/useToastMessage'; -import TickIcon from 'src/assets/images/icon_tick.svg'; import ToastErrorIcon from 'src/assets/images/toast_error.svg'; +import Fonts from 'src/constants/Fonts'; +import CreateWalletIllustration from 'src/assets/images/createWalletIllustration.svg'; +import { resetRealyWalletState } from 'src/store/reducers/bhr'; +import HelpGreen from 'src/assets/images/helpGreen.svg'; +import { SelectWalletTypeCards } from 'src/screens/AddWalletScreen/SelectWalletType'; +import { FAB } from 'src/components/FAB'; +import Plus from 'src/assets/images/plusRound.svg'; const HomeWallet = () => { const { colorMode } = useColorMode(); @@ -50,24 +42,18 @@ const HomeWallet = () => { const navigation = useNavigation(); const { wallets } = useWallets({ getAll: true }); const { translations } = useContext(LocalizationContext); - const { wallet: walletText, home, common, usdtWalletText } = translations; + const { wallet: walletText } = translations; const { getWalletCardGradient, getWalletTags } = useWalletAsset(); const { allVaults } = useVault({ includeArchived: false, getFirst: true, getHiddenWallets: false, }); - const { usdtWallets, createWallet } = useUSDTWallets(); - const { collaborativeSession } = useAppSelector((state) => state.vault); - const { bitcoinNetworkType } = useAppSelector((state) => state.settings); + const { usdtWallets } = useUSDTWallets(); const dispatch = useDispatch(); - const [showAddWalletModal, setShowAddWalletModal] = useState(false); - const [collabSessionExistsModalVisible, setCollabSessionExistsModalVisible] = useState(false); const [pullRefresh, setPullRefresh] = useState(false); const { walletSyncing } = useAppSelector((state) => state.wallet); - const [pickWalletType, setPickWalletType] = useState(false); - const [createUsdtWallet, setCreateUsdtWallet] = useState(false); const syncing = ELECTRUM_CLIENT.isClientConnected && Object.values(walletSyncing).some((isSyncing) => isSyncing); @@ -81,25 +67,24 @@ const HomeWallet = () => { ...usdtWallets, ].filter((item) => item !== null); const [isShowAmount, setIsShowAmount] = useState(false); - const DashedCta_hexagonBackgroundColor = ThemedColor({ - name: 'DashedCta_hexagonBackgroundColor', - }); - const dashed_CTA_background = ThemedColor({ - name: 'dashed_CTA_background', - }); + const [loading, setLoading] = useState(false); + const { relayWalletUpdate, relayWalletError, realyWalletErrorMessage } = useAppSelector( + (state) => state.bhr + ); + const { showToast } = useToastMessage(); - const handleCollaborativeWalletCreation = () => { - setShowAddWalletModal(false); - if (Object.keys(collaborativeSession.signers).length > 0) { - setCollabSessionExistsModalVisible(true); - } else { - dispatch(resetCollaborativeSession()); - setTimeout(() => { - navigation.navigate('SetupCollaborativeWallet'); - }, 500); // delaying navigation by 0.5 second to ensure collaborative session reset + useEffect(() => { + if (relayWalletUpdate) { + dispatch(resetRealyWalletState()); + setLoading(false); } - }; + if (relayWalletError) { + showToast(realyWalletErrorMessage || walletText.walletCreationFailed, ); + setLoading(false); + dispatch(resetRealyWalletState()); + } + }, [relayWalletUpdate, relayWalletError]); const pullDownRefresh = () => { setPullRefresh(true); @@ -108,96 +93,6 @@ const HomeWallet = () => { setPullRefresh(false); }; - const importUSDTWallet = async (mnemonic) => { - try { - const { newWallet, error } = await createWallet({ - type: USDTWalletType.IMPORTED, - name: 'USDT Wallet', - description: 'Imported USDT Wallet', - importDetails: { - mnemonic, - }, - }); - - if (newWallet) { - showToast('USDT wallet imported successfully!', ); - setTimeout(() => { - navigation.dispatch( - CommonActions.navigate({ - name: 'Home', - params: { selectedOption: 'Wallets' }, - }) - ); - }, 900); - } else { - throw new Error(error); - } - } catch (err) { - showToast(`Failed to import USDT wallet: ${err.message}`, ); - } - }; - - const CREATE_WALLET_OPTIONS = [ - { - title: walletText.createWallet, - subtitle: walletText.createWalletDesc, - icon: , - onPress: () => { - setShowAddWalletModal(false); - navigation.navigate('AddNewWallet'); - }, - id: 'newWallet', - }, - { - title: home.ImportWallet, - subtitle: walletText.restoreExistingWallet, - icon: , - onPress: () => { - setShowAddWalletModal(false); - navigation.navigate('VaultConfigurationCreation'); - }, - id: 'importWallet', - }, - { - title: common.collaborativeWallet, - subtitle: walletText.walletWithFamily, - icon: , - onPress: handleCollaborativeWalletCreation, - id: 'collaborativeWallet', - }, - ]; - const CREATE_USDT_WALLET_OPTIONS = [ - { - title: walletText.createWallet, - subtitle: 'Create a new USDT wallet', - icon: , - onPress: () => { - navigation.navigate('addUsdtWallet'); - setCreateUsdtWallet(false); - }, - id: 'usdtnewWallet', - }, - { - title: home.ImportWallet, - subtitle: walletText.restoreExistingWallet, - icon: , - onPress: () => { - setCreateUsdtWallet(false); - navigation.dispatch( - CommonActions.navigate({ - name: 'EnterSeedScreen', - params: { - isImport: true, - isUSDTWallet: true, - importSeedCta: importUSDTWallet, - }, - }) - ); - }, - id: 'usdtimportWallet', - }, - ]; - const renderWalletCard = ({ item }: { item: Wallet | Vault | USDTWallet }) => { const handleWalletPress = (item, navigation) => { if (item.entityKind === EntityKind.VAULT) { @@ -218,8 +113,8 @@ const HomeWallet = () => { hexagonBackgroundColor={ item.entityKind === EntityKind.USDT_WALLET ? Colors.aqualightMarine : Colors.CyanGreen } - iconWidth={42} - iconHeight={38} + iconWidth={33} + iconHeight={30} title={item.presentationData.name} tags={getWalletTags(item)} totalBalance={ @@ -231,25 +126,60 @@ const HomeWallet = () => { wallet={item} isShowAmount={isShowAmount} setIsShowAmount={setIsShowAmount} + tag={getWalletCardSingleTag(item)} /> ); }; + const EmptyWalletComponent = () => { + return ( + + + + + + {walletText.createFirstWalletTitle} + + + {walletText.createFirstWalletSubtitle} + + + + + + {}}> + + + + {walletText.helpMeDecide} + + + + + ); + }; + return ( - - setPickWalletType(true)} - icon={} - iconWidth={22} - iconHeight={20} - cardStyles={styles.DashedCtaStyle} - /> + { keyExtractor={(item, index) => `${item.id || index}`} showsVerticalScrollIndicator={false} ItemSeparatorComponent={() => } + ListEmptyComponent={EmptyWalletComponent} /> - setShowAddWalletModal(false)} - textColor={`${colorMode}.textGreen`} - subTitleColor={`${colorMode}.modalSubtitleBlack`} - showCloseIcon - Content={() => ( - - {CREATE_WALLET_OPTIONS.map((option, index) => ( - - ))} - - )} - /> - setCreateUsdtWallet(false)} - textColor={`${colorMode}.textGreen`} - subTitleColor={`${colorMode}.modalSubtitleBlack`} - showCloseIcon - Content={() => ( - - {CREATE_USDT_WALLET_OPTIONS.map((option, index) => ( - - ))} - - )} - /> - setCollabSessionExistsModalVisible(false)} - title={walletText.collaborativeSessionExists} - subTitle={walletText.collaborativeSessionExistsDesc} - buttonText={common.continueSession} - secondaryButtonText={common.startNew} - secondaryCallback={() => { - setCollabSessionExistsModalVisible(false); - dispatch(resetCollaborativeSession()); - setTimeout(() => { - navigation.navigate('SetupCollaborativeWallet'); - }, 500); - }} - buttonCallback={() => { - setCollabSessionExistsModalVisible(false); - navigation.navigate('SetupCollaborativeWallet'); - }} - /> - setPickWalletType(false)} - title={usdtWalletText.pickWalletType} - subTitle={usdtWalletText.selectCurrency} - textColor={`${colorMode}.textGreen`} - subTitleColor={`${colorMode}.modalSubtitleBlack`} - modalBackground={`${colorMode}.modalWhiteBackground`} - Content={() => ( - - { - setShowAddWalletModal(true); - setPickWalletType(false); - }} - > - - } - backgroundColor={Colors.BrightOrange} - /> - - {usdtWalletText.bitcoinWallet} - - - - {bitcoinNetworkType === USDTWalletSupportedNetwork ? ( - { - setCreateUsdtWallet(true); - setPickWalletType(false); - }} - > - - } - backgroundColor={Colors.DesaturatedTeal} - /> - - {usdtWalletText.dollarWallet} - - - - ) : null} - - )} - /> - - ); -}; - -const OptionItem = ({ option, colorMode }) => { - return ( - - - navigation.dispatch(CommonActions.navigate('SelectWalletType'))} + icon={} /> - - - {option.title} - - - {option.subtitle} - - - - + )} + ); }; @@ -407,42 +205,56 @@ const styles = StyleSheet.create({ walletContainer: { gap: 15, }, - addWalletOptionsList: { - gap: wp(15), - marginBottom: hp(10), - }, - optionTitle: { - marginBottom: hp(5), + createWalletCtr: { + gap: hp(8), + paddingHorizontal: wp(22), }, - optionCTR: { + suggestionCtr: { flexDirection: 'row', - paddingHorizontal: wp(15), - paddingVertical: hp(22), + justifyContent: 'center', alignItems: 'center', - gap: wp(16), - borderRadius: 12, - borderWidth: 1, + borderRadius: 10, + paddingVertical: hp(15), + marginTop: hp(10), + marginBottom: hp(40), + gap: wp(6), }, - customStyle: { - marginBottom: hp(10), - }, - DashedCtaStyle: { - width: windowWidth * 0.88, - }, - walletTypeContainer: { - gap: wp(15), - marginBottom: hp(10), - flexDirection: 'row', - justifyContent: 'center', - alignContent: 'center', + suggestionTxt: { textAlign: 'center' }, + createWalletTitle: { + fontFamily: Fonts.LoraMedium, + fontWeight: '500', }, - typeCard: { - width: wp(148), - height: hp(104), + createWalletSubTitle: { textAlign: 'center' }, + createWalletTxtCtr: { + gap: hp(4), alignItems: 'center', + paddingHorizontal: wp(20), + marginTop: hp(16), + }, + createWalletIllustration: { borderWidth: 1, - justifyContent: 'center', - borderRadius: 12, - gap: wp(10), + padding: wp(20), + borderRadius: wp(16), + marginBottom: hp(2), + alignItems: 'center', }, }); + + +const getWalletCardSingleTag = (wallet: Wallet | Vault | USDTWallet) => { + if (wallet.entityKind === EntityKind.WALLET) return 'Hot Wallet'; + else if (wallet.entityKind === EntityKind.USDT_WALLET) return 'USDT Wallet'; + else if (wallet.entityKind === EntityKind.VAULT) { + switch (wallet.type) { + case VaultType.SINGE_SIG: + return 'Cold Storage'; + case VaultType.COLLABORATIVE: + return 'Collaborative'; + case VaultType.MINISCRIPT: + return 'Advance Storage'; + default: + return 'Wallet'; + } + } + return 'Wallet'; +}; \ No newline at end of file diff --git a/src/screens/Home/components/Wallet/WalletCard.tsx b/src/screens/Home/components/Wallet/WalletCard.tsx index 4db16664b6..a3be4f6219 100644 --- a/src/screens/Home/components/Wallet/WalletCard.tsx +++ b/src/screens/Home/components/Wallet/WalletCard.tsx @@ -26,6 +26,7 @@ type WalletCardProps = { allowHideBalance?: boolean; isShowAmount?: boolean; setIsShowAmount?: () => void; + tag: string; }; const WalletCard: React.FC = ({ @@ -41,6 +42,7 @@ const WalletCard: React.FC = ({ allowHideBalance = true, isShowAmount, setIsShowAmount, + tag, }) => { const defaultHexagonBackgroundColor = Colors.headerWhite; const { getWalletIcon } = useWalletAsset(); @@ -53,40 +55,35 @@ const WalletCard: React.FC = ({ end={{ x: 0.9, y: 1 }} style={[styles.cardContainer]} > - - } - /> - - - - {tags?.map(({ tag, color }, index) => ( - - ))} - - - - - - {description} - + + + } + /> {title} - - {}} - isShowAmount={allowHideBalance ? isShowAmount : true} - balance={totalBalance} - wallet={wallet} - /> + + + + + + {}} + isShowAmount={allowHideBalance ? isShowAmount : true} + balance={totalBalance} + wallet={wallet} + BalanceFontSize={20} + ctrStyle={styles.amount} + /> + ); }; @@ -98,62 +95,47 @@ const styles = StyleSheet.create({ flexDirection: 'column', width: windowWidth * 0.88, height: wp(180), - padding: wp(20), + paddingHorizontal: wp(18), + paddingVertical: wp(16), borderRadius: 15, position: 'relative', overflow: 'hidden', + justifyContent: 'space-between', }, - walletLine: { - position: 'absolute', - top: -15, - right: -25, - zIndex: 0, + topRow: { + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + alignItems: 'flex-start', }, - topLeftContainer: { - position: 'absolute', - top: 20, - left: wp(13), - zIndex: 2, + cardNameCtr: { flexDirection: 'row', - alignItems: 'center', + alignItems: 'flex-start', + gap: wp(6), + maxWidth: '50%', }, - bottomContainer: { + balanceCtr: { position: 'absolute', - bottom: hp(17), + bottom: hp(7), left: wp(16), - right: wp(5), - flexDirection: 'row', - justifyContent: 'space-between', - zIndex: 2, }, - bottomLeft: { - flexDirection: 'column', - left: wp(3), + walletLine: { + position: 'absolute', + top: -15, + right: -25, + zIndex: 0, }, title: { + marginTop: hp(2), fontSize: 15, }, - description: { - fontSize: 12, - }, - bottomRight: { - flexDirection: 'row', - justifyContent: 'flex-end', - flex: 1, - marginTop: hp(5), - }, pillsContainer: { flexDirection: 'row', - position: 'absolute', - top: 20, - right: wp(13), gap: 5, justifyContent: 'flex-end', flexWrap: 'wrap', - width: '80%', }, - secondCard: { - maxWidth: wp(80), + amount: { + marginHorizontal: 0, }, - usdtContainer: {}, }); diff --git a/src/screens/InheritanceToolsAndTips/components/AssistedKeys.tsx b/src/screens/InheritanceToolsAndTips/components/AssistedKeys.tsx index 195bb82def..9668b5f37c 100644 --- a/src/screens/InheritanceToolsAndTips/components/AssistedKeys.tsx +++ b/src/screens/InheritanceToolsAndTips/components/AssistedKeys.tsx @@ -21,14 +21,6 @@ function InheritanceTips({}) { icon: , paragraph2: inheritancePlanning.inheritanceKeyParagraph2, paragraph: inheritancePlanning.inheritanceKeyParagraph1, - callback: () => - navigation.dispatch( - CommonActions.navigate({ - name: 'AddNewWallet', - params: { isAddInheritanceKeyFromParams: true, scheme: { m: 2, n: 3 } }, - }) - ), - buttonIcon: , buttonTitle: inheritancePlanning.inheritanceKeyCtaTitle, note: inheritancePlanning.inheritanceKeyCtaNotes, diff --git a/src/screens/USDT/UsdtAddWallet.tsx b/src/screens/USDT/UsdtAddWallet.tsx index 6f5379840d..3122f72ddd 100644 --- a/src/screens/USDT/UsdtAddWallet.tsx +++ b/src/screens/USDT/UsdtAddWallet.tsx @@ -47,7 +47,7 @@ const AddUsdtWallet = () => { const navigationState = { name: 'Home', - params: { selectedOption: 'Wallets' }, + params: { selectedOption: walletText.title }, }; const handleCreateWallet = async () => { diff --git a/src/screens/USDT/UsdtDetails.tsx b/src/screens/USDT/UsdtDetails.tsx index a2cc4ff269..26ad16c3ba 100644 --- a/src/screens/USDT/UsdtDetails.tsx +++ b/src/screens/USDT/UsdtDetails.tsx @@ -11,12 +11,16 @@ import Transactions from '../WalletDetails/components/Transactions'; import { useUSDTWallets } from 'src/hooks/useUSDTWallets'; import { getAvailableBalanceUSDTWallet } from 'src/services/wallets/factories/USDTWalletFactory'; import WalletDetailHeader from '../WalletDetails/components/WalletDetailHeader'; -import DetailCards from '../WalletDetails/components/DetailCards'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; import MoreCard from '../WalletDetails/components/MoreCard'; import KeeperModal from 'src/components/KeeperModal'; import SwapSvg from 'src/assets/images/swap.svg'; import ActivityIndicatorView from 'src/components/AppActivityIndicator/ActivityIndicatorView'; +import Fonts from 'src/constants/Fonts'; +import Colors from 'src/theme/Colors'; +import SendWhiteIcon from 'src/assets/images/send-btc-white-arrow.svg'; +import ReceiveWhiteIcon from 'src/assets/images/recieve-btc-white-arrow.svg'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; function TransactionsAndUTXOs({ transactions, setPullRefresh, pullRefresh, wallet }) { const [initialLoading, setInitialLoading] = useState(false); @@ -36,6 +40,7 @@ function TransactionsAndUTXOs({ transactions, setPullRefresh, pullRefresh, walle } const UsdtDetails = ({ route }) => { + const insets = useSafeAreaInsets(); const { colorMode } = useColorMode(); const navigation = useNavigation(); const { translations } = useContext(LocalizationContext); @@ -61,25 +66,7 @@ const UsdtDetails = ({ route }) => { description={usdtWallet.presentationData.description} wallet={usdtWallet} /> - - - - navigation.dispatch(CommonActions.navigate('sendUsdt', { usdtWallet })) - } - receiveCallback={() => - navigation.dispatch(CommonActions.navigate('usdtReceive', { usdtWallet })) - } - buyCallback={() => - navigation.dispatch(CommonActions.navigate('buyUstd', { usdtWallet })) - } - wallet={usdtWallet} - /> - - - + {usdtWallet ? ( { )} + + navigation.dispatch(CommonActions.navigate('sendUsdt', { usdtWallet }))} + > + + {common.send} + + navigation.dispatch(CommonActions.navigate('usdtReceive', { usdtWallet }))} + > + + {common.receive} + + setShowMore(false)} @@ -168,8 +174,7 @@ const styles = StyleSheet.create({ paddingHorizontal: 18, }, walletContainer: { - paddingTop: wp(30), - paddingBottom: 20, + marginTop: hp(20), flex: 1, justifyContent: 'space-between', }, @@ -187,9 +192,12 @@ const styles = StyleSheet.create({ }, transactionsContainer: { paddingHorizontal: wp(22), - marginTop: hp(5), - paddingTop: hp(24), borderBottomWidth: 0, + borderWidth: 1, + borderTopLeftRadius: 30, + borderTopRightRadius: 30, + borderColor: Colors.separator, + paddingBottom: hp(50), }, transTitleWrapper: { paddingTop: 5, @@ -229,13 +237,29 @@ const styles = StyleSheet.create({ }, detailCardsContainer: { zIndex: 1000, + paddingTop: hp(5), + paddingBottom: hp(10), }, detailCards: { width: '100%', alignItems: 'center', justifyContent: 'center', + }, + bottomCtr: { position: 'absolute', - bottom: 0, - transform: [{ translateY: hp(50) }], + width: '70%', + borderRadius: 100, + alignSelf: 'center', + flexDirection: 'row', + gap: wp(40), + }, + bottomCta: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + gap: wp(10), + paddingVertical: hp(17), }, + bottomCtaTxt: { fontFamily: Fonts.InterBold, fontSize: 14, color: Colors.headerWhite }, }); diff --git a/src/screens/Vault/ArchivedVault.tsx b/src/screens/Vault/ArchivedVault.tsx index f346bb8e4f..422ec76b99 100644 --- a/src/screens/Vault/ArchivedVault.tsx +++ b/src/screens/Vault/ArchivedVault.tsx @@ -24,7 +24,7 @@ function ArchivedVault({ navigation, route }) { const isSmallDevice = useIsSmallDevices(); const renderArchiveVaults = ({ item }) => ( - + ; function VaultDetails({ navigation, route }: ScreenProps) { + const insets = useSafeAreaInsets(); const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); const { vault: vaultTranslation, common } = translations; @@ -203,7 +209,7 @@ function VaultDetails({ navigation, route }: ScreenProps) { const [timeUntilTimelockExpires, setTimeUntilTimelockExpires] = useState(null); const [showmore, setShowMore] = useState(false); const [loadingMiniscript, setLoadingMiniscript] = useState(false); - + const isArchived = vault.archived; const miniscriptPathSelectorRef = useRef(null); useEffect(() => { @@ -483,9 +489,69 @@ function VaultDetails({ navigation, route }: ScreenProps) { { + updateSchemeCallback={() => { + navigation.dispatch( + CommonActions.navigate({ + name: 'SelectWalletType', + params: { + vaultId, + isAddInheritanceKeyFromParams: + vault.type === VaultType.MINISCRIPT && + vault.scheme?.miniscriptScheme?.usedMiniscriptTypes?.includes( + MiniscriptTypes.INHERITANCE + ), + }, + }) + ); + }} + viewCoinsCallback={() => + navigation.navigate('UTXOManagement', { + data: vault, + routeName: 'Vault', + vaultId, + }) + } + manageKeysCallback={() => { + navigation.dispatch( + CommonActions.navigate({ + name: 'ManageSigners', + params: { vaultId, vaultKeys: vault.signers }, + }) + ); + }} + /> + + + + + syncVault(true)} + pullRefresh={pullRefresh} + vault={vault} + isCollaborativeWallet={isCollaborativeWallet} + /> + + + + + { + + { if (timeUntilTimelockExpires) { setShowTimelockModal(true); return; @@ -501,37 +567,27 @@ function VaultDetails({ navigation, route }: ScreenProps) { navigation.dispatch(CommonActions.navigate('Send', { sender: vault })); } }} - receiveCallback={() => { + > + + {common.send} + + { if (pendingHealthCheckCount >= vault.scheme.m) { setShowHealthCheckModal(true); } else { navigation.dispatch(CommonActions.navigate('Receive', { wallet: vault })); } }} - buyCallback={() => - navigation.dispatch( - CommonActions.navigate({ name: 'BuyBitcoin', params: { wallet: vault } }) - ) - } - /> - - - - - syncVault(true)} - pullRefresh={pullRefresh} - vault={vault} - isCollaborativeWallet={isCollaborativeWallet} - /> + > + + {common.receive} + - - + } + { @@ -715,16 +771,19 @@ const styles = StyleSheet.create({ paddingHorizontal: 20, }, bottomSection: { - paddingTop: wp(65), paddingBottom: 20, flex: 1, justifyContent: 'space-between', }, transactionsContainer: { paddingHorizontal: wp(22), - marginTop: hp(5), - paddingTop: hp(10), + paddingTop: hp(15), + borderWidth: 1, borderBottomWidth: 0, + borderTopLeftRadius: 30, + borderTopRightRadius: 30, + borderColor: Colors.separator, + paddingBottom: hp(50), }, transTitleWrapper: { @@ -942,15 +1001,31 @@ const styles = StyleSheet.create({ }, detailCardsContainer: { zIndex: 1000, + paddingTop: hp(5), + paddingBottom: hp(10), }, detailCards: { width: '100%', alignItems: 'center', justifyContent: 'center', + }, + bottomCtr: { position: 'absolute', - bottom: 0, - transform: [{ translateY: hp(50) }], + width: '70%', + borderRadius: 100, + alignSelf: 'center', + flexDirection: 'row', + gap: wp(40), + }, + bottomCta: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + gap: wp(10), + paddingVertical: hp(17), }, + bottomCtaTxt: { fontFamily: Fonts.InterBold, fontSize: 14, color: Colors.headerWhite }, }); export default SentryErrorBoundary(VaultDetails); diff --git a/src/screens/Vault/VaultMigrationController.tsx b/src/screens/Vault/VaultMigrationController.tsx index 29a5838fdd..63c188d381 100644 --- a/src/screens/Vault/VaultMigrationController.tsx +++ b/src/screens/Vault/VaultMigrationController.tsx @@ -63,7 +63,7 @@ import { resetRealyVaultState } from 'src/store/reducers/bhr'; import { resetVaultMigration } from 'src/store/reducers/vaults'; import KeeperModal from 'src/components/KeeperModal'; import useSigners from 'src/hooks/useSigners'; -import { Box } from 'native-base'; +import { Box, useColorMode } from 'native-base'; import Text from 'src/components/KeeperText'; import { LocalizationContext } from 'src/context/Localization/LocContext'; @@ -113,6 +113,7 @@ function VaultMigrationController({ const [checkAddressModalVisible, setCheckAddressModalVisible] = useState(false); const { vaultSigners } = useSigners(activeVault?.id); const { bitcoinNetworkType } = useAppSelector((state) => state.settings); + const { colorMode } = useColorMode(); const DEVICES_WITH_SCREEN = [ SignerType.BITBOX02, @@ -579,9 +580,9 @@ function VaultMigrationController({ {ErrorText.transferFunds} )} - modalBackground="modalWhiteBackground" - textColor="modalHeaderTitle" - subTitleColor="modalSubtitleBlack" + modalBackground={`${colorMode}.modalWhiteBackground`} + textColor={`${colorMode}.textGreen`} + subTitleColor={`${colorMode}.modalSubtitleBlack`} buttonText="Check address" secondaryButtonText="Transfer funds" buttonCallback={() => { diff --git a/src/screens/Vault/VaultSettings.tsx b/src/screens/Vault/VaultSettings.tsx index 7c259b0b08..6c4e8fd97f 100644 --- a/src/screens/Vault/VaultSettings.tsx +++ b/src/screens/Vault/VaultSettings.tsx @@ -27,8 +27,6 @@ import { LocalizationContext } from 'src/context/Localization/LocContext'; import { trimCWDefaultName } from 'src/utils/utilities'; import { getVaultEnhancedSigners } from 'src/services/wallets/operations/miniscript/default/EnhancedVault'; import WalletHeader from 'src/components/WalletHeader'; -import VaultSetupIcon from 'src/assets/images/vault_setup.svg'; -import PrivateVaultSetupIcon from 'src/assets/privateImages/vault_setup.svg'; import Text from 'src/components/KeeperText'; import { ConciergeTag } from 'src/models/enums/ConciergeTag'; import ConciergeNeedHelp from 'src/assets/images/conciergeNeedHelp.svg'; @@ -42,9 +40,10 @@ import { NfcTech } from 'react-native-nfc-manager'; import { useQuery } from '@realm/react'; import ImportExportLabels from 'src/components/ImportExportLabels'; import ToastErrorIcon from 'src/assets/images/toast_error.svg'; -import { useSelector } from 'react-redux'; +import { useDispatch } from 'react-redux'; import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import { reinstateVault } from 'src/store/sagaActions/vaults'; function VaultSettings({ route }) { const { colorMode } = useColorMode(); const isDarkMode = colorMode === 'dark'; @@ -83,6 +82,7 @@ function VaultSettings({ route }) { const hasInitialTimelock = vault?.scheme?.miniscriptScheme?.usedMiniscriptTypes.includes( MiniscriptTypes.TIMELOCKED ); + const dispatch = useDispatch(); const cleanUp = () => { setVisible(false); @@ -219,13 +219,14 @@ function VaultSettings({ route }) { isDiamond: false, onPress: () => navigation.dispatch(CommonActions.navigate('ArchivedVault', { vaultId })), }, - !isCanaryWalletType && { - title: vaultText.vaultHideTitle, - description: vaultText.vaultHideDesc, - icon: null, - isDiamond: false, - onPress: () => updateWalletVisibility(), - }, + !isCanaryWalletType && + !vault.archived && { + title: vaultText.vaultHideTitle, + description: vaultText.vaultHideDesc, + icon: null, + isDiamond: false, + onPress: () => updateWalletVisibility(), + }, vault.archivedId && vault.isMigrating && { title: vaultText.archiveWallet, @@ -234,27 +235,6 @@ function VaultSettings({ route }) { isDiamond: false, onPress: () => archiveWallet(), }, - false && // disable update scheme as it gives wrong behavior - !isCanaryWalletType && { - title: vaultText.vaultSchemeTitle, - description: vaultText.vaultSchemeDesc, - icon: null, - isDiamond: false, - onPress: () => - navigation.dispatch( - CommonActions.navigate({ - name: 'AddNewWallet', - params: { - vaultId, - isAddInheritanceKeyFromParams: - vault.type === VaultType.MINISCRIPT && - vault.scheme?.miniscriptScheme?.usedMiniscriptTypes?.includes( - MiniscriptTypes.INHERITANCE - ), - }, - }) - ), - }, hasInitialTimelock && { title: inheritanceKeys.length || emergencyKeys.length @@ -319,6 +299,17 @@ function VaultSettings({ route }) { ); }, }, + + vault.archived && { + title: common.reinstate, + description: common.reinstateDesc, + icon: null, + isDiamond: false, + onPress: () => { + dispatch(reinstateVault(vault.id)); + showToast('Vault reinstated successfully', ); + }, + }, ].filter(Boolean); return ( diff --git a/src/screens/WalletDetails/WalletDetails.tsx b/src/screens/WalletDetails/WalletDetails.tsx index 2a6ca485d7..b991af16da 100644 --- a/src/screens/WalletDetails/WalletDetails.tsx +++ b/src/screens/WalletDetails/WalletDetails.tsx @@ -24,6 +24,11 @@ import { sendPhaseOneReset } from 'src/store/reducers/send_and_receive'; import WalletDetailHeader from './components/WalletDetailHeader'; import DetailCards from './components/DetailCards'; import ThemedColor from 'src/components/ThemedColor/ThemedColor'; +import SendWhiteIcon from 'src/assets/images/send-btc-white-arrow.svg'; +import ReceiveWhiteIcon from 'src/assets/images/recieve-btc-white-arrow.svg'; +import Colors from 'src/theme/Colors'; +import Fonts from 'src/constants/Fonts'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; // TODO: add type definitions to all components function TransactionsAndUTXOs({ transactions, setPullRefresh, pullRefresh, wallet }) { @@ -45,6 +50,7 @@ function TransactionsAndUTXOs({ transactions, setPullRefresh, pullRefresh, walle type ScreenProps = NativeStackScreenProps; function WalletDetails({ route }: ScreenProps) { + const insets = useSafeAreaInsets(); const { colorMode } = useColorMode(); const isDarkMode = colorMode === 'dark'; const navigation = useNavigation(); @@ -134,15 +140,22 @@ function WalletDetails({ route }: ScreenProps) { - navigation.dispatch(CommonActions.navigate('Send', { sender: wallet })) - } - receiveCallback={() => - navigation.dispatch(CommonActions.navigate('Receive', { wallet })) - } - buyCallback={() => + updateSchemeCallback={() => { + navigation.dispatch( + CommonActions.navigate({ + name: 'SelectWalletType', + params: { + vaultId: walletId, + }, + }) + ); + }} + viewCoinsCallback={() => navigation.dispatch( - CommonActions.navigate({ name: 'BuyBitcoin', params: { wallet } }) + CommonActions.navigate('UTXOManagement', { + data: wallet, + routeName: 'Wallet', + }) ) } /> @@ -198,6 +211,25 @@ function WalletDetails({ route }: ScreenProps) { )} + + navigation.dispatch(CommonActions.navigate('Send', { sender: wallet }))} + > + + {common.send} + + navigation.dispatch(CommonActions.navigate('Receive', { wallet }))} + > + + {common.receive} + + ); @@ -211,10 +243,13 @@ const styles = StyleSheet.create({ paddingHorizontal: 18, }, walletContainer: { - paddingTop: wp(60), paddingBottom: 20, flex: 1, justifyContent: 'space-between', + borderWidth: 1, + borderTopLeftRadius: 30, + borderTopRightRadius: 30, + borderColor: Colors.separator, }, addNewWalletText: { fontSize: 12, @@ -233,6 +268,7 @@ const styles = StyleSheet.create({ marginTop: hp(5), paddingTop: hp(10), borderBottomWidth: 0, + paddingBottom: hp(50), }, transTitleWrapper: { paddingTop: 5, @@ -267,14 +303,30 @@ const styles = StyleSheet.create({ }, detailCardsContainer: { zIndex: 1000, + paddingTop: hp(5), + paddingBottom: hp(10), }, detailCards: { width: '100%', alignItems: 'center', justifyContent: 'center', + }, + bottomCtr: { position: 'absolute', - bottom: 0, - transform: [{ translateY: hp(50) }], + width: '70%', + borderRadius: 100, + alignSelf: 'center', + flexDirection: 'row', + gap: wp(40), + }, + bottomCta: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'flex-end', + gap: wp(10), + paddingVertical: hp(17), }, + bottomCtaTxt: { fontFamily: Fonts.InterBold, fontSize: 14, color: Colors.headerWhite }, }); export default SentryErrorBoundary(WalletDetails); diff --git a/src/screens/WalletDetails/components/DetailCards.tsx b/src/screens/WalletDetails/components/DetailCards.tsx index f0c2baa636..2886a3ae14 100644 --- a/src/screens/WalletDetails/components/DetailCards.tsx +++ b/src/screens/WalletDetails/components/DetailCards.tsx @@ -2,79 +2,72 @@ import { Box, useColorMode } from 'native-base'; import React, { useContext } from 'react'; import { StyleSheet, TouchableOpacity } from 'react-native'; import Text from 'src/components/KeeperText'; -import { hp, wp } from 'src/constants/responsive'; +import { hp, windowWidth, wp } from 'src/constants/responsive'; import { LocalizationContext } from 'src/context/Localization/LocContext'; -import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; import { EntityKind } from 'src/services/wallets/enums'; -import { CommonActions, useNavigation } from '@react-navigation/native'; +import CoinIcon from 'src/assets/images/coins.svg'; +import SignerIcon from 'src/assets/images/keys-icon.svg'; +import CircleIconWrapper from 'src/components/CircleIconWrapper'; +import UpdateSchemeIcon from 'src/assets/images/updateScheme.svg'; interface Props { - setShowMore?: (value: boolean) => void; - sendCallback?: () => void; - receiveCallback?: () => void; - buyCallback?: () => void; + updateSchemeCallback?: () => void; + viewCoinsCallback?: () => void; + manageKeysCallback?: () => void; disabled?: boolean; wallet?: any; } const DetailCards = ({ - setShowMore, - sendCallback, - receiveCallback, - buyCallback, + updateSchemeCallback, + viewCoinsCallback, + manageKeysCallback, disabled, wallet, }: Props) => { const { colorMode } = useColorMode(); const { translations } = useContext(LocalizationContext); - const { usdtWalletText, buyBTC: buyBTCText, common } = translations; - const navigation = useNavigation(); + const { common } = translations; const CardsData = [ - { + updateSchemeCallback && { id: 1, - icon: 'send_Btc_arrow', - title: - wallet?.entityKind === EntityKind.USDT_WALLET - ? usdtWalletText.sendUsdt - : buyBTCText.sendBtc, - callback: () => { - sendCallback?.(); - }, + icon: ( + } + backgroundColor={`${colorMode}.pantoneGreen`} + /> + ), + title: 'Update Wallet', // + callback: updateSchemeCallback, disableOption: disabled, }, - { + viewCoinsCallback && { id: 2, - icon: 'recieve_Btc_arrow', - title: - wallet?.entityKind === EntityKind.USDT_WALLET - ? usdtWalletText.recieveUSdt - : buyBTCText.recieveBtc, - callback: () => { - receiveCallback?.(); - }, + icon: ( + } + backgroundColor={`${colorMode}.pantoneGreen`} + /> + ), + title: common.viewAllCoins, + callback: viewCoinsCallback, disableOption: disabled, }, - { - id: 4, - icon: wallet?.entityKind === EntityKind.WALLET ? 'view_coins' : 'more_Btc_icon', - title: - wallet?.entityKind === EntityKind.WALLET - ? common.viewAllCoins - : wallet?.entityKind === EntityKind.USDT_WALLET - ? usdtWalletText.moreOption - : buyBTCText.moreOptions, - callback: () => { - wallet?.entityKind === EntityKind.WALLET - ? navigation.dispatch( - CommonActions.navigate('UTXOManagement', { - data: wallet, - routeName: 'Wallet', - }) - ) - : setShowMore?.(true); - }, - disableOption: false, + manageKeysCallback && { + id: 3, + icon: ( + } + backgroundColor={`${colorMode}.pantoneGreen`} + /> + ), + title: common.manageKeys, + callback: manageKeysCallback, + disableOption: disabled, }, ].filter(Boolean); @@ -85,7 +78,7 @@ const DetailCards = ({ return ( - {CardsData.map(({ id, icon: Icon, title, callback, disableOption }) => ( + {CardsData.map(({ id, icon, title, callback, disableOption }) => ( - - + {icon} + {title} @@ -121,10 +114,8 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', margin: wp(4), - width: wp(80), - height: hp(100), - paddingHorizontal: wp(8), - paddingVertical: 12, + width: windowWidth * 0.27, + padding: wp(11), shadowColor: 'rgba(0, 0, 0, 0.12)', shadowOffset: { width: 0, height: 4 }, shadowOpacity: 1, @@ -136,5 +127,6 @@ const styles = StyleSheet.create({ marginTop: 8, textAlign: 'center', maxWidth: '100%', + fontWeight: '500', }, }); diff --git a/src/screens/WalletDetails/components/WalletDetailHeader.tsx b/src/screens/WalletDetails/components/WalletDetailHeader.tsx index 9b66e5af3b..554dec2b0f 100644 --- a/src/screens/WalletDetails/components/WalletDetailHeader.tsx +++ b/src/screens/WalletDetails/components/WalletDetailHeader.tsx @@ -1,20 +1,23 @@ -import { Box } from 'native-base'; +import { Box, StatusBar, useColorMode } from 'native-base'; import React from 'react'; import { StyleSheet, TouchableOpacity } from 'react-native'; -import { hp, wp } from 'src/constants/responsive'; -import BackWhiteButton from 'src/assets/images/leftarrowCampainlight.svg'; -import WhiteSettingIcon from 'src/assets/privateImages/setting_icon_white.svg'; -import { useNavigation } from '@react-navigation/native'; +import { hp, windowWidth, wp } from 'src/constants/responsive'; import LinearGradient from 'react-native-linear-gradient'; import CardPill from 'src/components/CardPill'; import Text from 'src/components/KeeperText'; import BalanceComponent from 'src/screens/Home/components/BalanceComponent'; import Colors from 'src/theme/Colors'; +import WalletHeader from 'src/components/WalletHeader'; +import ThemedSvg from 'src/components/ThemedSvg.tsx/ThemedSvg'; +import { EntityKind } from 'src/services/wallets/enums'; +import WalletLine from 'src/assets/images/walletCardLines.svg'; +import HexagonIcon from 'src/components/HexagonIcon'; +import useWalletAsset from 'src/hooks/useWalletAsset'; interface Props { settingCallBack?: () => void; backgroundColor?: any; - tags?: string[]; + tags?: { tag: string; color: string }[]; setIsShowAmount?: any; isShowAmount?: boolean; title?: string; @@ -36,59 +39,71 @@ const WalletDetailHeader = ({ allowHideBalance, wallet, }: Props) => { - const navigation = useNavigation(); + const iconWidth = 40; + const iconHeight = 34; + const { colorMode } = useColorMode(); + const { getWalletIcon } = useWalletAsset(); + const WalletIcon = getWalletIcon(wallet); return ( - - - {/* header */} - - { - navigation.goBack(); - }} - style={styles.backButton} - > - + + + settingCallBack()}> + - { - settingCallBack(); - }} - > - - - - {/* Tags */} - - {tags?.map(({ tag, color }, index) => ( - <> - - - ))} + } + /> + + + + + } + /> + + + + + {tags?.map(({ tag, color }) => ( + + ))} + + + - - + - + {description} {title} - - {}} - isShowAmount={allowHideBalance ? isShowAmount : true} - balance={totalBalance} - BalanceFontSize={22} - wallet={wallet} - /> - + {}} + isShowAmount={allowHideBalance ? isShowAmount : true} + balance={totalBalance} + wallet={wallet} + BalanceFontSize={20} + ctrStyle={styles.amount} + /> - - + + ); }; @@ -97,50 +112,47 @@ const styles = StyleSheet.create({ container: { paddingHorizontal: wp(22), paddingTop: hp(40), - paddingBottom: hp(90), }, - header: { + cardContainer: { + flexDirection: 'column', + width: windowWidth * 0.88, + height: wp(180), + paddingHorizontal: wp(18), + paddingVertical: wp(16), + borderRadius: 15, + position: 'relative', + overflow: 'hidden', + justifyContent: 'space-between', + marginTop: hp(5), + }, + topRow: { + flex: 1, flexDirection: 'row', - alignItems: 'center', justifyContent: 'space-between', - marginTop: hp(10), + alignItems: 'flex-start', }, - backButton: { - height: hp(44), - width: wp(28), - justifyContent: 'center', + walletLine: { + position: 'absolute', + top: -15, + right: -25, + zIndex: 0, }, - settingBtn: { - paddingHorizontal: 8, - paddingVertical: 16, + title: { + marginTop: hp(2), + fontSize: 16, }, pillsContainer: { flexDirection: 'row', gap: 5, justifyContent: 'flex-end', flexWrap: 'wrap', - marginVertical: hp(20), }, - bottomContainer: { + amount: { + marginHorizontal: 0, + }, + bottomRow: { flexDirection: 'row', justifyContent: 'space-between', - zIndex: 2, - marginTop: hp(10), - }, - - title: { - fontSize: 16, - }, - description: { - fontSize: 14, - marginBottom: hp(5), - }, - bottomRight: { - justifyContent: 'flex-end', - }, - detailCards: { - position: 'absolute', - bottom: '-40%', - zIndex: 100, + alignItems: 'flex-end', }, }); diff --git a/src/store/sagas/storage.ts b/src/store/sagas/storage.ts index 99eaa08f39..3be8d4b81f 100644 --- a/src/store/sagas/storage.ts +++ b/src/store/sagas/storage.ts @@ -95,23 +95,7 @@ export function* setupKeeperAppWorker({ payload }) { yield put(addAccount(appID)); - const defaultWallet: NewWalletInfo = { - walletType: WalletType.DEFAULT, - walletDetails: { - name: 'Mobile Wallet', - description: '', - instanceNum: 0, - derivationPath: WalletUtilities.getDerivationPath( - false, - bitcoinNetworkType, - 0, - DerivationPurpose.BIP84 - ), - }, - }; - const recoveryKeySigner = setupRecoveryKeySigningKey(primaryMnemonic); - yield call(addNewWalletsWorker, { payload: [defaultWallet] }); yield call(addSigningDeviceWorker, { payload: { signers: [recoveryKeySigner] } }); yield put( updateDefaultWalletCreatedByAppId({ appId: appID, networkType: bitcoinNetworkType })