diff --git a/blue_modules/analytics.ts b/blue_modules/analytics.ts index 480ac5103..5da0ac7d9 100644 --- a/blue_modules/analytics.ts +++ b/blue_modules/analytics.ts @@ -12,26 +12,24 @@ const BlueApp = BlueAppClass.getInstance(); */ let userHasOptedOut: boolean = false; -if (process.env.NODE_ENV !== 'development') { - (async () => { - const uniqueID = await getUniqueId(); - const doNotTrack = await BlueApp.isDoNotTrackEnabled(); +(async () => { + const uniqueID = await getUniqueId(); + const doNotTrack = await BlueApp.isDoNotTrackEnabled(); - if (doNotTrack) { - // dont start Bugsnag at all - return; - } + if (doNotTrack) { + // dont start Bugsnag at all + return; + } - Bugsnag.start({ - user: { - id: uniqueID, - }, - onError: function (event) { - return !userHasOptedOut; - }, - }); - })(); -} + Bugsnag.start({ + user: { + id: uniqueID, + }, + onError: function (event) { + return !userHasOptedOut; + }, + }); +})(); const A = async (event: string) => {}; diff --git a/components/CompanionDelegates.tsx b/components/CompanionDelegates.tsx index c219f81f6..d805604fd 100644 --- a/components/CompanionDelegates.tsx +++ b/components/CompanionDelegates.tsx @@ -1,7 +1,7 @@ import 'react-native-gesture-handler'; // should be on top import { CommonActions } from '@react-navigation/native'; -import React, { lazy, Suspense, useCallback, useEffect, useRef } from 'react'; +import { useCallback, useEffect, useRef } from 'react'; import { AppState, AppStateStatus, Linking } from 'react-native'; import A from '../blue_modules/analytics'; import { getClipboardContent } from '../blue_modules/clipboard'; @@ -25,12 +25,10 @@ import { useStorage } from '../hooks/context/useStorage'; import RNQRGenerator from 'rn-qr-generator'; import presentAlert from './Alert'; import useMenuElements from '../hooks/useMenuElements'; -import { useSettings } from '../hooks/context/useSettings'; import useWidgetCommunication from '../hooks/useWidgetCommunication'; import useWatchConnectivity from '../hooks/useWatchConnectivity'; - -const DeviceQuickActions = lazy(() => import('../components/DeviceQuickActions')); -const HandOffComponentListener = lazy(() => import('../components/HandOffComponentListener')); +import useDeviceQuickActions from '../hooks/useDeviceQuickActions'; +import useHandoffListener from '../hooks/useHandoffListener'; const ClipboardContentType = Object.freeze({ BITCOIN: 'BITCOIN', @@ -40,12 +38,13 @@ const ClipboardContentType = Object.freeze({ const CompanionDelegates = () => { const { wallets, addWallet, saveToDisk, fetchAndSaveWalletTransactions, refreshAllWalletTransactions, setSharedCosigner } = useStorage(); const appState = useRef(AppState.currentState); - const { isHandOffUseEnabled, isQuickActionsEnabled } = useSettings(); const clipboardContent = useRef(); useWatchConnectivity(); useWidgetCommunication(); useMenuElements(); + useDeviceQuickActions(); + useHandoffListener(); const processPushNotifications = useCallback(async () => { await new Promise(resolve => setTimeout(resolve, 200)); @@ -311,12 +310,7 @@ const CompanionDelegates = () => { }; }, [addListeners]); - return ( - - {isQuickActionsEnabled && } - {isHandOffUseEnabled && } - - ); + return null; }; export default CompanionDelegates; diff --git a/components/Context/SettingsProvider.tsx b/components/Context/SettingsProvider.tsx index a00fd0a87..57203e9cc 100644 --- a/components/Context/SettingsProvider.tsx +++ b/components/Context/SettingsProvider.tsx @@ -6,7 +6,10 @@ import { clearUseURv1, isURv1Enabled, setUseURv1 } from '../../blue_modules/ur'; import { BlueApp } from '../../class'; import { saveLanguage, STORAGE_KEY } from '../../loc'; import { FiatUnit, TFiatUnit } from '../../models/fiatUnit'; -import { getEnabled as getIsDeviceQuickActionsEnabled, setEnabled as setIsDeviceQuickActionsEnabled } from '../DeviceQuickActions'; +import { + getEnabled as getIsDeviceQuickActionsEnabled, + setEnabled as setIsDeviceQuickActionsEnabled, +} from '../../hooks/useDeviceQuickActions'; import { getIsHandOffUseEnabled, setIsHandOffUseEnabled } from '../HandOffComponent'; import { useStorage } from '../../hooks/context/useStorage'; import { BitcoinUnit } from '../../models/bitcoinUnits'; diff --git a/components/DeviceQuickActions.windows.tsx b/components/DeviceQuickActions.windows.tsx deleted file mode 100644 index 1c5057bac..000000000 --- a/components/DeviceQuickActions.windows.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; - -export const DeviceQuickActionsStorageKey = 'DeviceQuickActionsEnabled'; - -interface DeviceQuickActionsFunctions { - popInitialAction: () => void; -} - -export const setEnabled = (): void => {}; - -export const getEnabled = async (): Promise => { - return false; -}; - -const DeviceQuickActions: React.FC & DeviceQuickActionsFunctions = () => { - return null; -}; - -DeviceQuickActions.popInitialAction = (): void => {}; - -export default DeviceQuickActions; diff --git a/components/HandOffComponent.ios.tsx b/components/HandOffComponent.ios.tsx index f96a5241e..0a262f3fe 100644 --- a/components/HandOffComponent.ios.tsx +++ b/components/HandOffComponent.ios.tsx @@ -1,6 +1,6 @@ import React from 'react'; import DefaultPreference from 'react-native-default-preference'; -// @ts-ignore: react-native-handoff is not in the type definition +// @ts-ignore: Handoff is not typed import Handoff from 'react-native-handoff'; import { useSettings } from '../hooks/context/useSettings'; import { GROUP_IO_BLUEWALLET } from '../blue_modules/currency'; @@ -9,32 +9,32 @@ import { HandOffComponentProps } from './types'; const HandOffComponent: React.FC = props => { const { isHandOffUseEnabled } = useSettings(); - - if (process.env.NODE_ENV === 'development') { - console.debug('HandOffComponent: render'); - } - if (isHandOffUseEnabled) { - return ; - } - return null; + console.debug('HandOffComponent is rendering.'); + return isHandOffUseEnabled ? : null; }; const MemoizedHandOffComponent = React.memo(HandOffComponent); export const setIsHandOffUseEnabled = async (value: boolean) => { - await DefaultPreference.setName(GROUP_IO_BLUEWALLET); - await DefaultPreference.set(BlueApp.HANDOFF_STORAGE_KEY, value.toString()); - console.debug('setIsHandOffUseEnabledAsyncStorage', value); + try { + await DefaultPreference.setName(GROUP_IO_BLUEWALLET); + await DefaultPreference.set(BlueApp.HANDOFF_STORAGE_KEY, value.toString()); + console.debug('setIsHandOffUseEnabled', value); + } catch (error) { + console.error('Error setting handoff enabled status:', error); + throw error; // Propagate error to caller + } }; export const getIsHandOffUseEnabled = async (): Promise => { try { await DefaultPreference.setName(GROUP_IO_BLUEWALLET); - const isEnabledValue = (await DefaultPreference.get(BlueApp.HANDOFF_STORAGE_KEY)) ?? false; - console.debug('getIsHandOffUseEnabled', isEnabledValue); - return isEnabledValue === 'true'; - } catch (e) { - console.debug('getIsHandOffUseEnabled error', e); + const isEnabledValue = await DefaultPreference.get(BlueApp.HANDOFF_STORAGE_KEY); + const result = isEnabledValue === 'true'; + console.debug('getIsHandOffUseEnabled', result); + return result; + } catch (error) { + console.error('Error getting handoff enabled status:', error); return false; } }; diff --git a/components/HandOffComponentListener.ios.tsx b/components/HandOffComponentListener.ios.tsx deleted file mode 100644 index 66a08b230..000000000 --- a/components/HandOffComponentListener.ios.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useEffect, useCallback } from 'react'; -import { NativeEventEmitter, NativeModules } from 'react-native'; -import { useStorage } from '../hooks/context/useStorage'; -import { useExtendedNavigation } from '../hooks/useExtendedNavigation'; -import { HandOffActivityType } from './types'; - -interface UserActivityData { - activityType: HandOffActivityType; - userInfo: { - address?: string; - xpub?: string; - }; -} - -const { EventEmitter } = NativeModules; -const eventEmitter = new NativeEventEmitter(EventEmitter); - -const HandOffComponentListener: React.FC = React.memo(() => { - const { walletsInitialized } = useStorage(); - const { navigate } = useExtendedNavigation(); - - const onUserActivityOpen = useCallback((data: UserActivityData) => { - switch (data.activityType) { - case HandOffActivityType.ReceiveOnchain: - navigate('ReceiveDetailsRoot', { - screen: 'ReceiveDetails', - params: { - address: data.userInfo.address, - }, - }); - break; - case HandOffActivityType.Xpub: - navigate('WalletXpubRoot', { - screen: 'WalletXpub', - params: { - xpub: data.userInfo.xpub, - }, - }); - break; - default: - console.log(`Unhandled activity type: ${data.activityType}`); - break; - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - if (!walletsInitialized) { - return; - } - - const addListeners = () => { - const activitySubscription = eventEmitter.addListener('onUserActivityOpen', onUserActivityOpen); - - // Attempt to fetch the most recent user activity - EventEmitter.getMostRecentUserActivity?.() - .then(onUserActivityOpen) - .catch(() => console.log('No userActivity object sent')); - - return { activitySubscription }; - }; - - const subscriptions = addListeners(); - - return () => { - subscriptions.activitySubscription?.remove(); - }; - }, [walletsInitialized, onUserActivityOpen]); - - return null; -}); - -export default HandOffComponentListener; diff --git a/components/HandOffComponentListener.tsx b/components/HandOffComponentListener.tsx deleted file mode 100644 index 933fc9988..000000000 --- a/components/HandOffComponentListener.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -const HandOffComponentListener: React.FC = () => { - return null; -}; - -export default HandOffComponentListener; diff --git a/components/DeviceQuickActions.tsx b/hooks/useDeviceQuickActions.ts similarity index 77% rename from components/DeviceQuickActions.tsx rename to hooks/useDeviceQuickActions.ts index 36d72d921..55a3e15d4 100644 --- a/components/DeviceQuickActions.tsx +++ b/hooks/useDeviceQuickActions.ts @@ -1,8 +1,8 @@ +import { useEffect } from 'react'; import AsyncStorage from '@react-native-async-storage/async-storage'; import { CommonActions } from '@react-navigation/native'; -import { useEffect } from 'react'; import { DeviceEventEmitter, Linking, Platform } from 'react-native'; -import QuickActions from 'react-native-quick-actions'; +import QuickActions, { ShortcutItem } from 'react-native-quick-actions'; import DeeplinkSchemaMatch from '../class/deeplink-schema-match'; import { TWallet } from '../class/wallets/types'; import useOnAppLaunch from '../hooks/useOnAppLaunch'; @@ -30,16 +30,15 @@ export async function getEnabled(): Promise { } } -function DeviceQuickActions() { +const useDeviceQuickActions = () => { const { wallets, walletsInitialized, isStorageEncrypted, addWallet, saveToDisk, setSharedCosigner } = useStorage(); const { preferredFiatCurrency, isQuickActionsEnabled } = useSettings(); - const { isViewAllWalletsEnabled, getSelectedDefaultWallet } = useOnAppLaunch(); useEffect(() => { if (walletsInitialized) { isStorageEncrypted() - .then((value: boolean | undefined | null) => { + .then(value => { if (value) { removeShortcuts(); } else { @@ -48,7 +47,7 @@ function DeviceQuickActions() { }) .catch(() => removeShortcuts()); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [wallets, walletsInitialized, preferredFiatCurrency, isStorageEncrypted]); useEffect(() => { @@ -57,7 +56,7 @@ function DeviceQuickActions() { popInitialShortcutAction().then(popInitialAction); return () => DeviceEventEmitter.removeAllListeners('quickActionShortcut'); } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [walletsInitialized]); useEffect(() => { @@ -68,7 +67,7 @@ function DeviceQuickActions() { removeShortcuts(); } } - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isQuickActionsEnabled, walletsInitialized]); const popInitialShortcutAction = async (): Promise => { @@ -78,7 +77,7 @@ function DeviceQuickActions() { const popInitialAction = async (data: any): Promise => { if (data) { - const wallet = wallets.find((w: { getID: () => any }) => w.getID() === data.userInfo.url.split('wallet/')[1]); + const wallet = wallets.find(w => w.getID() === data.userInfo.url.split('wallet/')[1]); if (wallet) { NavigationService.dispatch( CommonActions.navigate({ @@ -126,7 +125,7 @@ function DeviceQuickActions() { }; const walletQuickActions = (data: any): void => { - const wallet = wallets.find((w: { getID: () => any }) => w.getID() === data.userInfo.url.split('wallet/')[1]); + const wallet = wallets.find(w => w.getID() === data.userInfo.url.split('wallet/')[1]); if (wallet) { NavigationService.dispatch( CommonActions.navigate({ @@ -153,22 +152,21 @@ function DeviceQuickActions() { if (await getEnabled()) { QuickActions.isSupported((error: null, _supported: any) => { if (error === null) { - const shortcutItems = []; - for (const wallet of wallets.slice(0, 4)) { - shortcutItems.push({ - type: 'Wallets', // Required - title: wallet.getLabel(), // Optional, if empty, `type` will be used instead - subtitle: - wallet.hideBalance || wallet.getBalance() <= 0 - ? '' - : formatBalance(Number(wallet.getBalance()), wallet.getPreferredBalanceUnit(), true), - userInfo: { - url: `bluewallet://wallet/${wallet.getID()}`, // Provide any custom data like deep linking URL - }, - icon: Platform.select({ android: 'quickactions', ios: 'bookmark' }), - }); - } - // @ts-ignore: Fix later + const shortcutItems: ShortcutItem[] = wallets.slice(0, 4).map((wallet, index) => ({ + type: 'Wallets', + title: wallet.getLabel(), + subtitle: + wallet.hideBalance || wallet.getBalance() <= 0 + ? '' + : formatBalance(Number(wallet.getBalance()), wallet.getPreferredBalanceUnit(), true), + userInfo: { + url: `bluewallet://wallet/${wallet.getID()}`, + }, + icon: Platform.select({ + android: 'quickactions', + ios: index === 0 ? 'Favorite' : 'Bookmark', + }) || 'quickactions', + })); QuickActions.setShortcutItems(shortcutItems); } }); @@ -177,7 +175,7 @@ function DeviceQuickActions() { } }; - return null; + return { popInitialAction }; } -export default DeviceQuickActions; +export default useDeviceQuickActions; \ No newline at end of file diff --git a/hooks/useDeviceQuickActions.windows.ts b/hooks/useDeviceQuickActions.windows.ts new file mode 100644 index 000000000..f87b43d14 --- /dev/null +++ b/hooks/useDeviceQuickActions.windows.ts @@ -0,0 +1,17 @@ + +export const DeviceQuickActionsStorageKey = 'DeviceQuickActionsEnabled'; + +export const setEnabled = (): void => {}; + +export const getEnabled = async (): Promise => { + return false; +}; + +const useDeviceQuickActions = () => { + + const popInitialAction = (): void => {}; + return { popInitialAction }; +}; + + +export default useDeviceQuickActions; diff --git a/hooks/useHandoffListener.ios.ts b/hooks/useHandoffListener.ios.ts new file mode 100644 index 000000000..df9ecec3d --- /dev/null +++ b/hooks/useHandoffListener.ios.ts @@ -0,0 +1,63 @@ +import { useEffect, useCallback } from 'react'; +import { NativeEventEmitter, NativeModules } from 'react-native'; +import { useStorage } from '../hooks/context/useStorage'; +import { useExtendedNavigation } from '../hooks/useExtendedNavigation'; +import { HandOffActivityType } from '../components/types'; +import { useSettings } from './context/useSettings'; + +interface UserActivityData { + activityType: HandOffActivityType; + userInfo: { + address?: string; + xpub?: string; + }; +} + +const EventEmitter = NativeModules.EventEmitter; +const eventEmitter = EventEmitter ? new NativeEventEmitter(EventEmitter) : null; + +const useHandoffListener = () => { + const { walletsInitialized } = useStorage(); + const { isHandOffUseEnabled } = useSettings(); + const { navigate } = useExtendedNavigation(); + + const handleUserActivity = useCallback( + (data: UserActivityData) => { + const { activityType, userInfo } = data; + try { + if (activityType === HandOffActivityType.ReceiveOnchain) { + navigate('ReceiveDetailsRoot', { + screen: 'ReceiveDetails', + params: { address: userInfo.address }, + }); + } else if (activityType === HandOffActivityType.Xpub) { + navigate('WalletXpubRoot', { + screen: 'WalletXpub', + params: { xpub: userInfo.xpub }, + }); + } else { + console.debug(`Unhandled activity type: ${activityType}`); + } + } catch (error) { + console.error('Error handling user activity:', error); + } + }, + [navigate], + ); + + useEffect(() => { + if (!walletsInitialized || !isHandOffUseEnabled) return; + + const activitySubscription = eventEmitter?.addListener('onUserActivityOpen', handleUserActivity); + + EventEmitter.getMostRecentUserActivity?.() + .then(handleUserActivity) + .catch(() => console.debug('No userActivity object sent')); + + return () => { + activitySubscription?.remove(); + }; + }, [walletsInitialized, isHandOffUseEnabled, handleUserActivity]); +}; + +export default useHandoffListener; diff --git a/hooks/useHandoffListener.ts b/hooks/useHandoffListener.ts new file mode 100644 index 000000000..f0666c853 --- /dev/null +++ b/hooks/useHandoffListener.ts @@ -0,0 +1,3 @@ +const useHandoffListener = () => {}; + +export default useHandoffListener; diff --git a/package-lock.json b/package-lock.json index 995ecb70b..8025bce67 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "@lodev09/react-native-true-sheet": "github:BlueWallet/react-native-true-sheet#839f2966cee77c0ad99d09609dadb61a338e7f54", "@ngraveio/bc-ur": "1.1.13", "@noble/secp256k1": "1.6.3", - "@react-native-async-storage/async-storage": "2.0.0", + "@react-native-async-storage/async-storage": "2.1.0", "@react-native-clipboard/clipboard": "1.15.0", "@react-native-community/push-notification-ios": "1.11.0", "@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#02592ae", @@ -46,7 +46,7 @@ "coinselect": "3.1.13", "crypto-js": "4.2.0", "dayjs": "1.11.13", - "detox": "20.27.6", + "detox": "20.28.0", "ecpair": "2.0.1", "ecurve": "1.0.6", "electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc", @@ -4507,9 +4507,9 @@ } }, "node_modules/@react-native-async-storage/async-storage": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.0.0.tgz", - "integrity": "sha512-af6H9JjfL6G/PktBfUivvexoiFKQTJGQCtSWxMdivLzNIY94mu9DdiY0JqCSg/LyPCLGKhHPUlRQhNvpu3/KVA==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@react-native-async-storage/async-storage/-/async-storage-2.1.0.tgz", + "integrity": "sha512-eAGQGPTAuFNEoIQSB5j2Jh1zm5NPyBRTfjRMfCN0W1OakC5WIB5vsDyIQhUweKN9XOE2/V07lqTMGsL0dGXNkA==", "license": "MIT", "dependencies": { "merge-options": "^3.0.4" @@ -9731,9 +9731,9 @@ } }, "node_modules/detox": { - "version": "20.27.6", - "resolved": "https://registry.npmjs.org/detox/-/detox-20.27.6.tgz", - "integrity": "sha512-eyVkBC7uFpxgUAuWjvbejwnPOjRHqUWSSE/P0FwsCxWVnrNOSq8IhBnSj82Ic5Dc76CAB+Xw5SWYsHnbhG26Bg==", + "version": "20.28.0", + "resolved": "https://registry.npmjs.org/detox/-/detox-20.28.0.tgz", + "integrity": "sha512-JeUkWNnYE7lqby3S9AeYJP3ttCBKH+qZWACjWXwvSbe3tm6JeXvecVUYkzSoNfC4IzTX5p+rWvG0IPsfOsZSFw==", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -9743,7 +9743,7 @@ "caf": "^15.0.1", "chalk": "^4.0.0", "child-process-promise": "^2.2.0", - "detox-copilot": "^0.0.23", + "detox-copilot": "^0.0.24", "execa": "^5.1.1", "find-up": "^5.0.0", "fs-extra": "^11.0.0", @@ -9790,9 +9790,9 @@ } }, "node_modules/detox-copilot": { - "version": "0.0.23", - "resolved": "https://registry.npmjs.org/detox-copilot/-/detox-copilot-0.0.23.tgz", - "integrity": "sha512-qDSdLwgPUMVawpE0R3agNWd2U69ilTnhf+SodSqqrkmTI0oG67IfkACvwox+K9Slcc8ki6y0Bw6QVBi54MqpaA==", + "version": "0.0.24", + "resolved": "https://registry.npmjs.org/detox-copilot/-/detox-copilot-0.0.24.tgz", + "integrity": "sha512-42g0QyJS31URl28YRxc4hGozSXhbbB1sKwzxEjZR9WtLoSx6WYDsQkQD8+yP5t1NExiSCZAfvNmBw8PYQwDKwg==", "license": "MIT" }, "node_modules/detox/node_modules/ansi-styles": { diff --git a/package.json b/package.json index 5014955f5..aa23eac38 100644 --- a/package.json +++ b/package.json @@ -81,7 +81,7 @@ "@lodev09/react-native-true-sheet": "github:BlueWallet/react-native-true-sheet#839f2966cee77c0ad99d09609dadb61a338e7f54", "@ngraveio/bc-ur": "1.1.13", "@noble/secp256k1": "1.6.3", - "@react-native-async-storage/async-storage": "2.0.0", + "@react-native-async-storage/async-storage": "2.1.0", "@react-native-clipboard/clipboard": "1.15.0", "@react-native-community/push-notification-ios": "1.11.0", "@react-native-menu/menu": "https://github.com/BlueWallet/menu.git#02592ae", @@ -110,7 +110,7 @@ "coinselect": "3.1.13", "crypto-js": "4.2.0", "dayjs": "1.11.13", - "detox": "20.27.6", + "detox": "20.28.0", "ecpair": "2.0.1", "ecurve": "1.0.6", "electrum-client": "github:BlueWallet/rn-electrum-client#1bfe3cc", diff --git a/screen/settings/About.tsx b/screen/settings/About.tsx index 586b57e7c..c63490ebd 100644 --- a/screen/settings/About.tsx +++ b/screen/settings/About.tsx @@ -207,23 +207,19 @@ const About: React.FC = () => { w, h = {width}, {height} - {process.env.NODE_ENV !== 'development' && ( - <> - Unique ID: {getUniqueIdSync()} - - { - const stringToCopy = 'userId:' + getUniqueIdSync(); - A.logError('copied unique id'); - Clipboard.setString(stringToCopy); - }} - > - {loc.transactions.details_copy} - - - - )} + Unique ID: {getUniqueIdSync()} + + { + const stringToCopy = 'userId:' + getUniqueIdSync(); + A.logError('copied unique id'); + Clipboard.setString(stringToCopy); + }} + > + {loc.transactions.details_copy} + + diff --git a/screen/wallets/ImportSpeed.tsx b/screen/wallets/ImportSpeed.tsx index 9115ba883..849f82a0d 100644 --- a/screen/wallets/ImportSpeed.tsx +++ b/screen/wallets/ImportSpeed.tsx @@ -13,7 +13,7 @@ import { AddWalletStackParamList } from '../../navigation/AddWalletStack'; type NavigationProp = NativeStackNavigationProp; -const WalletsImportWallet = () => { +const ImportSpeed = () => { const navigation = useNavigation(); const { colors } = useTheme(); const [loading, setLoading] = useState(false); @@ -102,4 +102,4 @@ const WalletsImportWallet = () => { ); }; -export default WalletsImportWallet; +export default ImportSpeed; diff --git a/screen/wallets/ImportWalletDiscovery.tsx b/screen/wallets/ImportWalletDiscovery.tsx index fe7ec1392..973094e9c 100644 --- a/screen/wallets/ImportWalletDiscovery.tsx +++ b/screen/wallets/ImportWalletDiscovery.tsx @@ -197,7 +197,7 @@ const ImportWalletDiscovery: React.FC = () => { ) : ( <> {loc.wallets.import_discovery_no_wallets} - {' '} + )} diff --git a/screen/wallets/WalletTransactions.tsx b/screen/wallets/WalletTransactions.tsx index de4fb3f30..1ee221b5a 100644 --- a/screen/wallets/WalletTransactions.tsx +++ b/screen/wallets/WalletTransactions.tsx @@ -44,6 +44,8 @@ import assert from 'assert'; import useMenuElements from '../../hooks/useMenuElements'; import { useSettings } from '../../hooks/context/useSettings'; import { getClipboardContent } from '../../blue_modules/clipboard'; +import HandOffComponent from '../../components/HandOffComponent'; +import { HandOffActivityType } from '../../components/types'; const buttonFontSize = PixelRatio.roundToNearestPixel(Dimensions.get('window').width / 26) > 22 @@ -496,6 +498,13 @@ const WalletTransactions: React.FC = ({ route }) => { /> )} + {wallet?.chain === Chain.ONCHAIN && wallet.type !== MultisigHDWallet.type && wallet.getXpub && wallet.getXpub() ? ( + + ) : null} ); }; diff --git a/tests/e2e/bluewallet.spec.js b/tests/e2e/bluewallet.spec.js index 9dd2782e8..e6f319f36 100644 --- a/tests/e2e/bluewallet.spec.js +++ b/tests/e2e/bluewallet.spec.js @@ -698,13 +698,14 @@ describe('BlueWallet UI Tests - no wallets', () => { await element(by.id('DoImport')).tap(); await sleep(1000); await element(by.text('OK')).tap(); - await waitFor(element(by.id('Loading'))) // wait for discovery to be completed - .not.toExist() - .withTimeout(300 * 1000); + // wait for discovery to be completed + await waitFor(element(by.text("m/84'/0'/0'"))) + .toBeVisible() + .withTimeout(300 * 1000); await expect(element(by.text("m/44'/0'/1'"))).toBeVisible(); await expect(element(by.text("m/49'/0'/0'"))).toBeVisible(); - await expect(element(by.text("m/84'/0'/0'"))).toBeVisible(); + await expect(element(by.id('Loading'))).not.toBeVisible(); // open custom derivation path screen and import the wallet await element(by.id('CustomDerivationPathButton')).tap();