diff --git a/packages/components/src/layouts/Navigation/Tab/TabBar/DesktopLeftSideBar.tsx b/packages/components/src/layouts/Navigation/Tab/TabBar/DesktopLeftSideBar.tsx
index cc8a321a580..0aa0c4a7763 100644
--- a/packages/components/src/layouts/Navigation/Tab/TabBar/DesktopLeftSideBar.tsx
+++ b/packages/components/src/layouts/Navigation/Tab/TabBar/DesktopLeftSideBar.tsx
@@ -1,8 +1,7 @@
-import { useCallback, useMemo } from 'react';
+import { useMemo } from 'react';
-import { CommonActions, useNavigation } from '@react-navigation/native';
+import { CommonActions } from '@react-navigation/native';
import { MotiView } from 'moti';
-import { useIntl } from 'react-intl';
import { StyleSheet } from 'react-native';
import { getTokens, useMedia, useTheme } from 'tamagui';
@@ -14,23 +13,9 @@ import {
import useProviderSideBarValue from '@onekeyhq/components/src/hocs/Provider/hooks/useProviderSideBarValue';
import { useSafeAreaInsets } from '@onekeyhq/components/src/hooks';
import type { IKeyOfIcons } from '@onekeyhq/components/src/primitives';
-import {
- Icon,
- Stack,
- XStack,
- YStack,
-} from '@onekeyhq/components/src/primitives';
-import { DOWNLOAD_URL } from '@onekeyhq/shared/src/config/appConfig';
-import { ETranslations } from '@onekeyhq/shared/src/locale';
+import { Icon, XStack, YStack } from '@onekeyhq/components/src/primitives';
import platformEnv from '@onekeyhq/shared/src/platformEnv';
-import {
- EModalRoutes,
- EModalSettingRoutes,
- ERootRoutes,
-} from '@onekeyhq/shared/src/routes';
import { type EShortcutEvents } from '@onekeyhq/shared/src/shortcuts/shortcuts.enum';
-import { shortcutsKeys } from '@onekeyhq/shared/src/shortcuts/shortcutsKeys.enum';
-import { openUrlExternal } from '@onekeyhq/shared/src/utils/openUrlUtils';
import { DesktopDragZoneAbsoluteBar } from '../../../DesktopDragZoneBox';
@@ -87,26 +72,6 @@ function TabItemView({
return contentMemo;
}
-function DownloadButton() {
- const intl = useIntl();
- const onPress = useCallback(() => {
- openUrlExternal(DOWNLOAD_URL);
- }, []);
- if (!platformEnv.isWeb) {
- return null;
- }
- return (
-
- );
-}
-
function OneKeyLogo() {
if (!platformEnv.isWeb) {
return null;
@@ -127,7 +92,6 @@ export function DesktopLeftSideBar({
extraConfig?: ITabNavigatorExtraConfig;
}) {
const { routes } = state;
- const intl = useIntl();
const { leftSidebarCollapsed: isCollapse } = useProviderSideBarValue();
const { top } = useSafeAreaInsets(); // used for ipad
const theme = useTheme();
@@ -192,15 +156,6 @@ export function DesktopLeftSideBar({
],
);
- const appNavigation = useNavigation();
- const openSettingPage = useCallback(() => {
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
- appNavigation.navigate(ERootRoutes.Modal, {
- screen: EModalRoutes.SettingModal,
- params: EModalSettingRoutes.SettingListModal,
- });
- }, [appNavigation]);
-
return (
{tabs}
-
-
-
-
-
+
diff --git a/packages/kit-bg/src/services/ServiceAccount/ServiceAccount.ts b/packages/kit-bg/src/services/ServiceAccount/ServiceAccount.ts
index 4f56eb45259..b06ca73cd92 100644
--- a/packages/kit-bg/src/services/ServiceAccount/ServiceAccount.ts
+++ b/packages/kit-bg/src/services/ServiceAccount/ServiceAccount.ts
@@ -70,6 +70,7 @@ import timerUtils from '@onekeyhq/shared/src/utils/timerUtils';
import type { IServerNetwork } from '@onekeyhq/shared/types';
import type {
IBatchCreateAccount,
+ IHwQrWalletWithDevice,
INetworkAccount,
} from '@onekeyhq/shared/types/account';
import type { IGeneralInputValidation } from '@onekeyhq/shared/types/address';
@@ -271,6 +272,36 @@ class ServiceAccount extends ServiceBase {
};
}
+ @backgroundMethod()
+ async getAllHwQrWalletWithDevice() {
+ const { wallets, allDevices } = await this.getAllWallets({
+ refillWalletInfo: true,
+ });
+ // const { devices } = await this.getAllDevices();
+
+ const result: {
+ [walletId: string]: IHwQrWalletWithDevice;
+ } = {};
+
+ for (const wallet of wallets) {
+ if (
+ !accountUtils.isHwHiddenWallet({ wallet }) &&
+ (accountUtils.isHwWallet({ walletId: wallet.id }) ||
+ accountUtils.isQrWallet({ walletId: wallet.id }))
+ ) {
+ const device = (allDevices ?? []).find(
+ (d) => d.id === wallet.associatedDevice,
+ );
+ result[wallet.id] = {
+ wallet,
+ device,
+ };
+ }
+ }
+
+ return result;
+ }
+
@backgroundMethod()
async isWalletHasIndexedAccounts({ walletId }: { walletId: string }) {
const { accounts: indexedAccounts } = await this.getIndexedAccountsOfWallet(
diff --git a/packages/kit/assets/device-management-guide.png b/packages/kit/assets/device-management-guide.png
new file mode 100644
index 00000000000..32b738b825b
Binary files /dev/null and b/packages/kit/assets/device-management-guide.png differ
diff --git a/packages/kit/src/hooks/useShowAddressBook.ts b/packages/kit/src/hooks/useShowAddressBook.ts
new file mode 100644
index 00000000000..d844eab767a
--- /dev/null
+++ b/packages/kit/src/hooks/useShowAddressBook.ts
@@ -0,0 +1,50 @@
+import { useCallback } from 'react';
+
+import { useIntl } from 'react-intl';
+
+import { useAddressBookPersistAtom } from '@onekeyhq/kit-bg/src/states/jotai/atoms';
+import { defaultLogger } from '@onekeyhq/shared/src/logger/logger';
+import {
+ EModalAddressBookRoutes,
+ EModalRoutes,
+} from '@onekeyhq/shared/src/routes';
+
+import backgroundApiProxy from '../background/instance/backgroundApiProxy';
+import { showAddressSafeNotificationDialog } from '../components/AddressInput/AddressSafeDialog';
+
+import useAppNavigation from './useAppNavigation';
+
+export function useShowAddressBook({
+ useNewModal = false,
+}: {
+ useNewModal?: boolean;
+}) {
+ const intl = useIntl();
+ const navigation = useAppNavigation();
+ const [{ hideDialogInfo }] = useAddressBookPersistAtom();
+
+ const showAddressBook = useCallback(async () => {
+ await backgroundApiProxy.servicePassword.promptPasswordVerify();
+ if (useNewModal) {
+ navigation.pushModal(EModalRoutes.AddressBookModal, {
+ screen: EModalAddressBookRoutes.ListItemModal,
+ params: {},
+ });
+ } else {
+ navigation.push(EModalAddressBookRoutes.ListItemModal);
+ }
+ defaultLogger.setting.page.enterAddressBook();
+ }, [navigation, useNewModal]);
+
+ const onPress = useCallback(async () => {
+ if (!hideDialogInfo) {
+ await showAddressSafeNotificationDialog({
+ intl,
+ });
+ await backgroundApiProxy.serviceAddressBook.hideDialogInfo();
+ }
+ await showAddressBook();
+ }, [hideDialogInfo, showAddressBook, intl]);
+
+ return onPress;
+}
diff --git a/packages/kit/src/provider/Container/PortalBodyContainer/SideBanner.tsx b/packages/kit/src/provider/Container/PortalBodyContainer/SideBanner.tsx
index d4bed74eea1..9026aa4f56f 100644
--- a/packages/kit/src/provider/Container/PortalBodyContainer/SideBanner.tsx
+++ b/packages/kit/src/provider/Container/PortalBodyContainer/SideBanner.tsx
@@ -1,6 +1,7 @@
import { useCallback } from 'react';
import { useIntl } from 'react-intl';
+import { StyleSheet } from 'react-native';
import {
EPortalContainerConstantName,
@@ -12,12 +13,26 @@ import {
Stack,
useMedia,
} from '@onekeyhq/components';
+import { DesktopTabItem } from '@onekeyhq/components/src/layouts/Navigation/Tab/TabBar/DesktopTabItem';
import SidebarBannerImage from '@onekeyhq/kit/assets/sidebar-banner.png';
import { useSpotlight } from '@onekeyhq/kit/src/components/Spotlight';
+import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
+import { useShowAddressBook } from '@onekeyhq/kit/src/hooks/useShowAddressBook';
+import { DOWNLOAD_URL } from '@onekeyhq/shared/src/config/appConfig';
import { ETranslations } from '@onekeyhq/shared/src/locale';
+import platformEnv from '@onekeyhq/shared/src/platformEnv';
+import {
+ EModalDeviceManagementRoutes,
+ EModalRoutes,
+ EModalSettingRoutes,
+ EOnboardingPages,
+} from '@onekeyhq/shared/src/routes';
+import { shortcutsKeys } from '@onekeyhq/shared/src/shortcuts/shortcutsKeys.enum';
import { ESpotlightTour } from '@onekeyhq/shared/src/spotlight';
import { openUrlExternal } from '@onekeyhq/shared/src/utils/openUrlUtils';
+import backgroundApiProxy from '../../../background/instance/backgroundApiProxy';
+
import type { GestureResponderEvent } from 'react-native';
function BasicSidebarBanner() {
@@ -85,11 +100,103 @@ function BasicSidebarBanner() {
) : null;
}
+function DownloadButton() {
+ const intl = useIntl();
+ const onPress = useCallback(() => {
+ openUrlExternal(DOWNLOAD_URL);
+ }, []);
+
+ if (!platformEnv.isWeb) {
+ return null;
+ }
+
+ return (
+
+ );
+}
+
+function BottomMenu() {
+ const intl = useIntl();
+ const appNavigation = useAppNavigation();
+
+ const openSettingPage = useCallback(() => {
+ appNavigation.pushModal(EModalRoutes.SettingModal, {
+ screen: EModalSettingRoutes.SettingListModal,
+ });
+ }, [appNavigation]);
+
+ const openAddressBookPage = useShowAddressBook({
+ useNewModal: true,
+ });
+
+ const openDeviceManagementPage = useCallback(async () => {
+ const allHwQrWallet =
+ await backgroundApiProxy.serviceAccount.getAllHwQrWalletWithDevice();
+ if (Object.keys(allHwQrWallet).length > 0) {
+ appNavigation.pushModal(EModalRoutes.DeviceManagementModal, {
+ screen: EModalDeviceManagementRoutes.DeviceListModal,
+ });
+ return;
+ }
+
+ appNavigation.pushModal(EModalRoutes.OnboardingModal, {
+ screen: EOnboardingPages.DeviceManagementGuide,
+ });
+ }, [appNavigation]);
+
+ return (
+
+
+
+
+
+
+
+ );
+}
+
export const SidebarBanner = () => {
const { gtMd } = useMedia();
return gtMd ? (
-
+
) : null;
};
diff --git a/packages/kit/src/routes/Modal/router.tsx b/packages/kit/src/routes/Modal/router.tsx
index f06696022cd..c765ef9a94c 100644
--- a/packages/kit/src/routes/Modal/router.tsx
+++ b/packages/kit/src/routes/Modal/router.tsx
@@ -12,6 +12,7 @@ import { AssetSelectorRouter } from '../../views/AssetSelector/router';
import { ChainSelectorRouter } from '../../views/ChainSelector/router';
import { CloudBackupPages } from '../../views/CloudBackup/router';
import { DAppConnectionRouter } from '../../views/DAppConnection/router';
+import { DeviceManagementStacks } from '../../views/DeviceManagement/router';
import { ModalDiscoveryStack } from '../../views/Discovery/router';
import { ModalFiatCryptoRouter } from '../../views/FiatCrypto/router';
import { ModalFirmwareUpdateStack } from '../../views/FirmwareUpdate/router';
@@ -163,6 +164,10 @@ const router: IModalRootNavigatorConfig[] = [
name: EModalRoutes.ShortcutsModal,
children: ShortcutsModalRouter,
},
+ {
+ name: EModalRoutes.DeviceManagementModal,
+ children: DeviceManagementStacks,
+ },
];
// Pages in Dev Mode
diff --git a/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/DeviceManagementButton.tsx b/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/DeviceManagementButton.tsx
new file mode 100644
index 00000000000..c75b3aaaf04
--- /dev/null
+++ b/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/DeviceManagementButton.tsx
@@ -0,0 +1,58 @@
+import { useIntl } from 'react-intl';
+
+import backgroundApiProxy from '@onekeyhq/kit/src/background/instance/backgroundApiProxy';
+import { AccountSelectorProviderMirror } from '@onekeyhq/kit/src/components/AccountSelector';
+import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
+import { useActiveAccount } from '@onekeyhq/kit/src/states/jotai/contexts/accountSelector';
+import type { IDBWallet } from '@onekeyhq/kit-bg/src/dbs/local/types';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+import {
+ EModalDeviceManagementRoutes,
+ EModalRoutes,
+} from '@onekeyhq/shared/src/routes';
+import networkUtils from '@onekeyhq/shared/src/utils/networkUtils';
+import { EAccountSelectorSceneName } from '@onekeyhq/shared/types';
+
+import { WalletOptionItem } from './WalletOptionItem';
+
+function DeviceManagementButtonView({
+ wallet,
+}: {
+ wallet: IDBWallet | undefined;
+}) {
+ const intl = useIntl();
+ const navigation = useAppNavigation();
+
+ return (
+ {
+ navigation.pushModal(EModalRoutes.DeviceManagementModal, {
+ screen: EModalDeviceManagementRoutes.DeviceDetailModal,
+ params: {
+ walletId: wallet?.id || '',
+ },
+ });
+ }}
+ />
+ );
+}
+
+export function DeviceManagementButton({
+ wallet,
+}: {
+ wallet: IDBWallet | undefined;
+}) {
+ return (
+
+
+
+ );
+}
diff --git a/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/index.tsx b/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/index.tsx
index f073f16e41d..7249c38aeb2 100644
--- a/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/index.tsx
+++ b/packages/kit/src/views/AccountManagerStacks/pages/AccountSelectorStack/WalletDetails/WalletOptions/index.tsx
@@ -6,20 +6,17 @@ import { HiddenWalletAddButton } from '@onekeyhq/kit/src/views/AccountManagerSta
import { defaultLogger } from '@onekeyhq/shared/src/logger/logger';
import accountUtils from '@onekeyhq/shared/src/utils/accountUtils';
-import { Advance } from './Advance';
import { BatchCreateAccountButton } from './BatchCreateAccountButton';
-import { CheckFirmwareUpdateButton } from './CheckFirmwareUpdateButton';
-import { HardwareHomeScreenButton } from './HardwareHomeScreenButton';
+import { DeviceManagementButton } from './DeviceManagementButton';
import { HdWalletBackupButton } from './HdWalletBackupButton';
import { HiddenWalletRememberSwitch } from './HiddenWalletRememberSwitch';
-import { Verification } from './Verification';
import { WalletProfile } from './WalletProfile';
import type { IWalletDetailsProps } from '..';
type IWalletOptionsProps = Partial;
-function WalletOptionsView({ wallet, device }: IWalletOptionsProps) {
+function WalletOptionsView({ wallet }: IWalletOptionsProps) {
const [editMode] = useAccountSelectorEditModeAtom();
const walletSpecifiedOptions = useMemo(() => {
@@ -48,10 +45,11 @@ function WalletOptionsView({ wallet, device }: IWalletOptionsProps) {
// HW Normal Wallet
return (
<>
-
+ {/*
-
+ */}
+
>
@@ -77,7 +75,7 @@ function WalletOptionsView({ wallet, device }: IWalletOptionsProps) {
}
return null;
- }, [device, wallet]);
+ }, [wallet]);
return (
//
diff --git a/packages/kit/src/views/DeviceManagement/hooks/useBuyOneKeyHeaderRightButton.tsx b/packages/kit/src/views/DeviceManagement/hooks/useBuyOneKeyHeaderRightButton.tsx
new file mode 100644
index 00000000000..7f2f39e5a13
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/hooks/useBuyOneKeyHeaderRightButton.tsx
@@ -0,0 +1,34 @@
+import { useCallback } from 'react';
+
+import { HeaderIconButton } from '@onekeyhq/components/src/layouts/Navigation/Header';
+import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
+import { EOnboardingPages } from '@onekeyhq/shared/src/routes';
+import { EModalDeviceManagementRoutes } from '@onekeyhq/shared/src/routes/deviceManagement';
+
+export function useBuyOneKeyHeaderRightButton(
+ params?:
+ | {
+ inDeviceManagementStack?: boolean;
+ }
+ | undefined,
+) {
+ const navigation = useAppNavigation();
+
+ const toOneKeyHardwareWalletPage = useCallback(() => {
+ if (params?.inDeviceManagementStack) {
+ navigation.push(EModalDeviceManagementRoutes.BuyOneKeyHardwareWallet);
+ } else {
+ navigation.push(EOnboardingPages.OneKeyHardwareWallet);
+ }
+ }, [params?.inDeviceManagementStack, navigation]);
+
+ return {
+ headerRight: () => (
+
+ ),
+ toOneKeyHardwareWalletPage,
+ };
+}
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceAdvanceSection.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceAdvanceSection.tsx
new file mode 100644
index 00000000000..a80de810a9b
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceAdvanceSection.tsx
@@ -0,0 +1,68 @@
+import { useIntl } from 'react-intl';
+
+import { SizableText, Switch, XStack, YStack } from '@onekeyhq/components';
+import { ListItem } from '@onekeyhq/kit/src/components/ListItem';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+
+function DeviceAdvanceSection({
+ passphraseEnabled,
+ pinOnAppEnabled,
+ onPassphraseEnabledChange,
+ onPinOnAppEnabledChange,
+ inputPinOnSoftwareSupport,
+}: {
+ passphraseEnabled: boolean;
+ pinOnAppEnabled: boolean;
+ onPassphraseEnabledChange: (value: boolean) => void;
+ onPinOnAppEnabledChange: (value: boolean) => void;
+ inputPinOnSoftwareSupport: boolean;
+}) {
+ const intl = useIntl();
+ return (
+
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_advance,
+ })}
+
+
+
+
+ {
+ onPassphraseEnabledChange(!passphraseEnabled);
+ }}
+ />
+
+ {inputPinOnSoftwareSupport ? (
+
+ {
+ onPinOnAppEnabledChange(!pinOnAppEnabled);
+ }}
+ />
+
+ ) : null}
+
+
+ );
+}
+
+export default DeviceAdvanceSection;
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceBasicInfoSection.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceBasicInfoSection.tsx
new file mode 100644
index 00000000000..7f071ca8ede
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceBasicInfoSection.tsx
@@ -0,0 +1,141 @@
+import { useIntl } from 'react-intl';
+
+import type { IIconProps, IKeyOfIcons } from '@onekeyhq/components';
+import { Badge, Icon, SizableText, XStack, YStack } from '@onekeyhq/components';
+import { ListItem } from '@onekeyhq/kit/src/components/ListItem';
+import { WalletAvatar } from '@onekeyhq/kit/src/components/WalletAvatar';
+import { usePromiseResult } from '@onekeyhq/kit/src/hooks/usePromiseResult';
+import { WalletRenameButton } from '@onekeyhq/kit/src/views/AccountManagerStacks/components/WalletRename';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+import accountUtils from '@onekeyhq/shared/src/utils/accountUtils';
+import deviceUtils from '@onekeyhq/shared/src/utils/deviceUtils';
+import type { IHwQrWalletWithDevice } from '@onekeyhq/shared/types/account';
+
+function DeviceBasicInfoSection({
+ data,
+ onPressHomescreen,
+ onPressAuthRequest,
+ onPressCheckForUpdates,
+}: {
+ data: IHwQrWalletWithDevice;
+ onPressHomescreen: () => void;
+ onPressAuthRequest: () => void;
+ onPressCheckForUpdates: () => void;
+}) {
+ const { wallet, device } = data;
+ const intl = useIntl();
+ const isQrWallet = accountUtils.isQrWallet({ walletId: wallet.id });
+
+ const { result: deviceInfo } = usePromiseResult(
+ async () => {
+ if (!device || !device.featuresInfo) {
+ return {
+ firmwareVersion: '-',
+ walletAvatarBadge: isQrWallet ? 'QR' : undefined,
+ verifiedBadgeIconName: 'DocumentSearch2Outline' as IKeyOfIcons,
+ verifiedBadgeIconColor: '$iconSubdued' as IIconProps['color'],
+ };
+ }
+
+ const versions = await deviceUtils.getDeviceVersion({
+ device,
+ features: device.featuresInfo,
+ });
+
+ let iconName: IKeyOfIcons = 'DocumentSearch2Outline';
+ let iconColor: IIconProps['color'] = '$iconSubdued';
+
+ if (device.verifiedAtVersion) {
+ iconName = 'BadgeVerifiedSolid';
+ iconColor = '$iconSuccess';
+ } else if (device.verifiedAtVersion === '') {
+ iconName = 'ErrorSolid';
+ iconColor = '$iconCritical';
+ }
+
+ return {
+ firmwareVersion: versions?.firmwareVersion ?? '-',
+ walletAvatarBadge: isQrWallet ? 'QR' : undefined,
+ verifiedBadgeIconName: iconName,
+ verifiedBadgeIconColor: iconColor,
+ };
+ },
+ [device, isQrWallet],
+ {
+ initResult: {
+ firmwareVersion: '-',
+ walletAvatarBadge: isQrWallet ? 'QR' : undefined,
+ verifiedBadgeIconName: 'DocumentSearch2Outline',
+ verifiedBadgeIconColor: '$iconSubdued',
+ },
+ },
+ );
+
+ return (
+
+
+
+
+
+
+
+
+
+ {isQrWallet ? null : (
+
+
+ {`v${deviceInfo.firmwareVersion}`}
+
+
+
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_verified,
+ })}
+
+
+
+
+ )}
+
+
+ {isQrWallet ? null : (
+
+
+
+
+
+ )}
+
+ );
+}
+
+export default DeviceBasicInfoSection;
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceQrInfoSection.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceQrInfoSection.tsx
new file mode 100644
index 00000000000..8f1d8fd9bbf
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceQrInfoSection.tsx
@@ -0,0 +1,39 @@
+import { useIntl } from 'react-intl';
+
+import { SizableText, YStack } from '@onekeyhq/components';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+
+function DeviceQrInfoSection() {
+ const intl = useIntl();
+
+ return (
+
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_about_qr_details_question_a,
+ })}
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_about_qr_details_answer_a,
+ })}
+
+
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_about_qr_details_question_b,
+ })}
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_about_qr_details_answer_b,
+ })}
+
+
+
+ );
+}
+
+export default DeviceQrInfoSection;
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceSpecsSection.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceSpecsSection.tsx
new file mode 100644
index 00000000000..45e475adcab
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/DeviceSpecsSection.tsx
@@ -0,0 +1,122 @@
+import { useMemo } from 'react';
+
+import { useIntl } from 'react-intl';
+
+import { SizableText, XStack, YStack } from '@onekeyhq/components';
+import { usePromiseResult } from '@onekeyhq/kit/src/hooks/usePromiseResult';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+import deviceUtils from '@onekeyhq/shared/src/utils/deviceUtils';
+import type { IHwQrWalletWithDevice } from '@onekeyhq/shared/types/account';
+
+type ISpecItemProps = {
+ title: string;
+ value: string;
+};
+
+function SpecItem({ title, value }: ISpecItemProps) {
+ return (
+
+
+ {title}
+
+
+ {value}
+
+
+ );
+}
+
+function DeviceSpecsSection({ data }: { data: IHwQrWalletWithDevice }) {
+ const intl = useIntl();
+ const { device } = data;
+ const defaultDeviceInfo = useMemo(
+ () => ({
+ model: '-',
+ bleName: '-',
+ bleVersion: '-',
+ bootloaderVersion: '-',
+ firmwareVersion: '-',
+ serialNumber: '-',
+ }),
+ [],
+ );
+ const { result: deviceInfo } = usePromiseResult(
+ async () => {
+ if (!device || !device.featuresInfo) {
+ return defaultDeviceInfo;
+ }
+
+ const versions = await deviceUtils.getDeviceVersion({
+ device,
+ features: device.featuresInfo,
+ });
+
+ const model = await deviceUtils.buildDeviceLabel({
+ features: device.featuresInfo,
+ buildModelName: true,
+ });
+
+ return {
+ model,
+ bleName: device.featuresInfo.ble_name ?? '-',
+ bleVersion: versions?.bleVersion ?? '-',
+ bootloaderVersion: versions?.bootloaderVersion ?? '-',
+ firmwareVersion: versions?.firmwareVersion ?? '-',
+ serialNumber:
+ device.featuresInfo.onekey_serial ??
+ device.featuresInfo.serial_no ??
+ '-',
+ };
+ },
+ [device, defaultDeviceInfo],
+ {
+ initResult: defaultDeviceInfo,
+ },
+ );
+
+ return (
+
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_device_info,
+ })}
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default DeviceSpecsSection;
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/index.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/index.tsx
new file mode 100644
index 00000000000..ad8dd0f1417
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceDetailsModal/index.tsx
@@ -0,0 +1,202 @@
+import { useCallback, useEffect, useState } from 'react';
+
+import { useRoute } from '@react-navigation/native';
+import { useIntl } from 'react-intl';
+
+import { Page, YStack } from '@onekeyhq/components';
+import backgroundApiProxy from '@onekeyhq/kit/src/background/instance/backgroundApiProxy';
+import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
+import { usePromiseResult } from '@onekeyhq/kit/src/hooks/usePromiseResult';
+import { useFirmwareUpdateActions } from '@onekeyhq/kit/src/views/FirmwareUpdate/hooks/useFirmwareUpdateActions';
+import { useFirmwareVerifyDialog } from '@onekeyhq/kit/src/views/Onboarding/pages/ConnectHardwareWallet/FirmwareVerifyDialog';
+import {
+ EAppEventBusNames,
+ appEventBus,
+} from '@onekeyhq/shared/src/eventBus/appEventBus';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+import type {
+ EModalDeviceManagementRoutes,
+ IModalDeviceManagementParamList,
+} from '@onekeyhq/shared/src/routes';
+import {
+ EAccountManagerStacksRoutes,
+ EModalRoutes,
+} from '@onekeyhq/shared/src/routes';
+import accountUtils from '@onekeyhq/shared/src/utils/accountUtils';
+import type { IHwQrWalletWithDevice } from '@onekeyhq/shared/types/account';
+
+import DeviceAdvanceSection from './DeviceAdvanceSection';
+import DeviceBasicInfoSection from './DeviceBasicInfoSection';
+import DeviceQrInfoSection from './DeviceQrInfoSection';
+import DeviceSpecsSection from './DeviceSpecsSection';
+
+import type { RouteProp } from '@react-navigation/native';
+
+function DeviceDetailsModal() {
+ const intl = useIntl();
+ const navigation = useAppNavigation();
+ const route =
+ useRoute<
+ RouteProp<
+ IModalDeviceManagementParamList,
+ EModalDeviceManagementRoutes.DeviceDetailModal
+ >
+ >();
+ const { walletId } = route.params;
+
+ const [passphraseEnabled, setPassphraseEnabled] = useState(false);
+ const [pinOnAppEnabled, setPinOnAppEnabled] = useState(false);
+ const {
+ result,
+ isLoading,
+ run: refreshData,
+ } = usePromiseResult(async () => {
+ const r =
+ await backgroundApiProxy.serviceAccount.getAllHwQrWalletWithDevice();
+
+ const device = r?.[walletId]?.device;
+ setPassphraseEnabled(Boolean(device?.featuresInfo?.passphrase_protection));
+ setPinOnAppEnabled(Boolean(device?.settings?.inputPinOnSoftware));
+
+ return r?.[walletId] ?? undefined;
+ }, [walletId]);
+
+ useEffect(() => {
+ const fn = () => {
+ void refreshData();
+ };
+ appEventBus.on(EAppEventBusNames.WalletUpdate, fn);
+ return () => {
+ appEventBus.off(EAppEventBusNames.WalletUpdate, fn);
+ };
+ }, [refreshData]);
+
+ const isQrWallet = result
+ ? accountUtils.isQrWallet({ walletId: result.wallet.id })
+ : false;
+
+ // Basic Info Section
+ const onPressHomescreen = useCallback(() => {
+ if (!result?.device) return;
+ navigation.pushModal(EModalRoutes.AccountManagerStacks, {
+ screen: EAccountManagerStacksRoutes.HardwareHomeScreenModal,
+ params: {
+ device: result?.device,
+ },
+ });
+ }, [result?.device, navigation]);
+
+ const { showFirmwareVerifyDialog } = useFirmwareVerifyDialog();
+ const onPressAuthRequest = useCallback(async () => {
+ if (!result?.device) {
+ return;
+ }
+ await showFirmwareVerifyDialog({
+ device: result.device,
+ features: result.device.featuresInfo,
+ onContinue: async ({ checked }) => {
+ console.log(checked);
+ },
+ });
+ }, [result?.device, showFirmwareVerifyDialog]);
+
+ const actions = useFirmwareUpdateActions();
+ const onPressCheckForUpdates = useCallback(() => {
+ actions.openChangeLogModal({
+ connectId: result?.device?.connectId,
+ });
+ }, [result?.device?.connectId, actions]);
+
+ // Advance Section
+ const inputPinOnSoftwareSupport = ['classic', 'mini', 'classic1s'].includes(
+ result?.device?.deviceType || '',
+ );
+
+ const onPassphraseEnabledChange = useCallback(
+ async (value: boolean) => {
+ try {
+ await backgroundApiProxy.serviceHardware.setPassphraseEnabled({
+ walletId: result?.wallet.id || '',
+ passphraseEnabled: value,
+ });
+ setPassphraseEnabled(value);
+ } catch (error) {
+ console.error(error);
+ }
+ },
+ [result?.wallet.id],
+ );
+
+ const onPinOnAppEnabledChange = useCallback(
+ async (value: boolean) => {
+ try {
+ setPinOnAppEnabled(value);
+ await backgroundApiProxy.serviceHardware.setInputPinOnSoftware({
+ walletId: result?.wallet.id || '',
+ inputPinOnSoftware: value,
+ });
+ } catch (error) {
+ console.error(error);
+ setPinOnAppEnabled(!value);
+ }
+ },
+ [result?.wallet.id],
+ );
+
+ const renderContent = useCallback(() => {
+ if (isLoading || !result) {
+ return null;
+ }
+
+ if (isQrWallet) {
+ return ;
+ }
+
+ return (
+ <>
+
+
+ >
+ );
+ }, [
+ isLoading,
+ result,
+ isQrWallet,
+ passphraseEnabled,
+ pinOnAppEnabled,
+ inputPinOnSoftwareSupport,
+ onPassphraseEnabledChange,
+ onPinOnAppEnabledChange,
+ ]);
+
+ return (
+
+
+
+
+ {result ? (
+ <>
+
+ {renderContent()}
+ >
+ ) : null}
+
+
+
+ );
+}
+
+export default DeviceDetailsModal;
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceGuideModal/index.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceGuideModal/index.tsx
new file mode 100644
index 00000000000..9be91ddb117
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceGuideModal/index.tsx
@@ -0,0 +1,69 @@
+import { useCallback } from 'react';
+
+import { useIntl } from 'react-intl';
+
+import { Button, Image, Page, SizableText, YStack } from '@onekeyhq/components';
+import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+import { EOnboardingPages } from '@onekeyhq/shared/src/routes';
+
+import { useBuyOneKeyHeaderRightButton } from '../../hooks/useBuyOneKeyHeaderRightButton';
+
+function DeviceGuideModal() {
+ const intl = useIntl();
+ const navigation = useAppNavigation();
+ const { headerRight } = useBuyOneKeyHeaderRightButton();
+
+ const handleStartConnect = useCallback(() => {
+ navigation.push(EOnboardingPages.ConnectYourDevice);
+ }, [navigation]);
+
+ return (
+
+
+
+
+
+
+
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_no_device_connected,
+ })}
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_no_device_connected_desc,
+ })}
+
+
+
+
+
+
+
+ );
+}
+
+export default DeviceGuideModal;
diff --git a/packages/kit/src/views/DeviceManagement/pages/DeviceManagementListModal/index.tsx b/packages/kit/src/views/DeviceManagement/pages/DeviceManagementListModal/index.tsx
new file mode 100644
index 00000000000..645ed3da17d
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/pages/DeviceManagementListModal/index.tsx
@@ -0,0 +1,176 @@
+import { useCallback, useEffect, useMemo } from 'react';
+
+import { useIntl } from 'react-intl';
+
+import {
+ Anchor,
+ Icon,
+ ListView,
+ Page,
+ SizableText,
+ XStack,
+} from '@onekeyhq/components';
+import backgroundApiProxy from '@onekeyhq/kit/src/background/instance/backgroundApiProxy';
+import { ListItem } from '@onekeyhq/kit/src/components/ListItem';
+import type { IWalletAvatarProps } from '@onekeyhq/kit/src/components/WalletAvatar';
+import { WalletAvatar } from '@onekeyhq/kit/src/components/WalletAvatar';
+import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
+import { usePromiseResult } from '@onekeyhq/kit/src/hooks/usePromiseResult';
+import {
+ EAppEventBusNames,
+ appEventBus,
+} from '@onekeyhq/shared/src/eventBus/appEventBus';
+import { ETranslations } from '@onekeyhq/shared/src/locale';
+import {
+ EModalDeviceManagementRoutes,
+ EModalRoutes,
+ EOnboardingPages,
+} from '@onekeyhq/shared/src/routes';
+import accountUtils from '@onekeyhq/shared/src/utils/accountUtils';
+import type { IHwQrWalletWithDevice } from '@onekeyhq/shared/types/account';
+
+import { useBuyOneKeyHeaderRightButton } from '../../hooks/useBuyOneKeyHeaderRightButton';
+
+function DeviceManagementListModal() {
+ const intl = useIntl();
+ const appNavigation = useAppNavigation();
+ const { result: hwQrWalletList = [], run: refreshHwQrWalletList } =
+ usePromiseResult>(async () => {
+ const r =
+ await backgroundApiProxy.serviceAccount.getAllHwQrWalletWithDevice();
+ return Object.values(r).filter((item): item is IHwQrWalletWithDevice =>
+ Boolean(item.device),
+ );
+ }, []);
+
+ useEffect(() => {
+ const fn = () => {
+ void refreshHwQrWalletList();
+ };
+ appEventBus.on(EAppEventBusNames.WalletUpdate, fn);
+ return () => {
+ appEventBus.off(EAppEventBusNames.WalletUpdate, fn);
+ };
+ }, [refreshHwQrWalletList]);
+
+ const onAddDevice = useCallback(async () => {
+ appNavigation.pushModal(EModalRoutes.OnboardingModal, {
+ screen: EOnboardingPages.ConnectYourDevice,
+ });
+ }, [appNavigation]);
+
+ const onWalletPressed = useCallback(
+ (wallet: IHwQrWalletWithDevice['wallet']) => {
+ if (wallet.id) {
+ appNavigation.push(EModalDeviceManagementRoutes.DeviceDetailModal, {
+ walletId: wallet.id,
+ });
+ }
+ },
+ [appNavigation],
+ );
+
+ const renderItem = useCallback(
+ ({ item }: { item: IHwQrWalletWithDevice }) => {
+ const walletAvatarProps: IWalletAvatarProps = {
+ wallet: item.wallet,
+ status: 'default',
+ badge: accountUtils.isQrWallet({ walletId: item.wallet.id })
+ ? 'QR'
+ : undefined,
+ };
+ return (
+ }
+ onPress={() => {
+ onWalletPressed(item.wallet);
+ }}
+ />
+ );
+ },
+ [onWalletPressed],
+ );
+
+ const footer = useMemo(
+ () => (
+ (
+
+
+
+ )}
+ title={intl.formatMessage({
+ id: ETranslations.global_add_new_device,
+ })}
+ drillIn
+ onPress={onAddDevice}
+ />
+ ),
+ [intl, onAddDevice],
+ );
+
+ const { headerRight } = useBuyOneKeyHeaderRightButton({
+ inDeviceManagementStack: true,
+ });
+
+ return (
+
+
+
+ item.wallet.id}
+ data={hwQrWalletList}
+ renderItem={renderItem}
+ estimatedItemSize={68}
+ ListFooterComponent={footer}
+ />
+
+
+ {intl.formatMessage({
+ id: ETranslations.global_onekey_prompt_dont_have_yet,
+ })}
+
+
+ {intl.formatMessage({ id: ETranslations.global_buy_one })}
+
+
+
+
+ );
+}
+
+export default DeviceManagementListModal;
diff --git a/packages/kit/src/views/DeviceManagement/router/index.tsx b/packages/kit/src/views/DeviceManagement/router/index.tsx
new file mode 100644
index 00000000000..db04c79b37c
--- /dev/null
+++ b/packages/kit/src/views/DeviceManagement/router/index.tsx
@@ -0,0 +1,45 @@
+import type { IModalFlowNavigatorConfig } from '@onekeyhq/components';
+import { LazyLoadPage } from '@onekeyhq/kit/src/components/LazyLoadPage';
+import type { IModalDeviceManagementParamList } from '@onekeyhq/shared/src/routes';
+import { EModalDeviceManagementRoutes } from '@onekeyhq/shared/src/routes/deviceManagement';
+
+const DeviceGuideModal = LazyLoadPage(
+ () => import('../pages/DeviceGuideModal'),
+);
+
+const DeviceListModal = LazyLoadPage(
+ () => import('../pages/DeviceManagementListModal'),
+);
+
+const DeviceDetailModal = LazyLoadPage(
+ () => import('../pages/DeviceDetailsModal'),
+);
+
+const BuyOneKeyHardwareWallet = LazyLoadPage(
+ () =>
+ import(
+ '@onekeyhq/kit/src/views/Onboarding/pages/ConnectHardwareWallet/OneKeyHardwareWallet'
+ ),
+);
+
+export const DeviceManagementStacks: IModalFlowNavigatorConfig<
+ EModalDeviceManagementRoutes,
+ IModalDeviceManagementParamList
+>[] = [
+ {
+ name: EModalDeviceManagementRoutes.GuideModal,
+ component: DeviceGuideModal,
+ },
+ {
+ name: EModalDeviceManagementRoutes.DeviceListModal,
+ component: DeviceListModal,
+ },
+ {
+ name: EModalDeviceManagementRoutes.DeviceDetailModal,
+ component: DeviceDetailModal,
+ },
+ {
+ name: EModalDeviceManagementRoutes.BuyOneKeyHardwareWallet,
+ component: BuyOneKeyHardwareWallet,
+ },
+];
diff --git a/packages/kit/src/views/Onboarding/pages/ConnectHardwareWallet/ConnectYourDevice.tsx b/packages/kit/src/views/Onboarding/pages/ConnectHardwareWallet/ConnectYourDevice.tsx
index 9661c01fc4e..f67d2cf7445 100644
--- a/packages/kit/src/views/Onboarding/pages/ConnectHardwareWallet/ConnectYourDevice.tsx
+++ b/packages/kit/src/views/Onboarding/pages/ConnectHardwareWallet/ConnectYourDevice.tsx
@@ -86,6 +86,7 @@ import {
type IOneKeyDeviceFeatures,
} from '@onekeyhq/shared/types/device';
+import { useBuyOneKeyHeaderRightButton } from '../../../DeviceManagement/hooks/useBuyOneKeyHeaderRightButton';
import { useFirmwareUpdateActions } from '../../../FirmwareUpdate/hooks/useFirmwareUpdateActions';
import { useFirmwareVerifyDialog } from './FirmwareVerifyDialog';
@@ -102,10 +103,6 @@ type IConnectYourDeviceItem = {
device: SearchDevice | undefined;
};
-const headerRight = (onPress: () => void) => (
-
-);
-
function DeviceListItem({ item }: { item: IConnectYourDeviceItem }) {
const [isLoading, setIsLoading] = useState(false);
return (
@@ -1185,9 +1182,8 @@ export function ConnectYourDevicePage() {
channel ?? EConnectDeviceChannel.usbOrBle,
);
- const toOneKeyHardwareWalletPage = useCallback(() => {
- navigation.push(EOnboardingPages.OneKeyHardwareWallet);
- }, [navigation]);
+ const { headerRight, toOneKeyHardwareWalletPage } =
+ useBuyOneKeyHeaderRightButton();
return (
@@ -1195,7 +1191,7 @@ export function ConnectYourDevicePage() {
title={intl.formatMessage({
id: ETranslations.onboarding_connect_your_device,
})}
- headerRight={() => headerRight(toOneKeyHardwareWalletPage)}
+ headerRight={headerRight}
/>
diff --git a/packages/kit/src/views/Onboarding/router/index.ts b/packages/kit/src/views/Onboarding/router/index.ts
index 5cce64c197c..05eb4fa7e26 100644
--- a/packages/kit/src/views/Onboarding/router/index.ts
+++ b/packages/kit/src/views/Onboarding/router/index.ts
@@ -76,6 +76,10 @@ const ImportKeyTag = LazyLoadPage(
() => import('../pages/ImportWallet/ImportKeyTag'),
);
+const DeviceManagementGuideModal = LazyLoadPage(
+ () => import('../../DeviceManagement/pages/DeviceGuideModal'),
+);
+
export const OnboardingRouter: IModalFlowNavigatorConfig<
EOnboardingPages,
IOnboardingParamList
@@ -178,4 +182,10 @@ export const OnboardingRouter: IModalFlowNavigatorConfig<
component: FinalizeWalletSetup,
allowDisableClose: true,
},
+
+ // device management guide page
+ {
+ name: EOnboardingPages.DeviceManagementGuide,
+ component: DeviceManagementGuideModal,
+ },
];
diff --git a/packages/kit/src/views/Setting/pages/List/DefaultSection/index.tsx b/packages/kit/src/views/Setting/pages/List/DefaultSection/index.tsx
index 42d65b3f8ce..2a7154945cc 100644
--- a/packages/kit/src/views/Setting/pages/List/DefaultSection/index.tsx
+++ b/packages/kit/src/views/Setting/pages/List/DefaultSection/index.tsx
@@ -4,15 +4,12 @@ import { useIntl } from 'react-intl';
import { YStack } from '@onekeyhq/components';
import backgroundApiProxy from '@onekeyhq/kit/src/background/instance/backgroundApiProxy';
-import { showAddressSafeNotificationDialog } from '@onekeyhq/kit/src/components/AddressInput/AddressSafeDialog';
import { ListItem } from '@onekeyhq/kit/src/components/ListItem';
import useAppNavigation from '@onekeyhq/kit/src/hooks/useAppNavigation';
import { usePromiseResult } from '@onekeyhq/kit/src/hooks/usePromiseResult';
+import { useShowAddressBook } from '@onekeyhq/kit/src/hooks/useShowAddressBook';
import { useBackupEntryStatus } from '@onekeyhq/kit/src/views/CloudBackup/components/useBackupEntryStatus';
-import {
- useAddressBookPersistAtom,
- usePasswordPersistAtom,
-} from '@onekeyhq/kit-bg/src/states/jotai/atoms';
+import { usePasswordPersistAtom } from '@onekeyhq/kit-bg/src/states/jotai/atoms';
import {
EAppEventBusNames,
appEventBus,
@@ -24,7 +21,6 @@ import {
ECloudBackupRoutes,
EDAppConnectionModal,
ELiteCardRoutes,
- EModalAddressBookRoutes,
EModalKeyTagRoutes,
EModalRoutes,
} from '@onekeyhq/shared/src/routes';
@@ -47,22 +43,9 @@ export const useOnLock = () => {
const AddressBookItem = () => {
const intl = useIntl();
- const navigation = useAppNavigation();
- const showAddressBook = useCallback(async () => {
- await backgroundApiProxy.servicePassword.promptPasswordVerify();
- navigation.push(EModalAddressBookRoutes.ListItemModal);
- defaultLogger.setting.page.enterAddressBook();
- }, [navigation]);
- const [{ hideDialogInfo }] = useAddressBookPersistAtom();
- const onPress = useCallback(async () => {
- if (!hideDialogInfo) {
- await showAddressSafeNotificationDialog({
- intl,
- });
- await backgroundApiProxy.serviceAddressBook.hideDialogInfo();
- }
- await showAddressBook();
- }, [hideDialogInfo, showAddressBook, intl]);
+ const onPress = useShowAddressBook({
+ useNewModal: false,
+ });
return (
{
- if (features.label) {
+ if (features.label && !buildModelName) {
return features.label;
}
const defaultLabelsByDeviceType: Record = {
diff --git a/packages/shared/types/account.ts b/packages/shared/types/account.ts
index 2fa050bae84..e4f66650dea 100644
--- a/packages/shared/types/account.ts
+++ b/packages/shared/types/account.ts
@@ -1,4 +1,8 @@
-import type { IDBAccount } from '@onekeyhq/kit-bg/src/dbs/local/types';
+import type {
+ IDBAccount,
+ IDBDevice,
+ IDBWallet,
+} from '@onekeyhq/kit-bg/src/dbs/local/types';
import type { IAirGapAccount } from '@onekeyhq/qr-wallet-sdk';
import type { INetworkAccountAddressDetail } from './address';
@@ -42,3 +46,8 @@ export enum ERequestWalletTypeEnum {
THIRD_PARTY = 'third-party',
UNKNOWN = 'unknown',
}
+
+export type IHwQrWalletWithDevice = {
+ device: IDBDevice | undefined;
+ wallet: IDBWallet;
+};