From 9d2e0daae025bbe604633f7aa5566a0fe4566d7c Mon Sep 17 00:00:00 2001 From: zzggo Date: Mon, 16 Dec 2024 22:52:57 +1100 Subject: [PATCH 1/5] feat: decode call contract data --- src/background/controller/wallet.ts | 25 +- src/background/service/openapi.ts | 9 + src/ui/FRWAssets/svg/transactionFeeIcon.svg | 10 + src/ui/FRWComponent/Approval/SignHeader.tsx | 212 ++++++++++++ src/ui/FRWComponent/Approval/index.tsx | 1 + src/ui/FRWComponent/CopyButton.tsx | 29 ++ src/ui/FRWComponent/index.tsx | 1 + .../EthApproval/EthConfirm/DefaultBlock.tsx | 234 ++----------- .../EthConfirm/TransactionBlock.tsx | 320 ++++++++++++++++++ .../EthApproval/EthConfirm/index.tsx | 240 ++++++------- .../EthApproval/EthSignType/DefaultBlock.tsx | 279 --------------- .../EthApproval/EthSignV1/DefaultBlock.tsx | 279 --------------- 12 files changed, 724 insertions(+), 915 deletions(-) create mode 100644 src/ui/FRWAssets/svg/transactionFeeIcon.svg create mode 100644 src/ui/FRWComponent/Approval/SignHeader.tsx create mode 100644 src/ui/FRWComponent/Approval/index.tsx create mode 100644 src/ui/FRWComponent/CopyButton.tsx create mode 100644 src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx delete mode 100644 src/ui/views/Approval/components/EthApproval/EthSignType/DefaultBlock.tsx delete mode 100644 src/ui/views/Approval/components/EthApproval/EthSignV1/DefaultBlock.tsx diff --git a/src/background/controller/wallet.ts b/src/background/controller/wallet.ts index f2633672..04266efb 100644 --- a/src/background/controller/wallet.ts +++ b/src/background/controller/wallet.ts @@ -1074,17 +1074,6 @@ export class WalletController extends BaseController { return result; } - private async getFixedTokenPrice(symbol: string): Promise { - if (symbol === 'usdc') { - return await openapiService.getUSDCPrice(); - } else if (symbol === 'fusd') { - return Promise.resolve({ - price: { last: '1.0', change: { percentage: '0.0' } }, - }); - } - return null; - } - private async calculateTokenPrice(token: string, price: string | null): Promise { if (price) { return { price: { last: price, change: { percentage: '0.0' } } }; @@ -1108,9 +1097,6 @@ export class WalletController extends BaseController { return this.getFlowTokenPrice(flowPrice); } - const fixedTokenPrice = await this.getFixedTokenPrice(token); - if (fixedTokenPrice) return fixedTokenPrice; - return this.calculateTokenPrice(token, price); } @@ -1123,9 +1109,6 @@ export class WalletController extends BaseController { return this.getFlowTokenPrice(flowPrice); } - const fixedTokenPrice = await this.getFixedTokenPrice(token); - if (fixedTokenPrice) return fixedTokenPrice; - return this.calculateTokenPrice(token, price); } @@ -1962,10 +1945,8 @@ export class WalletController extends BaseController { return await userWalletService.sendTransaction(script, [fcl.arg(formattedAmount, t.UFix64)]); }; - coaLink = async (amount = '1.0'): Promise => { + coaLink = async (): Promise => { await this.getNetwork(); - // TODO: This doesn't seem to be used anywhere - const formattedAmount = parseFloat(amount).toFixed(8); const script = await getScripts('evm', 'coaLink'); @@ -4097,6 +4078,10 @@ export class WalletController extends BaseController { source: source, }); }; + + decodeEvmCall = async (callData: string, address = '') => { + return await openapiService.decodeEvmCall(callData, address); + }; } export default new WalletController(); diff --git a/src/background/service/openapi.ts b/src/background/service/openapi.ts index a9298677..5aa2b2f6 100644 --- a/src/background/service/openapi.ts +++ b/src/background/service/openapi.ts @@ -2188,6 +2188,15 @@ class OpenApiService { return data; }; + decodeEvmCall = async (data: string, address = '') => { + const bodyData = { + to: address, // address -- optional + data: data, // calldata -- required + }; + const res = await this.sendRequest('POST', `/api/evm/decodeData`, {}, bodyData, WEB_NEXT_URL); + return res; + }; + EvmNFTcollectionList = async ( address: string, collectionIdentifier: string, diff --git a/src/ui/FRWAssets/svg/transactionFeeIcon.svg b/src/ui/FRWAssets/svg/transactionFeeIcon.svg new file mode 100644 index 00000000..6985cbf7 --- /dev/null +++ b/src/ui/FRWAssets/svg/transactionFeeIcon.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/ui/FRWComponent/Approval/SignHeader.tsx b/src/ui/FRWComponent/Approval/SignHeader.tsx new file mode 100644 index 00000000..78f883c6 --- /dev/null +++ b/src/ui/FRWComponent/Approval/SignHeader.tsx @@ -0,0 +1,212 @@ +import { Box, CardMedia, Typography } from '@mui/material'; +import Avatar from '@mui/material/Avatar'; +import { makeStyles } from '@mui/styles'; +import React, { useState, useEffect } from 'react'; +import { useHistory } from 'react-router-dom'; + +import IconCheck from 'ui/assets/check.svg'; +import { LLPrimaryButton } from 'ui/FRWComponent'; + +const useStyles = makeStyles({ + IconCheck: { + display: 'inline', + backgroundColor: '#00E075', + borderRadius: '20px', + width: '24px', + height: '24px', + padding: '3px', + color: '#000', + }, +}); + +export const SignHeader = ({ linkingDone, image, accountTitle, userInfo }) => { + const history = useHistory(); + const classes = useStyles(); + const [count, setCount] = useState(0); + const colorArray = [ + 'rgba(94,94,94,0.3)', + 'rgba(94,94,94,0.4)', + 'rgba(94,94,94,0.5)', + 'rgba(94,94,94,0.6)', + 'rgba(94,94,94,0.7)', + 'rgba(94,94,94,0.8)', + 'rgba(94,94,94,0.9)', + ]; + + const startCount = () => { + let count = 0; + setInterval(() => { + count++; + if (count === 15) { + count = 0; + } + setCount(count); + }, 500); + }; + + const startUsing = () => { + setTimeout(() => { + history.replace('/'); + }); + }; + + useEffect(() => { + startCount(); + }, []); + + return ( +
+ + + + + + + {accountTitle} + + + + {colorArray.map((color, index) => ( + + {count === index ? ( + + ) : ( + + )} + + ))} + + + {userInfo && ( + + )} + + {userInfo?.nickname} + + + + {/* {chrome.i18n.getMessage('Lo')} */} + {linkingDone ? ( + + + + {chrome.i18n.getMessage('Linked_Successful')} + + + ) : ( + + {chrome.i18n.getMessage('Linking_Child_Account')}... + + )} + {linkingDone && ( + + )} + + +
+ ); +}; diff --git a/src/ui/FRWComponent/Approval/index.tsx b/src/ui/FRWComponent/Approval/index.tsx new file mode 100644 index 00000000..92c07369 --- /dev/null +++ b/src/ui/FRWComponent/Approval/index.tsx @@ -0,0 +1 @@ +export * from './SignHeader'; diff --git a/src/ui/FRWComponent/CopyButton.tsx b/src/ui/FRWComponent/CopyButton.tsx new file mode 100644 index 00000000..530aa94b --- /dev/null +++ b/src/ui/FRWComponent/CopyButton.tsx @@ -0,0 +1,29 @@ +import { styled, Button, Tooltip } from '@mui/material'; +import React from 'react'; + +import IconCopy from '../../components/iconfont/IconCopy'; + +const CopyIconWrapper = styled('div')(() => ({ + cursor: 'pointer', +})); + +interface CopyButtonProps { + textToCopy: string; +} + +export const CopyButton = ({ textToCopy }: CopyButtonProps) => { + return ( + + + + + + ); +}; diff --git a/src/ui/FRWComponent/index.tsx b/src/ui/FRWComponent/index.tsx index d735eb6c..fb9dd214 100644 --- a/src/ui/FRWComponent/index.tsx +++ b/src/ui/FRWComponent/index.tsx @@ -26,3 +26,4 @@ export * from './FWDropDownProfile'; export * from './FWMoveDropdown'; export * from './LLContactEth'; export * from './FRWTargetProfile'; +export * from './CopyButton'; diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/DefaultBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/DefaultBlock.tsx index bd34ba9f..66522cf8 100644 --- a/src/ui/views/Approval/components/EthApproval/EthConfirm/DefaultBlock.tsx +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/DefaultBlock.tsx @@ -1,5 +1,4 @@ import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import GppGoodRoundedIcon from '@mui/icons-material/GppGoodRounded'; import { Stack, Box, @@ -9,50 +8,12 @@ import { AccordionSummary, AccordionDetails, } from '@mui/material'; -import React, { useState, useEffect } from 'react'; +import React from 'react'; import Highlight from 'react-highlight'; -import { useHistory } from 'react-router-dom'; -import { getScripts } from 'background/utils'; import placeholder from 'ui/FRWAssets/image/placeholder.png'; -import IconFlow from '../../../../../../components/iconfont/IconFlow'; - -export const DefaultBlock = ({ - title, - host, - auditor, - expanded, - data, - method, - logo, - setExpanded, - dedent, - lilicoEnabled, -}) => { - const history = useHistory(); - - const [contract, setContract] = useState(''); - - const hexToAscii = (hex) => { - let str = ''; - for (let i = 2; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - } - return str; - }; - - useEffect(() => { - if (method === 'eth_sendTransaction') { - getContract(); - } - }, [method]); - - const getContract = async () => { - const script = await getScripts('evm', 'callContract'); - setContract(script); - }; - +export const DefaultBlock = ({ title, host, data, logo }) => { const hexToString = (hex) => { let str = ''; for (let i = 0; i < hex.length; i += 2) { @@ -75,7 +36,7 @@ export const DefaultBlock = ({ }; return ( - + - {method === 'personal_sign' && ( - - - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('SIGN__MESSAGE')} - - - - {data.length > 0 && ( - - - {`${processItem(data[0])}`} - - - )} - - - - )} - {method === 'eth_sendTransaction' && ( - - setExpanded(!expanded)} - disableGutters - sx={{ - color: '#BABABA', - background: '#282828', - borderRadius: '12px !important', - overflow: 'hidden', - }} - > - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('Transaction__Fee')} - - - - - {lilicoEnabled ? ( - - - - - 0 - - - - {chrome.i18n.getMessage('lilico__covers__this__gas__fee__for__you')} - - - ) : ( - - - - - 0.00001 - - - - )} - - - - - )} - {method === 'eth_sendTransaction' && ( - - + + } + aria-controls="panel1a-content" + sx={{ height: '40px !important' }} > - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('SCRIPT')} - - - - {data.length > 0 && ( - - - - {`[\n${data.map((item) => `\t${processItem(item)}`).join(',\n')}\n]`} - - - - )} - + + {chrome.i18n.getMessage('SIGN__MESSAGE')} + + + + {data.length > 0 && ( - {contract && dedent(contract)} + {`${processItem(data[0])}`} - - - - )} + )} + + + ); }; diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx new file mode 100644 index 00000000..1f88a52c --- /dev/null +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx @@ -0,0 +1,320 @@ +import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; +import GppGoodRoundedIcon from '@mui/icons-material/GppGoodRounded'; +import { + Stack, + Box, + Typography, + Divider, + CardMedia, + AccordionSummary, + AccordionDetails, +} from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import Highlight from 'react-highlight'; +import { useHistory } from 'react-router-dom'; + +import { getScripts } from 'background/utils'; +import circlecheck from 'ui/FRWAssets/image/circlecheck.png'; +import placeholder from 'ui/FRWAssets/image/placeholder.png'; +import transactionFeeIcon from 'ui/FRWAssets/svg/transactionFeeIcon.svg'; +import { CopyButton } from 'ui/FRWComponent'; +import { useWallet, formatAddress, isEmoji } from 'ui/utils'; + +import IconFlow from '../../../../../../components/iconfont/IconFlow'; + +export const TransactionBlock = ({ title, data, logo, lilicoEnabled, decodedCall }) => { + return ( + + + + + + Sign Transaction from + + + {title} + + + + + + + + + {chrome.i18n.getMessage('Transaction__Fee')} + + + + {lilicoEnabled ? ( + + + + 0.001 + + + 0.00 + + + + + Covered by Flow Wallet + + + ) : ( + + + + ~ 0.001 + + + + + )} + + + + + {data && data.length > 0 && data[0].to && ( + + + To Address + + + {formatAddress(data[0].to)} + + + )} + {data && data.length > 0 && data[0].value && ( + + + Amount + + {data[0].value} + + )} + + + {decodedCall && ( + + + + Contract + + + + {decodedCall.name || 'Unknown'} + + {decodedCall.is_verified && ( + + )} + + + + {decodedCall.decodedData.name ? ( + // Original rendering for when we have named parameters + <> + + + Function + + + {decodedCall.decodedData.name} + + + {decodedCall.decodedData.params && ( + + {decodedCall.decodedData.params.map((param, index) => ( + + + {param.name || `param${index + 1}`} + + + {formatAddress(param.value)} + + + ))} + + )} + + ) : ( + decodedCall.decodedData.allPossibilities && ( + <> + + + Function + + + {decodedCall.decodedData.allPossibilities[0].function} + + + + {decodedCall.decodedData.allPossibilities[0].params.map((param, index) => ( + + {''} + + {formatAddress(param)} + + + ))} + + + ) + )} + + + )} + + {data && data.length > 0 && data[0].data && ( + + + + Call Data + + + + + + {data[0].data} + + + + )} + + + ); +}; diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/index.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/index.tsx index 5530099d..545cba80 100644 --- a/src/ui/views/Approval/components/EthApproval/EthConfirm/index.tsx +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/index.tsx @@ -1,29 +1,19 @@ import { Stack, Box } from '@mui/material'; import * as fcl from '@onflow/fcl'; -import dedent from 'dedent'; import React, { useCallback, useEffect, useState } from 'react'; -import { useTranslation } from 'react-i18next'; -import { LLConnectLoading, LLLinkingLoading } from '@/ui/FRWComponent'; -import { type UserInfoResponse } from 'background/service/networkModel'; import { LLPrimaryButton, LLSecondaryButton } from 'ui/FRWComponent'; import { useApproval, useWallet } from 'ui/utils'; import { DefaultBlock } from './DefaultBlock'; - +import { TransactionBlock } from './TransactionBlock'; interface ConnectProps { params: any; } const EthConfirm = ({ params }: ConnectProps) => { - const [, resolveApproval, rejectApproval, linkningConfirm] = useApproval(); - const { t } = useTranslation(); + const [, resolveApproval, rejectApproval] = useApproval(); const usewallet = useWallet(); - const [signable, setSignable] = useState(null); - // const [payerSignable, setPayerSignable] = useState(null); - const [opener, setOpener] = useState(undefined); - const [host, setHost] = useState(null); - const [cadenceArguments, setCadenceArguments] = useState([]); const [requestParams, setParams] = useState({ method: '', data: [], @@ -31,58 +21,58 @@ const EthConfirm = ({ params }: ConnectProps) => { name: '', icon: '', }); - const [approval, setApproval] = useState(false); - const [windowId, setWindowId] = useState(undefined); - const [expanded, setExpanded] = useState(false); - const [linkingDone, setLinkingDone] = useState(false); - const [accountLinking, setAccountLinking] = useState(false); - const [accountArgs, setAccountArgs] = useState([]); - const [isLoading, setIsLoading] = useState(false); + const [lilicoEnabled, setLilicoEnabled] = useState(true); - const [auditor, setAuditor] = useState(null); - const [image, setImage] = useState(''); - const [accountTitle, setAccountTitle] = useState(''); - const [userInfo, setUserInfo] = useState(null); const [loading, setLoading] = useState(false); + const [decodedCall, setDecodedCall] = useState(null); - // TODO: replace default logo - const [logo, setLogo] = useState(''); - interface Roles { - authorizer: boolean; - payer: boolean; - proposer: boolean; + interface DecodedParam { + name?: string; + value: string; } - interface Signable { - cadence: string; - message: string; - addr: string; - keyId: number; - roles: Roles; - voucher: Voucher; - f_type: string; - } - interface Voucher { - refBlock: string; - payloadSigs: Signature; + + interface DecodedFunction { + function: string; + params: string[]; } - interface Signature { - address: string; - keyId: number; - sig: string | null; + + interface DecodedData { + name?: string; + params?: DecodedParam[]; + allPossibilities?: DecodedFunction[]; } - const extractData = (obj) => { - console.log('obj ', obj); - try { - const { method = '', data = [], session: { origin = '', name = '', icon = '' } = {} } = obj; + interface DecodedCall { + abi: any[]; + name: string; + is_verified: boolean; + decodedData: DecodedData; + status?: number; + } - const params = { origin, name, icon, method, data }; - setParams(params); - } catch (error) { - console.error('Error extracting data:', error); - setParams({ origin: '', name: '', icon: '', method: '', data: [] }); - } - }; + const extractData = useCallback( + async (obj) => { + if (!obj) return; + + try { + const { method = '', data = [], session: { origin = '', name = '', icon = '' } = {} } = obj; + const params = { origin, name, icon, method, data }; + setParams(params); + + if (!data[0]?.data) return; + + const res = await usewallet.decodeEvmCall(data[0].data, data[0].to); + if (res.status === 200) { + const { abi, status, ...decodedData } = res; + setDecodedCall(decodedData); + } + } catch (error) { + console.error('Error extracting data:', error); + setParams({ origin: '', name: '', icon: '', method: '', data: [] }); + } + }, + [usewallet] + ); const handleCancel = () => { rejectApproval('User rejected the request.'); @@ -103,19 +93,19 @@ const EthConfirm = ({ params }: ConnectProps) => { const checkCoa = async () => { setLoading(true); - const isEnabled = await usewallet.checkCoaLink(); - if (!isEnabled) { + try { + const isEnabled = await usewallet.checkCoaLink(); + if (isEnabled) return; + const result = await usewallet.coaLink(); const res = await fcl.tx(result).onceSealed(); const transactionExecutedEvent = res.events.find((event) => event.type.includes('TransactionExecuted') ); - if (transactionExecutedEvent) { - setLoading(false); - return; - } + if (transactionExecutedEvent) return; + } finally { + setLoading(false); } - setLoading(false); }; useEffect(() => { @@ -123,84 +113,70 @@ const EthConfirm = ({ params }: ConnectProps) => { loadPayer(); extractData(params); } - }, [loadPayer, params]); + }, [loadPayer, extractData, params]); return ( - <> - {isLoading ? ( - - {accountLinking ? ( - - ) : ( - - )} - - ) : ( - + + + {requestParams.method === 'personal_sign' ? ( + ) : ( + - - {/* Push the button stack to the bottom */} - - - {/* Sticky button group at the bottom */} - - - - {!loading ? ( - - ) : ( - - )} - - - - )} - + )} + + + + + + + {!loading ? ( + + ) : ( + + )} + + + ); }; diff --git a/src/ui/views/Approval/components/EthApproval/EthSignType/DefaultBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthSignType/DefaultBlock.tsx deleted file mode 100644 index bd34ba9f..00000000 --- a/src/ui/views/Approval/components/EthApproval/EthSignType/DefaultBlock.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import GppGoodRoundedIcon from '@mui/icons-material/GppGoodRounded'; -import { - Stack, - Box, - Typography, - Divider, - Accordion, - AccordionSummary, - AccordionDetails, -} from '@mui/material'; -import React, { useState, useEffect } from 'react'; -import Highlight from 'react-highlight'; -import { useHistory } from 'react-router-dom'; - -import { getScripts } from 'background/utils'; -import placeholder from 'ui/FRWAssets/image/placeholder.png'; - -import IconFlow from '../../../../../../components/iconfont/IconFlow'; - -export const DefaultBlock = ({ - title, - host, - auditor, - expanded, - data, - method, - logo, - setExpanded, - dedent, - lilicoEnabled, -}) => { - const history = useHistory(); - - const [contract, setContract] = useState(''); - - const hexToAscii = (hex) => { - let str = ''; - for (let i = 2; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - } - return str; - }; - - useEffect(() => { - if (method === 'eth_sendTransaction') { - getContract(); - } - }, [method]); - - const getContract = async () => { - const script = await getScripts('evm', 'callContract'); - setContract(script); - }; - - const hexToString = (hex) => { - let str = ''; - for (let i = 0; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - } - return str; - }; - - const processItem = (item) => { - console.log('item ', item); - if (Array.isArray(item)) { - return `[\n${item.map((value) => `\t${value}`).join(',\n')}\n]`; - } else if (typeof item === 'object' && item !== null) { - return `{\n${Object.entries(item) - .map(([key, value]) => `\t${key}: ${value}`) - .join(',\n')}\n}`; - } else { - return hexToString(item); - } - }; - - return ( - - - - - {title} - - {host} - - - - - {method === 'personal_sign' && ( - - - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('SIGN__MESSAGE')} - - - - {data.length > 0 && ( - - - {`${processItem(data[0])}`} - - - )} - - - - )} - - {method === 'eth_sendTransaction' && ( - - setExpanded(!expanded)} - disableGutters - sx={{ - color: '#BABABA', - background: '#282828', - borderRadius: '12px !important', - overflow: 'hidden', - }} - > - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('Transaction__Fee')} - - - - - {lilicoEnabled ? ( - - - - - 0 - - - - {chrome.i18n.getMessage('lilico__covers__this__gas__fee__for__you')} - - - ) : ( - - - - - 0.00001 - - - - )} - - - - - )} - {method === 'eth_sendTransaction' && ( - - - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('SCRIPT')} - - - - {data.length > 0 && ( - - - - {`[\n${data.map((item) => `\t${processItem(item)}`).join(',\n')}\n]`} - - - - )} - - - - {contract && dedent(contract)} - - - - - - )} - - ); -}; diff --git a/src/ui/views/Approval/components/EthApproval/EthSignV1/DefaultBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthSignV1/DefaultBlock.tsx deleted file mode 100644 index bd34ba9f..00000000 --- a/src/ui/views/Approval/components/EthApproval/EthSignV1/DefaultBlock.tsx +++ /dev/null @@ -1,279 +0,0 @@ -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import GppGoodRoundedIcon from '@mui/icons-material/GppGoodRounded'; -import { - Stack, - Box, - Typography, - Divider, - Accordion, - AccordionSummary, - AccordionDetails, -} from '@mui/material'; -import React, { useState, useEffect } from 'react'; -import Highlight from 'react-highlight'; -import { useHistory } from 'react-router-dom'; - -import { getScripts } from 'background/utils'; -import placeholder from 'ui/FRWAssets/image/placeholder.png'; - -import IconFlow from '../../../../../../components/iconfont/IconFlow'; - -export const DefaultBlock = ({ - title, - host, - auditor, - expanded, - data, - method, - logo, - setExpanded, - dedent, - lilicoEnabled, -}) => { - const history = useHistory(); - - const [contract, setContract] = useState(''); - - const hexToAscii = (hex) => { - let str = ''; - for (let i = 2; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - } - return str; - }; - - useEffect(() => { - if (method === 'eth_sendTransaction') { - getContract(); - } - }, [method]); - - const getContract = async () => { - const script = await getScripts('evm', 'callContract'); - setContract(script); - }; - - const hexToString = (hex) => { - let str = ''; - for (let i = 0; i < hex.length; i += 2) { - str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); - } - return str; - }; - - const processItem = (item) => { - console.log('item ', item); - if (Array.isArray(item)) { - return `[\n${item.map((value) => `\t${value}`).join(',\n')}\n]`; - } else if (typeof item === 'object' && item !== null) { - return `{\n${Object.entries(item) - .map(([key, value]) => `\t${key}: ${value}`) - .join(',\n')}\n}`; - } else { - return hexToString(item); - } - }; - - return ( - - - - - {title} - - {host} - - - - - {method === 'personal_sign' && ( - - - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('SIGN__MESSAGE')} - - - - {data.length > 0 && ( - - - {`${processItem(data[0])}`} - - - )} - - - - )} - - {method === 'eth_sendTransaction' && ( - - setExpanded(!expanded)} - disableGutters - sx={{ - color: '#BABABA', - background: '#282828', - borderRadius: '12px !important', - overflow: 'hidden', - }} - > - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('Transaction__Fee')} - - - - - {lilicoEnabled ? ( - - - - - 0 - - - - {chrome.i18n.getMessage('lilico__covers__this__gas__fee__for__you')} - - - ) : ( - - - - - 0.00001 - - - - )} - - - - - )} - {method === 'eth_sendTransaction' && ( - - - } - aria-controls="panel1a-content" - sx={{ height: '40px !important' }} - > - - {chrome.i18n.getMessage('SCRIPT')} - - - - {data.length > 0 && ( - - - - {`[\n${data.map((item) => `\t${processItem(item)}`).join(',\n')}\n]`} - - - - )} - - - - {contract && dedent(contract)} - - - - - - )} - - ); -}; From 95afbace5fda2aefbc2add1be257b507ffb21204 Mon Sep 17 00:00:00 2001 From: zzggo Date: Mon, 16 Dec 2024 22:58:12 +1100 Subject: [PATCH 2/5] fixed: remove unused import --- .../EthConfirm/TransactionBlock.tsx | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx index 1f88a52c..238bb2d1 100644 --- a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx @@ -1,24 +1,11 @@ -import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; -import GppGoodRoundedIcon from '@mui/icons-material/GppGoodRounded'; -import { - Stack, - Box, - Typography, - Divider, - CardMedia, - AccordionSummary, - AccordionDetails, -} from '@mui/material'; -import React, { useState, useEffect } from 'react'; -import Highlight from 'react-highlight'; -import { useHistory } from 'react-router-dom'; +import { Stack, Box, Typography, Divider, CardMedia } from '@mui/material'; +import React from 'react'; -import { getScripts } from 'background/utils'; import circlecheck from 'ui/FRWAssets/image/circlecheck.png'; import placeholder from 'ui/FRWAssets/image/placeholder.png'; import transactionFeeIcon from 'ui/FRWAssets/svg/transactionFeeIcon.svg'; import { CopyButton } from 'ui/FRWComponent'; -import { useWallet, formatAddress, isEmoji } from 'ui/utils'; +import { formatAddress } from 'ui/utils'; import IconFlow from '../../../../../../components/iconfont/IconFlow'; From fef0ee87bca2a9d434bff4b9c9de9fe7cd132b50 Mon Sep 17 00:00:00 2001 From: zzggo Date: Mon, 16 Dec 2024 23:03:31 +1100 Subject: [PATCH 3/5] fixed: style --- .../EthApproval/EthConfirm/TransactionBlock.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx index 238bb2d1..6f97c043 100644 --- a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx @@ -120,7 +120,7 @@ export const TransactionBlock = ({ title, data, logo, lilicoEnabled, decodedCall - + Function {decodedCall.decodedData.name} + + + Parameters + + + {decodedCall.decodedData.params && ( Date: Tue, 17 Dec 2024 19:11:51 +1100 Subject: [PATCH 4/5] fixed: add tooltip for long address --- .../EthConfirm/TransactionBlock.tsx | 53 +++++++++++++++---- 1 file changed, 43 insertions(+), 10 deletions(-) diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx index 6f97c043..608781d0 100644 --- a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx @@ -1,4 +1,4 @@ -import { Stack, Box, Typography, Divider, CardMedia } from '@mui/material'; +import { Stack, Box, Typography, Divider, CardMedia, Tooltip } from '@mui/material'; import React from 'react'; import circlecheck from 'ui/FRWAssets/image/circlecheck.png'; @@ -127,9 +127,17 @@ export const TransactionBlock = ({ title, data, logo, lilicoEnabled, decodedCall > To Address - - {formatAddress(data[0].to)} - + {data[0].to?.length >= 30 ? ( + + + {formatAddress(data[0].to)} + + + ) : ( + + {formatAddress(data[0].to)} + + )} )} {data && data.length > 0 && data[0].value && ( @@ -215,9 +223,21 @@ export const TransactionBlock = ({ title, data, logo, lilicoEnabled, decodedCall {param.name || `param${index + 1}`} - - {formatAddress(param.value)} - + {param.value?.length >= 30 ? ( + + + {formatAddress(param.value)} + + + ) : ( + + {formatAddress(param.value)} + + )} ))} @@ -255,9 +275,22 @@ export const TransactionBlock = ({ title, data, logo, lilicoEnabled, decodedCall sx={{ padding: '0', width: '100%', alignItems: 'center' }} > {''} - - {formatAddress(param)} - + + {param?.length >= 30 ? ( + + + {formatAddress(param)} + + + ) : ( + + {formatAddress(param)} + + )} ))} From ba4b9fd85d24efe0f4c94307bc8cd2fefbdbb239 Mon Sep 17 00:00:00 2001 From: zzggo Date: Tue, 17 Dec 2024 19:33:52 +1100 Subject: [PATCH 5/5] fixed: managing value with array --- .../EthConfirm/TransactionBlock.tsx | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx index 608781d0..ca91d25a 100644 --- a/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx +++ b/src/ui/views/Approval/components/EthApproval/EthConfirm/TransactionBlock.tsx @@ -216,14 +216,46 @@ export const TransactionBlock = ({ title, data, logo, lilicoEnabled, decodedCall {decodedCall.decodedData.params.map((param, index) => ( - + {param.name || `param${index + 1}`} - {param.value?.length >= 30 ? ( + {Array.isArray(param.value) ? ( + + {param.value.map((item, i) => ( + + {item?.length >= 30 ? ( + + {formatAddress(item)} + + ) : ( + formatAddress(item) + )} + + ))} + + ) : param.value?.length >= 30 ? (