-
{actionName}
-
- {data.contractCall && (
-
- {t('page.signTx.unknownActionType')}{' '}
-
-
-
-
- )}
+ {!data.contractCall && (
+
-
+ )}
{data.swap && (
{
const wallet = useWallet();
const [, resolveApproval, rejectApproval] = useApproval();
@@ -182,6 +83,14 @@ const AddChain = ({ params }: { params: AddChainProps }) => {
init();
}, []);
+ useEffect(() => {
+ if (state.isShowUnsupportAlert) {
+ wallet.updateNotificationWinProps({
+ height: 388,
+ });
+ }
+ }, [state.isShowUnsupportAlert]);
+
const handleConfirm = () => {
resolveApproval();
};
@@ -200,26 +109,7 @@ const AddChain = ({ params }: { params: AddChainProps }) => {
if (!inited) return <>>;
if (state.isShowUnsupportAlert) {
- return (
-
-
-
-
- {t('page.switchChain.chainNotSupport')}
-
-
-
-
- );
+ return ;
}
if (state.isSwitchToMainnet || state.isSwitchToTestnet) {
diff --git a/src/ui/views/Approval/components/AddChain/UnsupportedAlert.tsx b/src/ui/views/Approval/components/AddChain/UnsupportedAlert.tsx
new file mode 100644
index 00000000000..c27c9939351
--- /dev/null
+++ b/src/ui/views/Approval/components/AddChain/UnsupportedAlert.tsx
@@ -0,0 +1,123 @@
+import { Button } from 'antd';
+import React from 'react';
+import { ReactComponent as IconInfo } from '@/ui/assets/add-chain/info.svg';
+import { ReactComponent as IconEmail } from '@/ui/assets/add-chain/email.svg';
+import { noop, useApproval, useWallet } from '@/ui/utils';
+import { useTranslation } from 'react-i18next';
+import { Footer } from './style';
+import { AddEthereumChainParams } from './type';
+import IconUnknown from '@/ui/assets/token-default.svg';
+import clsx from 'clsx';
+import { useAccount } from '@/ui/store-hooks';
+
+interface Props {
+ data: AddEthereumChainParams;
+}
+
+export const UnsupportedAlert: React.FC = ({ data }) => {
+ const [, , rejectApproval] = useApproval();
+ const { t } = useTranslation();
+ const [imgUrl, setImgUrl] = React.useState(data.rpcUrls?.[0]);
+ const [isRequested, setIsRequested] = React.useState(false);
+ const wallet = useWallet();
+ const [currentAccount] = useAccount();
+ const [requestedCount, setRequestedCount] = React.useState(1);
+ const [isRequesting, setIsRequesting] = React.useState(false);
+
+ React.useEffect(() => {
+ const img = new Image();
+ img.src = data.rpcUrls?.[0];
+ img.onload = () => {
+ setImgUrl(data.rpcUrls[0]);
+ };
+ img.onerror = () => {
+ setImgUrl(IconUnknown);
+ };
+ }, [data]);
+
+ const handleRequest = React.useCallback(() => {
+ setIsRequesting(true);
+ wallet.openapi
+ .walletSupportChain({
+ chain_id: data.chainId,
+ user_addr: currentAccount!.address,
+ })
+ .then((res) => {
+ setRequestedCount(res.count ? res.count : 1);
+ setIsRequested(true);
+ });
+ }, [data, currentAccount]);
+
+ return (
+
+
+
+ {t('page.switchChain.chainId')}
+ {data.chainId}
+
+
+
+
{data.chainName ?? t('page.switchChain.unknownChain')}
+
+
+
+
+ {t('page.switchChain.chainNotSupportYet')}
+
+
+
+ {isRequested ? (
+
+ {requestedCount > 1
+ ? t('page.switchChain.requestsReceivedPlural', {
+ count: requestedCount,
+ })
+ : t('page.switchChain.requestsReceived')}
+
+ ) : (
+
+
+
+ {t('page.switchChain.requestRabbyToSupport')}
+
+
+ )}
+
+
+
+
+
+ );
+};
diff --git a/src/ui/views/Approval/components/AddChain/style.ts b/src/ui/views/Approval/components/AddChain/style.ts
new file mode 100644
index 00000000000..5bebef6f495
--- /dev/null
+++ b/src/ui/views/Approval/components/AddChain/style.ts
@@ -0,0 +1,89 @@
+import styled from 'styled-components';
+
+export const OptionsWrapper = styled.div`
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+
+ .content {
+ padding: 20px;
+ }
+
+ .title {
+ color: #13141a;
+ font-size: 20px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: normal;
+ margin-bottom: 40px;
+ }
+ .connect-site-card {
+ border-radius: 8px;
+ background: #f5f6fa;
+ display: inline-flex;
+ padding: 28px 28px 32px 28px;
+ width: 100%;
+ flex-direction: column;
+ align-items: center;
+ gap: 14px;
+ margin-bottom: 40px;
+
+ .site-origin {
+ color: #13141a;
+ text-align: center;
+ font-size: 22px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: normal;
+ }
+ }
+ .switch-chain {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 12px;
+ }
+ .chain-card {
+ display: flex;
+ width: 260px;
+ padding: 12px;
+ justify-content: center;
+ align-items: center;
+ gap: 8px;
+ border-radius: 6px;
+ border: 1px solid #e5e9ef;
+
+ color: #13141a;
+ font-size: 20px;
+ font-style: normal;
+ font-weight: 500;
+ line-height: normal;
+
+ img {
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ flex-shrink: 0;
+ }
+ }
+`;
+
+export const Footer = styled.div`
+ margin-top: auto;
+ height: 76px;
+ border-top: 1px solid #e5e9ef;
+ padding: 16px 20px;
+ display: flex;
+ justify-content: space-between;
+ .ant-btn-primary[disabled],
+ .ant-btn-primary[disabled]:hover,
+ .ant-btn-primary[disabled]:focus,
+ .ant-btn-primary[disabled]:active {
+ background-color: rgba(112, 132, 255, 0.4);
+ border: none;
+ &:before {
+ display: none;
+ }
+ }
+`;
diff --git a/src/ui/views/Approval/components/AddChain/type.ts b/src/ui/views/Approval/components/AddChain/type.ts
new file mode 100644
index 00000000000..0ef2428fb59
--- /dev/null
+++ b/src/ui/views/Approval/components/AddChain/type.ts
@@ -0,0 +1,11 @@
+export interface AddEthereumChainParams {
+ chainId: string;
+ chainName: string;
+ nativeCurrency: {
+ name: string;
+ symbol: string;
+ decimals: number;
+ };
+ rpcUrls: string[];
+ blockExplorerUrls: string[];
+}
diff --git a/src/ui/views/Approval/components/NoActionAlert/NoActionAlert.tsx b/src/ui/views/Approval/components/NoActionAlert/NoActionAlert.tsx
new file mode 100644
index 00000000000..d0c9a2298a9
--- /dev/null
+++ b/src/ui/views/Approval/components/NoActionAlert/NoActionAlert.tsx
@@ -0,0 +1,109 @@
+import { useTranslation } from 'react-i18next';
+import styled from 'styled-components';
+import IconAlert from '@/ui/assets/sign/tx/alert.svg';
+import React from 'react';
+import clsx from 'clsx';
+import { ReactComponent as IconEmail } from '@/ui/assets/add-chain/email.svg';
+import { useAccount } from '@/ui/store-hooks';
+import { noop, useWallet } from '@/ui/utils';
+
+const NoActionAlertStyled = styled.div`
+ display: flex;
+ align-items: center;
+ flex-direction: column;
+ background: var(--r-neutral-card-1);
+ border-radius: 6px;
+ padding: 15px;
+ font-weight: 500;
+ font-size: 13px;
+ line-height: 18px;
+ color: var(--r-neutral-body);
+ margin-bottom: 15px;
+ .icon-alert {
+ margin-right: 4px;
+ width: 14px;
+ margin-top: 2px;
+ }
+`;
+
+type SupportOrigin = {
+ origin: string;
+ text: string;
+};
+
+type SupportSelector = {
+ chainId: string;
+ contractAddress?: string;
+ selector?: string;
+};
+
+interface Props {
+ data: SupportOrigin | SupportSelector;
+}
+
+export const NoActionAlert: React.FC = ({ data }) => {
+ const { t } = useTranslation();
+ const [isRequested, setIsRequested] = React.useState(false);
+ const wallet = useWallet();
+ const [currentAccount] = useAccount();
+ const [requestedCount, setRequestedCount] = React.useState(1);
+ const [isRequesting, setIsRequesting] = React.useState(false);
+
+ const handleRequest = React.useCallback(() => {
+ setIsRequesting(true);
+ let promise;
+ if ('origin' in data) {
+ promise = wallet.openapi.walletSupportOrigin({
+ origin: data.origin,
+ user_addr: currentAccount!.address,
+ text: data.text,
+ });
+ } else {
+ promise = wallet.openapi.walletSupportSelector({
+ chain_id: data.chainId,
+ contract_id: data.contractAddress ?? '',
+ selector: (data.selector ?? '').slice(0, 10),
+ user_addr: currentAccount!.address,
+ });
+ }
+
+ promise.then((res) => {
+ setRequestedCount(res.count ? res.count : 1);
+ setIsRequested(true);
+ });
+ }, [data, currentAccount]);
+
+ return (
+
+
+
+ {t('page.signTx.sigCantDecode')}
+
+
+
+ {isRequested ? (
+
+ {requestedCount > 1
+ ? t('page.switchChain.requestsReceivedPlural', {
+ count: requestedCount,
+ })
+ : t('page.switchChain.requestsReceived')}
+
+ ) : (
+
+
+
+ {t('page.switchChain.requestRabbyToSupport')}
+
+
+ )}
+
+
+ );
+};
diff --git a/src/ui/views/Approval/components/SignText.tsx b/src/ui/views/Approval/components/SignText.tsx
index 866c9c28c03..6e9133cf826 100644
--- a/src/ui/views/Approval/components/SignText.tsx
+++ b/src/ui/views/Approval/components/SignText.tsx
@@ -357,6 +357,7 @@ const SignText = ({ params }: { params: SignTextProps }) => {
engineResults={engineResults}
raw={hexData}
message={signText}
+ origin={params.session.origin}
/>
)}
diff --git a/src/ui/views/Approval/components/SignTypedData.tsx b/src/ui/views/Approval/components/SignTypedData.tsx
index 6d3f7812f8b..d0b5e956b06 100644
--- a/src/ui/views/Approval/components/SignTypedData.tsx
+++ b/src/ui/views/Approval/components/SignTypedData.tsx
@@ -520,6 +520,7 @@ const SignTypedData = ({ params }: { params: SignTypedDataProps }) => {
engineResults={engineResults}
raw={isSignTypedDataV1 ? data[0] : signTypedData || data[1]}
message={parsedMessage}
+ origin={params.session.origin}
/>
)}
diff --git a/src/ui/views/Approval/components/TextActions/index.tsx b/src/ui/views/Approval/components/TextActions/index.tsx
index f69b5232547..ed429c52bb4 100644
--- a/src/ui/views/Approval/components/TextActions/index.tsx
+++ b/src/ui/views/Approval/components/TextActions/index.tsx
@@ -10,6 +10,7 @@ import VerifyAddress from './VerifyAddress';
import IconAlert from 'ui/assets/sign/tx/alert.svg';
import clsx from 'clsx';
import { Popup } from 'ui/component';
+import { NoActionAlert } from '../NoActionAlert/NoActionAlert';
const { TabPane } = Tabs;
@@ -87,24 +88,6 @@ export const ActionWrapper = styled.div`
}
`;
-const NoActionAlert = styled.div`
- display: flex;
- align-items: flex-start;
- background: #e8eaf3;
- border-radius: 6px;
- padding: 15px;
- font-weight: 500;
- font-size: 13px;
- line-height: 18px;
- color: #333333;
- margin-bottom: 15px;
- .icon-alert {
- margin-right: 8px;
- width: 15px;
- margin-top: 1px;
- }
-`;
-
const MessageWrapper = styled.div`
.title {
position: relative;
@@ -161,11 +144,13 @@ const Actions = ({
engineResults,
raw,
message,
+ origin,
}: {
data: TextActionData | null;
engineResults: Result[];
raw: string;
message: string;
+ origin: string;
}) => {
const actionName = useMemo(() => {
if (!data) return '';
@@ -223,10 +208,12 @@ const Actions = ({