From ac798649dc0c60490d21201d286f343d2458c1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=B3vis=20Neto?= Date: Tue, 17 Sep 2024 16:46:50 +0200 Subject: [PATCH] fix: do not propose transaction for contrafactual safes --- .../SignOrExecuteForm/SignOrExecuteForm.tsx | 4 +- .../__tests__/SignOrExecuteForm.test.tsx | 106 ++++++++++++++++++ src/components/tx/SignOrExecuteForm/index.tsx | 9 +- .../ConfirmationView.test.tsx | 1 - .../tx/confirmation-views/index.tsx | 19 ++-- 5 files changed, 124 insertions(+), 15 deletions(-) diff --git a/src/components/tx/SignOrExecuteForm/SignOrExecuteForm.tsx b/src/components/tx/SignOrExecuteForm/SignOrExecuteForm.tsx index 08e3bfdafd..118dd51f9d 100644 --- a/src/components/tx/SignOrExecuteForm/SignOrExecuteForm.tsx +++ b/src/components/tx/SignOrExecuteForm/SignOrExecuteForm.tsx @@ -39,7 +39,7 @@ import ConfirmationView from '../confirmation-views' export type SubmitCallback = (txId: string, isExecuted?: boolean) => void export type SignOrExecuteProps = { - txId: string + txId?: string onSubmit?: SubmitCallback children?: ReactNode isExecutable?: boolean @@ -141,7 +141,7 @@ export const SignOrExecuteForm = ({ )} - {props.txDetails && } + {!isCounterfactualSafe && !props.isRejection && } diff --git a/src/components/tx/SignOrExecuteForm/__tests__/SignOrExecuteForm.test.tsx b/src/components/tx/SignOrExecuteForm/__tests__/SignOrExecuteForm.test.tsx index 58686852f8..833533b364 100644 --- a/src/components/tx/SignOrExecuteForm/__tests__/SignOrExecuteForm.test.tsx +++ b/src/components/tx/SignOrExecuteForm/__tests__/SignOrExecuteForm.test.tsx @@ -6,6 +6,12 @@ import { render } from '@/tests/test-utils' import { fireEvent } from '@testing-library/react' import { encodeBytes32String } from 'ethers' import { Status } from 'zodiac-roles-deployments' +import { + DetailedExecutionInfoType, + SettingsInfoType, + TransactionInfoType, +} from '@safe-global/safe-gateway-typescript-sdk' +import { createMockTransactionDetails } from '@/tests/transactions' let isSafeOwner = true // mock useIsSafeOwner @@ -14,6 +20,96 @@ jest.mock('@/hooks/useIsSafeOwner', () => ({ default: jest.fn(() => isSafeOwner), })) +const txDetails = createMockTransactionDetails({ + txInfo: { + type: TransactionInfoType.SETTINGS_CHANGE, + humanDescription: 'Add new owner 0xd8dA...6045 with threshold 1', + dataDecoded: { + method: 'addOwnerWithThreshold', + parameters: [ + { + name: 'owner', + type: 'address', + value: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + }, + { + name: '_threshold', + type: 'uint256', + value: '1', + }, + ], + }, + settingsInfo: { + type: SettingsInfoType.ADD_OWNER, + owner: { + value: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + name: 'Nevinha', + logoUri: 'http://something.com', + }, + threshold: 1, + }, + }, + txData: { + hexData: + '0x0d582f13000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa960450000000000000000000000000000000000000000000000000000000000000001', + dataDecoded: { + method: 'addOwnerWithThreshold', + parameters: [ + { + name: 'owner', + type: 'address', + value: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + }, + { + name: '_threshold', + type: 'uint256', + value: '1', + }, + ], + }, + to: { + value: '0xE20CcFf2c38Ef3b64109361D7b7691ff2c7D5f67', + name: '', + }, + value: '0', + operation: 0, + trustedDelegateCallTarget: false, + addressInfoIndex: { + '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045': { + value: '0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045', + name: 'MetaMultiSigWallet', + }, + }, + }, + detailedExecutionInfo: { + type: DetailedExecutionInfoType.MULTISIG, + submittedAt: 1726064794013, + nonce: 4, + safeTxGas: '0', + baseGas: '0', + gasPrice: '0', + gasToken: '0x0000000000000000000000000000000000000000', + refundReceiver: { + value: '0x0000000000000000000000000000000000000000', + name: 'MetaMultiSigWallet', + }, + safeTxHash: '0x96a96c11b8d013ff5d7a6ce960b22e961046cfa42eff422ac71c1daf6adef2e0', + signers: [ + { + value: '0xDa5e9FA404881Ff36DDa97b41Da402dF6430EE6b', + name: '', + }, + ], + confirmationsRequired: 1, + confirmations: [], + rejectors: [], + trusted: false, + proposer: { + value: '0xDa5e9FA404881Ff36DDa97b41Da402dF6430EE6b', + name: '', + }, + }, +}) describe('SignOrExecute', () => { beforeEach(() => { isSafeOwner = true @@ -22,6 +118,7 @@ describe('SignOrExecute', () => { it('should display a safeTxError', () => { const { getByText } = render( { const { getByText } = render( { const { getByText } = render( { const { queryByTestId } = render( { const { queryByTestId } = render( { const { queryByTestId } = render( { const { queryByTestId } = render( { const { queryByText } = render( { const { getByTestId, getByText } = render( { it('should not display safeTxError message for valid transactions', () => { const { queryByText } = render( & { onSubmit?: SubmitCallback @@ -24,17 +25,17 @@ type SignOrExecuteExtendedProps = Omit & { const SignOrExecute = (props: SignOrExecuteExtendedProps) => { const { safeTx } = useContext(SafeTxContext) - - const [txDetails, error, isLoading] = useProposeTx(safeTx, props.txId, props.origin) + const { safe } = useSafeInfo() + const [txDetails, error, isLoading] = useProposeTx(safe.deployed ? safeTx : undefined, props.txId, props.origin) return error ? ( - ) : isLoading || !safeTx || !txDetails ? ( + ) : isLoading || !safeTx || (!txDetails && safe.deployed) ? ( ) : ( - + ) } diff --git a/src/components/tx/confirmation-views/ConfirmationView.test.tsx b/src/components/tx/confirmation-views/ConfirmationView.test.tsx index cb93205185..3dc7aab028 100644 --- a/src/components/tx/confirmation-views/ConfirmationView.test.tsx +++ b/src/components/tx/confirmation-views/ConfirmationView.test.tsx @@ -109,7 +109,6 @@ const safeTxWithNativeData = { data: '0x', }, } -console.log(safeTxWithNativeData) describe('ConfirmationView', () => { it('should display a confirmation screen for a SETTINGS_CHANGE transaction', () => { const { container, getByTestId } = render( diff --git a/src/components/tx/confirmation-views/index.tsx b/src/components/tx/confirmation-views/index.tsx index 7513da77b2..0316c25818 100644 --- a/src/components/tx/confirmation-views/index.tsx +++ b/src/components/tx/confirmation-views/index.tsx @@ -10,7 +10,7 @@ import type { NarrowConfirmationViewProps } from './types' import SettingsChange from './SettingsChange' type ConfirmationViewProps = { - txDetails: TransactionDetails + txDetails?: TransactionDetails safeTx?: SafeTransaction txId?: string isBatch?: boolean @@ -26,22 +26,25 @@ const getConfirmationViewComponent = (txType: TransactionInfoType, props: Narrow } const ConfirmationView = (props: ConfirmationViewProps) => { - const { txInfo, txId } = props.txDetails + const { txId } = props.txDetails || {} const [decodedData] = useDecodeTx(props.safeTx) const ConfirmationViewComponent = useMemo( () => - getConfirmationViewComponent(txInfo.type, { - txDetails: props.txDetails, - txInfo, - }), - [props.txDetails, txInfo], + props.txDetails + ? getConfirmationViewComponent(props.txDetails.txInfo.type, { + txDetails: props.txDetails, + txInfo: props.txDetails.txInfo, + }) + : undefined, + [props.txDetails], ) const showTxDetails = txId && !props.isCreation && props.txDetails && !isCustomTxInfo(props.txDetails.txInfo) return ( <> - {ConfirmationViewComponent || (showTxDetails && )} + {ConfirmationViewComponent || + (showTxDetails && props.txDetails && )} {decodedData && }