feat: simplified sign page footerbar ui (#2564)

* feat: simplified sign page ui

* wip

* fix: footbar

* fix: ui bugs

* feat: ledger unlock
This commit is contained in:
heisenberg
2024-10-17 16:11:19 +08:00
committed by GitHub
parent cb02216062
commit 54a5d3cb82
23 changed files with 201 additions and 348 deletions

View File

@@ -37,7 +37,7 @@
"gasLimitLessThanGasUsed": "Gas limit is too low. There is 95% chance that the transaction may fail.",
"nativeTokenNotEngouthForGas": "Gas balance is not enough for transaction",
"nonceLowerThanExpect": "Nonce is too low, the minimum should be {{0}}",
"canOnlyUseImportedAddress": "You can only use imported addresses to sign",
"canOnlyUseImportedAddress": "You cannot sign transactions with a watch-only address.",
"multiSigChainNotMatch": "Multi-signature addresses are not on this chain and cannot initiate transactions",
"safeAddressNotSupportChain": "Current safe address is not supported on {{0}} chain",
"noGasRequired": "No gas required",

View File

@@ -9,7 +9,7 @@ import {
FeeMarketEIP1559Transaction,
} from '@ethereumjs/tx';
import { EVENTS } from 'consts';
import { isSameAddress, wait } from '@/background/utils';
import { isSameAddress } from '@/background/utils';
import { SignHelper, LedgerHDPathType } from './helper';
const type = 'Ledger Hardware';
@@ -303,11 +303,10 @@ class LedgerBridgeKeyring {
// wait connect the WebHID
while (!this.app) {
await this.makeApp();
await wait(() => {
if (count++ > 50) {
throw new Error('Ledger: Failed to connect to Ledger');
}
}, 100);
await new Promise((resolve) => setTimeout(resolve, 100));
if (count++ > 50) {
throw new Error('Ledger: Failed to connect to Ledger');
}
}
}

View File

@@ -57,15 +57,6 @@ export function normalizeAddress(input: number | string): string {
return ethUtil.addHexPrefix(input);
}
export const wait = (fn: () => void, ms = 1000) => {
return new Promise((resolve) => {
setTimeout(() => {
fn();
resolve(true);
}, ms);
});
};
export const setPageStateCacheWhenPopupClose = (data) => {
const cache = pageStateCache.get();
if (cache && cache.path === '/import/wallet-connect') {

View File

@@ -1,6 +1,5 @@
import { Tooltip } from 'antd';
import clsx from 'clsx';
import { KEYRING_ICONS, WALLET_BRAND_CONTENT } from 'consts';
import React, {
memo,
MouseEventHandler,
@@ -15,12 +14,10 @@ import { useRabbySelector } from '@/ui/store';
import { ReactComponent as RcIconWhitelist } from 'ui/assets/address/whitelist.svg';
import { CopyChecked } from '@/ui/component/CopyChecked';
import { useWalletConnectIcon } from '@/ui/component/WalletConnect/useWalletConnectIcon';
import { CommonSignal } from '@/ui/component/ConnectStatus/CommonSignal';
import { useTranslation } from 'react-i18next';
import ThemeIcon from '../ThemeMode/ThemeIcon';
import { pickKeyringThemeIcon } from '@/utils/account';
import { useThemeMode } from '@/ui/hooks/usePreference';
import { useBrandIcon } from '@/ui/hooks/useBrandIcon';
export interface AddressItemProps {
balance: number;
@@ -60,24 +57,12 @@ const AddressItem = memo(
const alias = _alias || aliasName;
const titleRef = useRef<HTMLDivElement>(null);
const brandIcon = useWalletConnectIcon({
const addressTypeIcon = useBrandIcon({
address,
brandName,
type,
});
const { isDarkTheme } = useThemeMode();
const addressTypeIcon = useMemo(
() =>
brandIcon ||
pickKeyringThemeIcon(type as any, isDarkTheme) ||
KEYRING_ICONS[type] ||
pickKeyringThemeIcon(brandName as any, isDarkTheme) ||
WALLET_BRAND_CONTENT?.[brandName]?.image,
[type, brandName, brandIcon, isDarkTheme]
);
return (
<div
className={clsx(

View File

@@ -0,0 +1,49 @@
import { useWalletConnectIcon } from '../component/WalletConnect/useWalletConnectIcon';
import { useThemeMode } from './usePreference';
import React from 'react';
import { pickKeyringThemeIcon } from '@/utils/account';
import {
KEYRING_ICONS,
KEYRINGS_LOGOS,
WALLET_BRAND_CONTENT,
} from '@/constant';
export const useBrandIcon = ({
address,
brandName,
type,
forceLight,
}: {
address: string;
brandName: string;
type: string;
forceLight?: boolean;
}) => {
const brandIcon = useWalletConnectIcon({
address,
brandName,
type,
});
const { isDarkTheme } = useThemeMode();
const addressTypeIcon = React.useMemo(
() =>
forceLight
? brandIcon ||
pickKeyringThemeIcon(type as any, {
needLightVersion: true,
}) ||
WALLET_BRAND_CONTENT?.[brandName]?.image ||
KEYRINGS_LOGOS[type]
: brandIcon ||
pickKeyringThemeIcon(brandName as any, {
needLightVersion: isDarkTheme,
}) ||
WALLET_BRAND_CONTENT?.[brandName]?.image ||
KEYRING_ICONS[type],
[type, brandName, brandIcon, isDarkTheme]
);
return addressTypeIcon;
};

View File

@@ -3,12 +3,12 @@ import { useEffect, useRef, useState, useCallback } from 'react';
import { useHistory } from 'react-router-dom';
import { Approval } from 'background/service/notification';
import { useWallet } from './WalletContext';
import { getUiType } from './index';
import { KEYRING_TYPE_TEXT, WALLET_BRAND_CONTENT } from '@/constant';
import { LedgerHDPathType, LedgerHDPathTypeLabel } from '@/ui/utils/ledger';
import { useApprovalPopup } from './approval-popup';
import { useRabbyDispatch, useRabbySelector } from '../store';
import { useTranslation } from 'react-i18next';
import { useDeviceConnect } from './useDeviceConnect';
export const useApproval = () => {
const wallet = useWallet();
@@ -16,6 +16,7 @@ export const useApproval = () => {
const { showPopup, enablePopup } = useApprovalPopup();
const getApproval: () => Promise<Approval> = wallet.getApproval;
const deviceConnect = useDeviceConnect();
const resolveApproval = async (
data?: any,
@@ -23,6 +24,11 @@ export const useApproval = () => {
forceReject = false,
approvalId?: string
) => {
// handle connect
if (!(await deviceConnect(data.type))) {
return;
}
const approval = await getApproval();
if (approval) {

View File

@@ -0,0 +1,76 @@
import { KEYRING_CLASS } from '@/constant';
import React from 'react';
import { useLedgerStatus } from '../component/ConnectStatus/useLedgerStatus';
import { useCommonPopupView, useWallet } from './WalletContext';
import { useSessionStatus } from '../component/WalletConnect/useSessionStatus';
import { useCurrentAccount } from '../hooks/backgroundState/useAccount';
import { useImKeyStatus } from '../component/ConnectStatus/useImKeyStatus';
/**
* some devices require a connection to the device to sign transactions
* ledger, walletConnect, gridplus, etc
*/
export const useDeviceConnect = () => {
const ledgerStatus = useLedgerStatus();
const account = useCurrentAccount();
const walletConnectStatus = useSessionStatus(account!);
const imKeyStatus = useImKeyStatus();
const { activePopup, setAccount } = useCommonPopupView();
const wallet = useWallet();
/**
* @returns {boolean} true if connected, false if not connected and popup is shown
*/
const connect = React.useCallback(
async (type: string) => {
if (type === KEYRING_CLASS.HARDWARE.LEDGER) {
if (ledgerStatus.status === 'DISCONNECTED') {
activePopup('Ledger');
return false;
} else {
try {
await wallet.requestKeyring(
KEYRING_CLASS.HARDWARE.LEDGER,
'cleanUp',
null
);
await wallet.requestKeyring(
KEYRING_CLASS.HARDWARE.LEDGER,
'unlock',
null,
"m/44'/60'/0'/0"
);
} catch (e) {
console.error(e);
activePopup('Ledger');
return false;
}
}
} else if (type === KEYRING_CLASS.WALLETCONNECT) {
if (
!walletConnectStatus.status ||
walletConnectStatus.status === 'DISCONNECTED'
) {
if (account) {
setAccount({
...account,
type,
});
}
activePopup('WalletConnect');
return false;
}
} else if (type === KEYRING_CLASS.HARDWARE.IMKEY) {
if (imKeyStatus.status === 'DISCONNECTED') {
activePopup('ImKeyPermission');
return false;
}
}
return true;
},
[ledgerStatus, walletConnectStatus, imKeyStatus, account]
);
return connect;
};

View File

@@ -2,11 +2,8 @@ import { message, Tooltip } from 'antd';
import clsx from 'clsx';
import {
BRAND_ALIAN_TYPE_TEXT,
KEYRINGS_LOGOS,
KEYRING_CLASS,
KEYRING_ICONS,
KEYRING_TYPE_TEXT,
KeyringWithIcon,
WALLET_BRAND_CONTENT,
} from 'consts';
import React, {
@@ -31,11 +28,9 @@ import IconCheck from 'ui/assets/check.svg';
import { ReactComponent as RcIconWhitelist } from 'ui/assets/address/whitelist.svg';
import { CopyChecked } from '@/ui/component/CopyChecked';
import SkeletonInput from 'antd/lib/skeleton/Input';
import { useWalletConnectIcon } from '@/ui/component/WalletConnect/useWalletConnectIcon';
import { CommonSignal } from '@/ui/component/ConnectStatus/CommonSignal';
import { pickKeyringThemeIcon } from '@/utils/account';
import { useThemeMode } from '@/ui/hooks/usePreference';
import ThemeIcon from '@/ui/component/ThemeMode/ThemeIcon';
import { useBrandIcon } from '@/ui/hooks/useBrandIcon';
export interface AddressItemProps {
balance: number;
@@ -149,32 +144,13 @@ const AddressItem = memo(
};
}, []);
const brandIcon = useWalletConnectIcon({
const addressTypeIcon = useBrandIcon({
address,
brandName,
type,
forceLight: isCurrentAccount,
});
const { isDarkTheme } = useThemeMode();
const addressTypeIcon = useMemo(
() =>
isCurrentAccount
? brandIcon ||
pickKeyringThemeIcon(type as any, {
needLightVersion: true,
}) ||
WALLET_BRAND_CONTENT?.[brandName]?.image ||
KEYRINGS_LOGOS[type]
: brandIcon ||
pickKeyringThemeIcon(brandName as any, {
needLightVersion: isDarkTheme,
}) ||
WALLET_BRAND_CONTENT?.[brandName]?.image ||
KEYRING_ICONS[type],
[type, brandName, brandIcon, isDarkTheme]
);
return (
<div className={clsx(className, 'rabby-address-item-container relative')}>
{canFastDeleteAccount && (

View File

@@ -1,26 +1,14 @@
import { Account } from '@/background/service/preference';
import {
KEYRING_ICONS,
KEYRING_CLASS,
WALLET_BRAND_CONTENT,
WALLET_BRAND_TYPES,
KEYRING_ICONS_WHITE,
} from '@/constant';
import { KEYRING_CLASS } from '@/constant';
import { AddressViewer } from '@/ui/component';
import useCurrentBalance from '@/ui/hooks/useCurrentBalance';
import { splitNumberByStep, useWallet } from '@/ui/utils';
import clsx from 'clsx';
import React from 'react';
import { WalletConnectAccount } from './WalletConnectAccount';
import { Chain } from '@debank/common';
import { LedgerAccount } from './LedgerAccount';
import { CommonAccount } from './CommonAccount';
import { KeystoneAccount } from './KeystoneAccount';
import { GridPlusAccount } from './GridPlusAccount';
import { Tooltip } from 'antd';
import { useTranslation } from 'react-i18next';
import { useThemeMode } from '@/ui/hooks/usePreference';
import { ImKeyAccount } from './ImKeyAccount';
import { useBrandIcon } from '@/ui/hooks/useBrandIcon';
export interface Props {
account: Account;
@@ -62,26 +50,47 @@ export const AccountInfo: React.FC<Props> = ({
init();
}, [account]);
const { isDarkTheme } = useThemeMode();
const brandIcon = useBrandIcon({
address: account?.address,
brandName: account?.brandName,
type: account?.type,
});
const nicknameRef = React.useRef<HTMLDivElement>(null);
const [enableTooltip, setEnableTooltip] = React.useState(false);
React.useEffect(() => {
if (nicknameRef.current) {
setEnableTooltip(
nicknameRef.current.offsetWidth < nicknameRef.current.scrollWidth
);
}
}, [nickname]);
return (
<div
className={clsx(
'bg-r-neutral-card-3 rounded-[8px]',
'py-[12px] px-[16px] mb-[12px]',
'py-[12px] px-[12px] mb-[12px]',
'space-y-6'
)}
>
<div className={clsx('flex items-center justify-between', 'h-18')}>
<div className="space-x-6 flex items-center">
<div
className={clsx('flex items-center justify-between', 'h-18 gap-x-16')}
>
<div className="space-x-6 flex items-center overflow-hidden">
<img src={brandIcon} className="w-18 h-18" />
<Tooltip
overlayClassName="rectangle w-[max-content]"
title={nickname}
trigger={enableTooltip ? 'hover' : ''}
>
<div
ref={nicknameRef}
className={clsx(
'text-r-neutral-body text-[15px]',
'max-w-[170px] overflow-ellipsis whitespace-nowrap overflow-hidden',
'overflow-ellipsis whitespace-nowrap overflow-hidden',
'leading-[20px]'
)}
>
@@ -94,6 +103,7 @@ export const AccountInfo: React.FC<Props> = ({
className={clsx('text-13 text-r-neutral-foot')}
/>
</div>
{isTestnet ? null : (
<div
className="text-13 font-normal text-r-neutral-foot"
@@ -103,134 +113,6 @@ export const AccountInfo: React.FC<Props> = ({
</div>
)}
</div>
{account?.type === KEYRING_CLASS.WALLETCONNECT && (
<WalletConnectAccount chain={chain} account={account} />
)}
{account?.type === KEYRING_CLASS.HARDWARE.LEDGER && <LedgerAccount />}
{account?.type === KEYRING_CLASS.HARDWARE.IMKEY && <ImKeyAccount />}
{account?.type === KEYRING_CLASS.HARDWARE.GRIDPLUS && <GridPlusAccount />}
{account?.type === KEYRING_CLASS.HARDWARE.ONEKEY && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.ONEKEY.lightIcon
: WALLET_BRAND_CONTENT.ONEKEY.icon
}
tip={t('page.signFooterBar.addressTip.onekey')}
/>
)}
{account?.type === KEYRING_CLASS.HARDWARE.TREZOR && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.TREZOR.lightIcon
: WALLET_BRAND_CONTENT.TREZOR.icon
}
tip={t('page.signFooterBar.addressTip.trezor')}
/>
)}
{account?.type === KEYRING_CLASS.HARDWARE.BITBOX02 && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.BITBOX02.lightIcon
: WALLET_BRAND_CONTENT.BITBOX02.icon
}
tip={t('page.signFooterBar.addressTip.bitbox')}
/>
)}
{account?.brandName === WALLET_BRAND_TYPES.KEYSTONE && (
<KeystoneAccount />
)}
{account?.brandName === WALLET_BRAND_TYPES.AIRGAP && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.AirGap.lightIcon
: WALLET_BRAND_CONTENT.AirGap.icon
}
tip={t('page.signFooterBar.addressTip.airgap')}
/>
)}
{account?.brandName === WALLET_BRAND_TYPES.COOLWALLET && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.CoolWallet.lightIcon
: WALLET_BRAND_CONTENT.CoolWallet.icon
}
tip={t('page.signFooterBar.addressTip.coolwallet')}
/>
)}
{account?.brandName === WALLET_BRAND_TYPES.IMTOKENOFFLINE && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.imTokenOffline.lightIcon
: WALLET_BRAND_CONTENT.imTokenOffline.icon
}
tip={t('page.signFooterBar.addressTip.coolwallet')}
/>
)}
{account?.type === KEYRING_CLASS.PRIVATE_KEY && (
<CommonAccount
icon={
(isDarkTheme ? KEYRING_ICONS_WHITE : KEYRING_ICONS)[
KEYRING_CLASS.PRIVATE_KEY
]
}
grayIcon
tip={t('page.signFooterBar.addressTip.privateKey')}
/>
)}
{account?.type === KEYRING_CLASS.MNEMONIC && (
<CommonAccount
icon={
(isDarkTheme ? KEYRING_ICONS_WHITE : KEYRING_ICONS)[
KEYRING_CLASS.MNEMONIC
]
}
grayIcon
tip={
needPassphrase
? t('page.signFooterBar.addressTip.seedPhraseWithPassphrase')
: t('page.signFooterBar.addressTip.seedPhrase')
}
/>
)}
{account?.type === KEYRING_CLASS.WATCH && (
<CommonAccount
icon={
(isDarkTheme ? KEYRING_ICONS_WHITE : KEYRING_ICONS)[
KEYRING_CLASS.WATCH
]
}
tip={t('page.signFooterBar.addressTip.watchAddress')}
/>
)}
{account?.type === KEYRING_CLASS.GNOSIS && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.Gnosis.lightIcon
: WALLET_BRAND_CONTENT.Gnosis.icon
}
tip={t('page.signFooterBar.addressTip.safe')}
/>
)}
{account?.type === KEYRING_CLASS.CoboArgus && (
<CommonAccount
icon={
isDarkTheme
? WALLET_BRAND_CONTENT.CoboArgus.lightIcon
: WALLET_BRAND_CONTENT.CoboArgus.icon
}
tip={t('page.signFooterBar.addressTip.coboSafe')}
/>
)}
{account?.type === KEYRING_CLASS.Coinbase && (
<WalletConnectAccount chain={chain} account={account} />
)}
</div>
);
};

View File

@@ -1,16 +1,9 @@
import React from 'react';
import { Props } from './ActionsContainer';
import { ProcessActions } from './ProcessActions';
import { useGridPlusStatus } from '@/ui/component/ConnectStatus/useGridPlusStatus';
export const GridPlusProcessActions: React.FC<Props> = (props) => {
const { disabledProcess } = props;
const { status } = useGridPlusStatus();
return (
<ProcessActions
{...props}
disabledProcess={status !== 'CONNECTED' || disabledProcess}
/>
);
return <ProcessActions {...props} disabledProcess={disabledProcess} />;
};

View File

@@ -1,16 +1,9 @@
import React from 'react';
import { Props } from './ActionsContainer';
import { ProcessActions } from './ProcessActions';
import { useImKeyStatus } from '@/ui/component/ConnectStatus/useImKeyStatus';
export const ImKeyProcessActions: React.FC<Props> = (props) => {
const { disabledProcess } = props;
const { status } = useImKeyStatus();
return (
<ProcessActions
{...props}
disabledProcess={status !== 'CONNECTED' || disabledProcess}
/>
);
return <ProcessActions {...props} disabledProcess={disabledProcess} />;
};

View File

@@ -1,16 +1,9 @@
import React from 'react';
import { Props } from './ActionsContainer';
import { ProcessActions } from './ProcessActions';
import { useLedgerStatus } from '@/ui/component/ConnectStatus/useLedgerStatus';
export const LedgerProcessActions: React.FC<Props> = (props) => {
const { disabledProcess } = props;
const { status } = useLedgerStatus();
return (
<ProcessActions
{...props}
disabledProcess={status !== 'CONNECTED' || disabledProcess}
/>
);
return <ProcessActions {...props} disabledProcess={disabledProcess} />;
};

View File

@@ -1,4 +1,4 @@
import { Button, Tooltip } from 'antd';
import { Button } from 'antd';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { ActionsContainer, Props } from './ActionsContainer';
@@ -7,6 +7,7 @@ import { ReactComponent as IconClose } from 'ui/assets/close-16-cc.svg';
import { GasLessAnimatedWrapper } from './GasLessComponents';
import styled from 'styled-components';
import { LoadingOutlined } from '@ant-design/icons';
import { TooltipWithMagnetArrow } from '@/ui/component/Tooltip/TooltipWithMagnetArrow';
const ButtonStyled = styled(Button)`
&:hover {
@@ -86,9 +87,11 @@ export const SubmitActions: React.FC<Props> = ({
</button>
</div>
) : (
<Tooltip
<TooltipWithMagnetArrow
overlayClassName="rectangle sign-tx-forbidden-tooltip"
title={enableTooltip ? tooltipContent : null}
inApproval
viewportOffset={[20, -20, -20, 20]}
>
<GasLessAnimatedWrapper>
<ButtonStyled
@@ -116,7 +119,7 @@ export const SubmitActions: React.FC<Props> = ({
{t('page.signFooterBar.signAndSubmitButton')}
</ButtonStyled>
</GasLessAnimatedWrapper>
</Tooltip>
</TooltipWithMagnetArrow>
)}
</ActionsContainer>
);

View File

@@ -1,14 +1,9 @@
import { Account } from '@/background/service/preference';
import {
KEYRINGS_LOGOS,
WALLET_BRAND_CONTENT,
WALLET_BRAND_TYPES,
} from '@/constant';
import { WALLET_BRAND_TYPES } from '@/constant';
import { SessionSignal } from '@/ui/component/WalletConnect/SessionSignal';
import { useDisplayBrandName } from '@/ui/component/WalletConnect/useDisplayBrandName';
import { useSessionChainId } from '@/ui/component/WalletConnect/useSessionChainId';
import { useSessionStatus } from '@/ui/component/WalletConnect/useSessionStatus';
import { useWalletConnectIcon } from '@/ui/component/WalletConnect/useWalletConnectIcon';
import { useCommonPopupView, useWallet } from '@/ui/utils';
import { Chain } from '@debank/common';
import { Button } from 'antd';
@@ -16,6 +11,7 @@ import clsx from 'clsx';
import React from 'react';
import { useTranslation } from 'react-i18next';
import { CommonAccount } from './CommonAccount';
import { useBrandIcon } from '@/ui/hooks/useBrandIcon';
export interface Props {
account: Account;
@@ -26,18 +22,12 @@ export const WalletConnectAccount: React.FC<Props> = ({ account, chain }) => {
const { activePopup, setAccount, setVisible } = useCommonPopupView();
const { t } = useTranslation();
const { address, brandName, type } = account;
const brandIcon = useWalletConnectIcon({
const addressTypeIcon = useBrandIcon({
address,
brandName,
type,
});
const addressTypeIcon = React.useMemo(
() =>
brandIcon ||
WALLET_BRAND_CONTENT?.[brandName]?.image ||
KEYRINGS_LOGOS[type],
[type, brandName, brandIcon]
);
const [displayBrandName, realBrandName] = useDisplayBrandName(
brandName,
address

View File

@@ -1,54 +1,9 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Props } from './ActionsContainer';
import { useDisplayBrandName } from '@/ui/component/WalletConnect/useDisplayBrandName';
import { useSessionChainId } from '@/ui/component/WalletConnect/useSessionChainId';
import { useSessionStatus } from '@/ui/component/WalletConnect/useSessionStatus';
import { ProcessActions } from './ProcessActions';
export const WalletConnectProcessActions: React.FC<Props> = (props) => {
const {
account,
disabledProcess,
tooltipContent,
enableTooltip,
chain,
} = props;
const { t } = useTranslation();
const { status } = useSessionStatus(account);
const sessionChainId = useSessionChainId(account);
const chainError = chain && sessionChainId !== chain.id;
const [displayBrandName] = useDisplayBrandName(
account.brandName,
account.address
);
const content = React.useMemo(() => {
if (status === 'ACCOUNT_ERROR') {
return t('page.signFooterBar.walletConnect.wrongAddressAlert');
}
const { disabledProcess } = props;
if (!status || status === 'DISCONNECTED') {
return t('page.signFooterBar.walletConnect.connectBeforeSign', [
displayBrandName,
]);
}
// if (chainError) {
// return t('page.signFooterBar.walletConnect.chainSwitched', [chain.name]);
// }
return enableTooltip ? tooltipContent : undefined;
}, [enableTooltip, tooltipContent, status, chainError, displayBrandName]);
return (
<ProcessActions
{...props}
tooltipContent={content}
disabledProcess={
(status !== 'CONNECTED' && status !== 'CHAIN_CHANGED') ||
// chainError ||
disabledProcess
}
/>
);
return <ProcessActions {...props} disabledProcess={disabledProcess} />;
};

View File

@@ -8,10 +8,7 @@ import clsx from 'clsx';
import { EVENTS, KEYRING_CLASS } from 'consts';
import React, { ReactNode } from 'react';
import { ReactComponent as LedgerSVG } from 'ui/assets/walletlogo/ledger.svg';
import {
ActionGroup,
Props as ActionGroupProps,
} from '../FooterBar/ActionGroup';
import { Props as ActionGroupProps } from '../FooterBar/ActionGroup';
import { GasLessConfig } from '../FooterBar/GasLessComponents';
import { ProcessActions } from '../FooterBar/ProcessActions';
import { Dots } from '../Popup/Dots';

View File

@@ -218,7 +218,6 @@ export const MiniSignTx = ({
const wallet = useWallet();
const [support1559, setSupport1559] = useState(chain.eip['1559']);
const [isLedger, setIsLedger] = useState(false);
const hasConnectedLedgerHID = useLedgerDeviceConnected();
const { userData, rules, currentTx, tokenDetail } = useRabbySelector((s) => ({
userData: s.securityEngine.userData,
rules: s.securityEngine.rules,

View File

@@ -226,7 +226,6 @@ export const SignTestnetTx = ({ params, origin }: SignTxProps) => {
const [nonceChanged, setNonceChanged] = useState(false);
const [isReady, setIsReady] = useState(false);
const [isLedger, setIsLedger] = useState(false);
const hasConnectedLedgerHID = useLedgerDeviceConnected();
const [isHardware, setIsHardware] = useState(false);
const [nativeTokenBalance, setNativeTokenBalance] = useState('0x0');
const [canProcess, setCanProcess] = useState(true);
@@ -771,7 +770,6 @@ export const SignTestnetTx = ({ params, origin }: SignTxProps) => {
(selectedGas ? selectedGas.price < 0 : true) ||
isGnosisAccount ||
isCoboArugsAccount ||
(isLedger && !hasConnectedLedgerHID) ||
!canProcess ||
!!checkErrors.find((item) => item.level === 'forbidden')
}

View File

@@ -67,7 +67,6 @@ const SignText = ({ params }: { params: SignTextProps }) => {
const [isWatch, setIsWatch] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [isLedger, setIsLedger] = useState(false);
const hasConnectedLedgerHID = useLedgerDeviceConnected();
const [
cantProcessReason,
setCantProcessReason,
@@ -274,7 +273,7 @@ const SignText = ({ params }: { params: SignTextProps }) => {
if (accountType === KEYRING_TYPE.WatchAddressKeyring) {
setIsWatch(true);
setCantProcessReason(
<div>You can only use imported addresses to sign</div>
<div>{t('page.signTx.canOnlyUseImportedAddress')}</div>
);
}
if (accountType === KEYRING_TYPE.GnosisKeyring && !params.account) {
@@ -450,11 +449,7 @@ const SignText = ({ params }: { params: SignTextProps }) => {
tooltipContent={cantProcessReason}
onCancel={handleCancel}
onSubmit={() => handleAllow()}
disabledProcess={
(isLedger && !hasConnectedLedgerHID) ||
isWatch ||
hasUnProcessSecurityResult
}
disabledProcess={isWatch || hasUnProcessSecurityResult}
engineResults={engineResults}
onIgnoreAllRules={handleIgnoreAllRules}
/>

View File

@@ -468,7 +468,6 @@ const SignTx = ({ params, origin }: SignTxProps) => {
if (!chain) throw new Error('No support chain found');
const [support1559, setSupport1559] = useState(chain.eip['1559']);
const [isLedger, setIsLedger] = useState(false);
const hasConnectedLedgerHID = useLedgerDeviceConnected();
const { userData, rules, currentTx, tokenDetail } = useRabbySelector((s) => ({
userData: s.securityEngine.userData,
rules: s.securityEngine.rules,
@@ -2092,7 +2091,6 @@ const SignTx = ({ params, origin }: SignTxProps) => {
(selectedGas ? selectedGas.price < 0 : true) ||
(isGnosisAccount ? !safeInfo : false) ||
(isCoboArugsAccount ? !coboArgusInfo : false) ||
(isLedger && !hasConnectedLedgerHID) ||
!canProcess ||
!!checkErrors.find((item) => item.level === 'forbidden') ||
hasUnProcessSecurityResult ||

View File

@@ -82,7 +82,6 @@ const SignTypedData = ({ params }: { params: SignTypedDataProps }) => {
const [footerShowShadow, setFooterShowShadow] = useState(false);
const { executeEngine } = useSecurityEngine();
const [engineResults, setEngineResults] = useState<Result[]>([]);
const hasConnectedLedgerHID = useLedgerDeviceConnected();
const dispatch = useRabbyDispatch();
const { userData, rules, currentTx, tokenDetail } = useRabbySelector((s) => ({
userData: s.securityEngine.userData,
@@ -681,12 +680,7 @@ const SignTypedData = ({ params }: { params: SignTypedDataProps }) => {
onSubmit={() => handleAllow()}
enableTooltip={isWatch}
tooltipContent={cantProcessReason}
disabledProcess={
isLoading ||
(isLedger && !hasConnectedLedgerHID) ||
isWatch ||
hasUnProcessSecurityResult
}
disabledProcess={isLoading || isWatch || hasUnProcessSecurityResult}
isTestnet={chain?.isTestnet}
onIgnoreAllRules={handleIgnoreAllRules}
/>

View File

@@ -22,11 +22,12 @@ export const Ledger: React.FC<{
}
}, [!isModalContent]);
React.useEffect(() => {
if (!isModalContent && hasConnectedLedgerHID) {
closePopup();
}
}, [hasConnectedLedgerHID, !isModalContent]);
// React.useEffect(() => {
// if (!isModalContent && hasConnectedLedgerHID && mounted.current) {
// closePopup();
// }
// mounted.current = true;
// }, [hasConnectedLedgerHID, !isModalContent]);
const handleClick = async () => {
if (!isModalContent) {

View File

@@ -1,13 +1,9 @@
import React, { useMemo, useState } from 'react';
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { AddressViewer, Popup } from '@/ui/component';
import { Button } from 'antd';
import { PopupProps } from '@/ui/component/Popup';
import { useWalletConnectIcon } from '@/ui/component/WalletConnect/useWalletConnectIcon';
import { useCurrentAccount } from '@/ui/hooks/backgroundState/useAccount';
import { useThemeMode } from '@/ui/hooks/usePreference';
import { pickKeyringThemeIcon } from '@/utils/account';
import { KEYRING_ICONS, WALLET_BRAND_CONTENT } from '@/constant';
import { noop } from 'lodash';
import clsx from 'clsx';
import { CopyChecked } from '@/ui/component/CopyChecked';
@@ -18,6 +14,7 @@ import { ReactComponent as RcIconQuoteStart } from '@/ui/assets/gas-account/quot
import { ReactComponent as RcIconQuoteEnd } from '@/ui/assets/gas-account/quote-end.svg';
import { GasAccountBlueLogo } from './GasAccountBlueLogo';
import { GasAccountWrapperBg } from './WrapperBg';
import { useBrandIcon } from '@/ui/hooks/useBrandIcon';
export const GasACcountCurrentAddress = ({
account,
@@ -30,30 +27,13 @@ export const GasACcountCurrentAddress = ({
}) => {
const currentAccount = useCurrentAccount();
const { isDarkTheme } = useThemeMode();
const [alias] = useAlias(account?.address || currentAccount?.address || '');
const brandIcon = useWalletConnectIcon({
const addressTypeIcon = useBrandIcon({
address: currentAccount!.address,
brandName: currentAccount!.brandName,
type: currentAccount!.type,
});
const [alias] = useAlias(account?.address || currentAccount?.address || '');
const addressTypeIcon = useMemo(
() =>
brandIcon ||
pickKeyringThemeIcon(
account?.brandName || (currentAccount!.brandName as any),
{
needLightVersion: isDarkTheme,
}
) ||
WALLET_BRAND_CONTENT?.[account?.brandName || currentAccount!.brandName]
?.image ||
KEYRING_ICONS[account?.type || currentAccount!.type],
[currentAccount, brandIcon, isDarkTheme]
);
return (
<div className="mb-[20px] py-12 px-16 rounded-[6px] flex items-center bg-r-neutral-card-2">
<img src={addressTypeIcon} className="w-24 h-24" />