diff --git a/cypress/e2e/pages/safeapps.pages.js b/cypress/e2e/pages/safeapps.pages.js index b4fc900f93..ec67d8cc5f 100644 --- a/cypress/e2e/pages/safeapps.pages.js +++ b/cypress/e2e/pages/safeapps.pages.js @@ -10,6 +10,7 @@ export const deleteBatchBtn = 'button[title="Delete Batch"]' const appModal = '[data-testid="app-info-modal"]' export const safeAppsList = '[data-testid="apps-list"]' const openSafeAppBtn = '[data-testid="open-safe-app-btn"]' +const appMessageInput = 'input[placeholder="Message"]' const addBtnStr = /add/i const noAppsStr = /no Safe Apps found/i @@ -90,6 +91,10 @@ export const warningStr = 'Warning' export const transferStr = 'Transfer' export const successStr = 'Success' export const failedStr = 'Failed' +const blindSigningStr = 'This request involves blind signing' +const enableBlindSigningStr = 'Enable blind signing' +const blindSigningStr2 = 'blind signing' +const signBtnStr = 'Sign' export const dummyTxStr = 'Trigger dummy tx (safe.txs.send)' export const signOnchainMsgStr = 'Sign message (on-chain)' @@ -135,6 +140,31 @@ export function triggetOffChainTx() { cy.contains(dummyTxStr).click() } +export function verifyBlindSigningEnabled(option) { + if (option) { + cy.contains(blindSigningStr).should('be.visible') + } else { + cy.contains(blindSigningStr).should('not.exist') + } +} + +export function clickOnBlindSigningOption() { + cy.contains(blindSigningStr2).click() + cy.contains(enableBlindSigningStr).click() +} + +export function triggetSignMsg() { + cy.contains(signOnchainMsgStr).click() +} + +export function enterMessage(msg) { + cy.get(appMessageInput).type(msg) +} + +export function verifySignBtnDisabled() { + cy.get('button').contains(signBtnStr).should('be.disabled') +} + export function triggetOnChainTx() { cy.contains(signOnchainMsgStr).click() } diff --git a/cypress/e2e/prodhealthcheck/swaps_tokens.cy.js b/cypress/e2e/prodhealthcheck/swaps_tokens.cy.js index 4c3f513470..747b2aeea2 100644 --- a/cypress/e2e/prodhealthcheck/swaps_tokens.cy.js +++ b/cypress/e2e/prodhealthcheck/swaps_tokens.cy.js @@ -36,20 +36,4 @@ describe('[PROD] Swaps token tests', () => { }) }, ) - - it('Verify swap button are displayed in assets table and dashboard', () => { - assets.selectTokenList(assets.tokenListOptions.allTokens) - cy.wait(3000) - main.verifyElementsCount(swaps.assetsSwapBtn, 4) - cy.window().then((window) => { - window.localStorage.setItem( - constants.localStorageKeys.SAFE_v2__settings, - JSON.stringify(ls.safeSettings.slimitSettings), - ) - }) - cy.visit(constants.homeUrl + staticSafes.SEP_STATIC_SAFE_1) - cy.wait(3000) - main.verifyElementsCount(swaps.assetsSwapBtn, 4) - main.verifyElementsCount(swaps.dashboardSwapBtn, 1) - }) }) diff --git a/cypress/e2e/regression/messages_popup.cy.js b/cypress/e2e/regression/messages_popup.cy.js index a679e6cc94..cfa1aa1ab5 100644 --- a/cypress/e2e/regression/messages_popup.cy.js +++ b/cypress/e2e/regression/messages_popup.cy.js @@ -62,4 +62,34 @@ describe('Messages popup window tests', () => { msg_confirmation_modal.verifySafeAppInPopupWindow(safeApp) msg_confirmation_modal.verifyMessagePresent(onchainMessage) }) + + it('Verify warning message is displayed when 0x0000000 is used as a message', () => { + const msgHash = '0x0000000' + main.addToLocalStorage( + constants.localStorageKeys.SAFE_v2__customSafeApps_11155111, + ls.customApps(constants.safeTestAppurl).safeTestApp, + ) + main.addToLocalStorage( + constants.localStorageKeys.SAFE_v2__SafeApps__browserPermissions, + ls.appPermissions(constants.safeTestAppurl).grantedPermissions, + ) + cy.reload() + apps.clickOnApp(safeApp) + apps.clickOnOpenSafeAppBtn() + main.getIframeBody(iframeSelector).within(() => { + apps.enterMessage(msgHash) + apps.triggetSignMsg() + }) + apps.verifyBlindSigningEnabled(true) + apps.clickOnBlindSigningOption() + cy.visit(constants.appsCustomUrl + staticSafes.SEP_STATIC_SAFE_10) + apps.clickOnApp(safeApp) + apps.clickOnOpenSafeAppBtn() + main.getIframeBody(iframeSelector).within(() => { + apps.enterMessage(msgHash) + apps.triggetSignMsg() + }) + apps.verifyBlindSigningEnabled(false) + apps.verifySignBtnDisabled() + }) }) diff --git a/cypress/e2e/regression/swaps.cy.js b/cypress/e2e/regression/swaps.cy.js index a195cf9dfe..af2535d2f2 100644 --- a/cypress/e2e/regression/swaps.cy.js +++ b/cypress/e2e/regression/swaps.cy.js @@ -201,6 +201,7 @@ describe('Swaps tests', () => { navigation.clickOnDisconnectBtn() wallet.connectSigner(signer3) + cy.wait(5000) create_tx.verifyConfirmTransactionBtnIsVisible() create_tx.clickOnConfirmTransactionBtn() create_tx.clickOnNoLaterOption() diff --git a/cypress/e2e/regression/swaps_tokens.cy.js b/cypress/e2e/regression/swaps_tokens.cy.js index 6c01abd675..d72036d555 100644 --- a/cypress/e2e/regression/swaps_tokens.cy.js +++ b/cypress/e2e/regression/swaps_tokens.cy.js @@ -38,7 +38,6 @@ describe('[SMOKE] Swaps token tests', () => { }, ) - // Added to prod it('Verify swap button are displayed in assets table and dashboard', () => { assets.selectTokenList(assets.tokenListOptions.allTokens) main.verifyElementsCount(swaps.assetsSwapBtn, 4) diff --git a/cypress/e2e/safe-apps/info_modal.cy.js b/cypress/e2e/safe-apps/info_modal.cy.js index 30b912de9a..fbd93cb3cd 100644 --- a/cypress/e2e/safe-apps/info_modal.cy.js +++ b/cypress/e2e/safe-apps/info_modal.cy.js @@ -24,14 +24,4 @@ describe('Info modal tests', () => { safeapps.clickOnOpenSafeAppBtn() safeapps.verifyDisclaimerIsDisplayed() }) - - it('Verify info modal consent is stored when accepted', { defaultCommandTimeout: 20000 }, () => { - // Required to show disclaimer - cy.clearLocalStorage() - main.acceptCookies() - safeapps.clickOnApp(safeapps.transactionBuilderStr) - safeapps.clickOnOpenSafeAppBtn() - safeapps.verifyDisclaimerIsDisplayed() - safeapps.verifyInfoModalAcceptance() - }) }) diff --git a/cypress/e2e/smoke/messages_offchain.cy.js b/cypress/e2e/smoke/messages_offchain.cy.js index a9349a2af6..7b997e0771 100644 --- a/cypress/e2e/smoke/messages_offchain.cy.js +++ b/cypress/e2e/smoke/messages_offchain.cy.js @@ -16,6 +16,7 @@ const typeMessagesOffchain = msg_data.type.offChain const walletCredentials = JSON.parse(Cypress.env('CYPRESS_WALLET_CREDENTIALS')) const signer = walletCredentials.OWNER_4_PRIVATE_KEY +const signer2 = walletCredentials.OWNER_1_PRIVATE_KEY describe('[SMOKE] Offchain Messages tests', () => { before(async () => { @@ -78,10 +79,10 @@ describe('[SMOKE] Offchain Messages tests', () => { main.verifyTextVisibility(values) }) - // TODO: Clarify changes - it.skip('[SMOKE] Verify confirmation window is displayed for unsigned message', () => { - wallet.connectSigner(signer) - messages.clickOnMessageSignBtn(2) + it('[SMOKE] Verify confirmation window is displayed for unsigned message', () => { + cy.visit(constants.transactionsMessagesUrl + staticSafes.SEP_STATIC_SAFE_26) + wallet.connectSigner(signer2) + messages.clickOnMessageSignBtn(0) msg_confirmation_modal.verifyConfirmationWindowTitle(modal.modalTitiles.confirmMsg) msg_confirmation_modal.verifyMessagePresent(offchainMessage) msg_confirmation_modal.clickOnMessageDetails() diff --git a/cypress/fixtures/safes/static.json b/cypress/fixtures/safes/static.json index 6e02c75418..eb1acacfa7 100644 --- a/cypress/fixtures/safes/static.json +++ b/cypress/fixtures/safes/static.json @@ -25,5 +25,6 @@ "ZKSYNC_STATIC_SAFE_22": "zksync:0x49136c0270c5682FFbb38Cb29Ecf0563b2E1F9f6", "SEP_STATIC_SAFE_23": "sep:0x589d862CE2d519d5A862066bB923da0564c3D2EA", "SEP_STATIC_SAFE_24": "sep:0x49DC5764961DA4864DC5469f16BC68a0F765f2F2", - "SEP_STATIC_SAFE_25": "sep:0x4ECFAa2E8cb4697bCD27bdC9Ce3E16f03F73124F" + "SEP_STATIC_SAFE_25": "sep:0x4ECFAa2E8cb4697bCD27bdC9Ce3E16f03F73124F", + "SEP_STATIC_SAFE_26": "sep:0x755428b02A458eD17fa93c86F6C3a2046F2c4C3C" } diff --git a/jest.setup.js b/jest.setup.js index 08425f8b65..ec8ccaa216 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -5,7 +5,7 @@ // Learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom/extend-expect' import { TextEncoder, TextDecoder } from 'util' -import { Headers, Request, Response } from 'node-fetch' +import { Request } from 'node-fetch' jest.mock('@web3-onboard/coinbase', () => jest.fn()) jest.mock('@web3-onboard/injected-wallets', () => ({ ProviderLabel: { MetaMask: 'MetaMask' } })) @@ -13,7 +13,7 @@ jest.mock('@web3-onboard/keystone/dist/index', () => jest.fn()) jest.mock('@web3-onboard/ledger/dist/index', () => jest.fn()) jest.mock('@web3-onboard/trezor', () => jest.fn()) jest.mock('@web3-onboard/walletconnect', () => jest.fn()) -jest.mock('safe-client-gateway-sdk') +jest.mock('@safe-global/safe-client-gateway-sdk') const mockOnboardState = { chains: [], @@ -71,7 +71,5 @@ Object.defineProperty(Uint8Array, Symbol.hasInstance, { }, }) -// These are required for safe-client-gateway-sdk +// These are required for @safe-global/safe-client-gateway-sdk globalThis.Request = Request -globalThis.Response = Response -globalThis.Headers = Headers diff --git a/package.json b/package.json index d9af3467eb..68b051a248 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@safe-global/protocol-kit": "^4.1.1", "@safe-global/safe-apps-sdk": "^9.1.0", "@safe-global/safe-deployments": "^1.37.10", + "@safe-global/safe-client-gateway-sdk": "1.58.0-next-25bba61", "@safe-global/safe-gateway-typescript-sdk": "3.22.3-beta.15", "@safe-global/safe-modules-deployments": "^2.2.1", "@sentry/react": "^7.91.0", @@ -91,7 +92,6 @@ "react-hook-form": "7.41.1", "react-papaparse": "^4.0.2", "react-redux": "^9.1.2", - "safe-client-gateway-sdk": "git+https://github.com/safe-global/safe-client-gateway-sdk.git#v1.53.0-next-7344903", "semver": "^7.6.3", "zodiac-roles-deployments": "^2.2.5" }, diff --git a/src/components/transactions/TxDetails/Summary/SafeTxHashDataRow/index.tsx b/src/components/transactions/TxDetails/Summary/SafeTxHashDataRow/index.tsx new file mode 100644 index 0000000000..c6b1d2b26a --- /dev/null +++ b/src/components/transactions/TxDetails/Summary/SafeTxHashDataRow/index.tsx @@ -0,0 +1,42 @@ +import { TypedDataEncoder } from 'ethers' +import { TxDataRow, generateDataRowValue } from '../TxDataRow' +import { type SafeTransactionData, type SafeVersion } from '@safe-global/safe-core-sdk-types' +import { getEip712TxTypes } from '@safe-global/protocol-kit/dist/src/utils' +import useSafeAddress from '@/hooks/useSafeAddress' +import useChainId from '@/hooks/useChainId' + +export const SafeTxHashDataRow = ({ + safeTxHash, + safeTxData, + safeVersion, +}: { + safeTxHash: string + safeTxData?: SafeTransactionData + safeVersion: SafeVersion +}) => { + const chainId = useChainId() + const safeAddress = useSafeAddress() + const domainHash = TypedDataEncoder.hashDomain({ + chainId, + verifyingContract: safeAddress, + }) + const messageHash = safeTxData + ? TypedDataEncoder.hashStruct('SafeTx', { SafeTx: getEip712TxTypes(safeVersion).SafeTx }, safeTxData) + : undefined + + return ( + <> + + {generateDataRowValue(safeTxHash, 'hash')} + + + {generateDataRowValue(domainHash, 'hash')} + + {messageHash && ( + + {generateDataRowValue(messageHash, 'hash')} + + )} + + ) +} diff --git a/src/components/transactions/TxDetails/Summary/index.tsx b/src/components/transactions/TxDetails/Summary/index.tsx index 090a57e4e1..7f1532e2b0 100644 --- a/src/components/transactions/TxDetails/Summary/index.tsx +++ b/src/components/transactions/TxDetails/Summary/index.tsx @@ -1,5 +1,5 @@ import type { ReactElement } from 'react' -import React, { useState } from 'react' +import React, { useMemo, useState } from 'react' import { Link, Box } from '@mui/material' import { generateDataRowValue, TxDataRow } from '@/components/transactions/TxDetails/Summary/TxDataRow' import { isCustomTxInfo, isMultisigDetailedExecutionInfo } from '@/utils/transaction-guards' @@ -7,9 +7,12 @@ import type { TransactionDetails } from '@safe-global/safe-gateway-typescript-sd import { Operation } from '@safe-global/safe-gateway-typescript-sdk' import { dateString } from '@/utils/formatters' import css from './styles.module.css' -import type { SafeTransaction } from '@safe-global/safe-core-sdk-types' +import type { SafeTransaction, SafeTransactionData, SafeVersion } from '@safe-global/safe-core-sdk-types' import SafeTxGasForm from '../SafeTxGasForm' import DecodedData from '../TxData/DecodedData' +import { calculateSafeTransactionHash } from '@safe-global/protocol-kit/dist/src/utils' +import useSafeInfo from '@/hooks/useSafeInfo' +import { SafeTxHashDataRow } from './SafeTxHashDataRow' interface Props { txDetails: TransactionDetails @@ -18,6 +21,7 @@ interface Props { } const Summary = ({ txDetails, defaultExpanded = false, hideDecodedData = false }: Props): ReactElement => { + const { safe } = useSafeInfo() const [expanded, setExpanded] = useState(defaultExpanded) const toggleExpanded = () => { @@ -26,10 +30,25 @@ const Summary = ({ txDetails, defaultExpanded = false, hideDecodedData = false } const { txHash, detailedExecutionInfo, executedAt, txData } = txDetails - let submittedAt, confirmations, safeTxHash, baseGas, gasPrice, gasToken, refundReceiver, safeTxGas + let safeTxData: SafeTransactionData | undefined = undefined + let submittedAt, confirmations, safeTxHash, baseGas, gasPrice, gasToken, refundReceiver, safeTxGas, nonce if (isMultisigDetailedExecutionInfo(detailedExecutionInfo)) { - ;({ submittedAt, confirmations, safeTxHash, baseGas, gasPrice, gasToken, safeTxGas } = detailedExecutionInfo) + ;({ submittedAt, confirmations, safeTxHash, baseGas, gasPrice, gasToken, safeTxGas, nonce } = detailedExecutionInfo) refundReceiver = detailedExecutionInfo.refundReceiver?.value + if (txData) { + safeTxData = { + to: txData.to.value, + data: txData.hexData ?? '0x', + value: txData.value ?? '0', + operation: txData.operation as number, + baseGas, + gasPrice, + gasToken, + nonce, + refundReceiver, + safeTxGas, + } + } } const isCustom = isCustomTxInfo(txDetails.txInfo) @@ -41,9 +60,9 @@ const Summary = ({ txDetails, defaultExpanded = false, hideDecodedData = false } {generateDataRowValue(txHash, 'hash', true)}{' '} )} - - {generateDataRowValue(safeTxHash, 'hash')} - + {safeTxHash && ( + + )} {submittedAt ? dateString(submittedAt) : null} @@ -115,8 +134,15 @@ export default Summary export const PartialSummary = ({ safeTx }: { safeTx: SafeTransaction }) => { const txData = safeTx.data + const { safeAddress, safe } = useSafeInfo() + const safeTxHash = useMemo(() => { + return safe.version && calculateSafeTransactionHash(safeAddress, safeTx.data, safe.version, BigInt(safe.chainId)) + }, [safe.chainId, safe.version, safeAddress, safeTx.data]) return ( <> + {safeTxHash && ( + + )} diff --git a/src/features/multichain/hooks/__tests__/useSafeCreationData.test.ts b/src/features/multichain/hooks/__tests__/useSafeCreationData.test.ts index 1ea05115a2..3c6aba20e3 100644 --- a/src/features/multichain/hooks/__tests__/useSafeCreationData.test.ts +++ b/src/features/multichain/hooks/__tests__/useSafeCreationData.test.ts @@ -5,7 +5,7 @@ import { PendingSafeStatus, type UndeployedSafe } from '@/store/slices' import { PayMethod } from '@/features/counterfactual/PayNowPayLater' import { chainBuilder } from '@/tests/builders/chains' import * as sdk from '@/services/tx/tx-sender/sdk' -import * as cgwSdk from 'safe-client-gateway-sdk' +import * as cgwSdk from '@safe-global/safe-client-gateway-sdk' import * as web3 from '@/hooks/wallets/web3' import { encodeMultiSendData, type SafeProvider } from '@safe-global/protocol-kit' import { Safe__factory, Safe_proxy_factory__factory } from '@/types/contracts' @@ -210,10 +210,7 @@ describe('useSafeCreationData', () => { }) it('should throw an error if creation data cannot be found', async () => { - jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - response: new Response(), - data: undefined, - } as any) + jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue(undefined as any) const safeAddress = faker.finance.ethereumAddress() const chainInfos = [chainBuilder().with({ chainId: '1', l2: false }).build()] @@ -228,15 +225,13 @@ describe('useSafeCreationData', () => { it('should throw an error if Safe creation data is incomplete', async () => { jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: null, - setupData: null, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: null, + setupData: null, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) const safeAddress = faker.finance.ethereumAddress() @@ -252,15 +247,13 @@ describe('useSafeCreationData', () => { it('should throw an error if Safe setupData is empty', async () => { jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: faker.finance.ethereumAddress(), - setupData: '0x', - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: faker.finance.ethereumAddress(), + setupData: '0x', + saltNonce: faker.string.hexadecimal({ length: 64 }), }) const safeAddress = faker.finance.ethereumAddress() @@ -287,15 +280,13 @@ describe('useSafeCreationData', () => { ]) jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: getSafeSingletonDeployment({ version: '1.1.1' })?.defaultAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: getSafeSingletonDeployment({ version: '1.1.1' })?.defaultAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) const safeAddress = faker.finance.ethereumAddress() @@ -326,15 +317,13 @@ describe('useSafeCreationData', () => { ]) jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: faker.finance.ethereumAddress(), - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: faker.finance.ethereumAddress(), + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) const safeAddress = faker.finance.ethereumAddress() @@ -365,15 +354,13 @@ describe('useSafeCreationData', () => { ]) jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) const safeAddress = faker.finance.ethereumAddress() @@ -400,15 +387,13 @@ describe('useSafeCreationData', () => { ]) jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) const safeAddress = faker.finance.ethereumAddress() @@ -435,15 +420,13 @@ describe('useSafeCreationData', () => { ]) jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: faker.finance.ethereumAddress(), - transactionHash: faker.string.hexadecimal({ length: 64 }), - masterCopy: getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: faker.finance.ethereumAddress(), + transactionHash: faker.string.hexadecimal({ length: 64 }), + masterCopy: getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue(undefined) @@ -476,15 +459,13 @@ describe('useSafeCreationData', () => { const mockMasterCopyAddress = getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: mockFactoryAddress, - transactionHash: mockTxHash, - masterCopy: mockMasterCopyAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: mockFactoryAddress, + transactionHash: mockTxHash, + masterCopy: mockMasterCopyAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue({ @@ -518,15 +499,13 @@ describe('useSafeCreationData', () => { const mockFactoryAddress = faker.finance.ethereumAddress() const mockMasterCopyAddress = getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress! jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: mockFactoryAddress, - transactionHash: mockTxHash, - masterCopy: mockMasterCopyAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: mockFactoryAddress, + transactionHash: mockTxHash, + masterCopy: mockMasterCopyAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue({ @@ -583,15 +562,13 @@ describe('useSafeCreationData', () => { const mockFactoryAddress = faker.finance.ethereumAddress() const mockMasterCopyAddress = getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress! jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: mockFactoryAddress, - transactionHash: mockTxHash, - masterCopy: mockMasterCopyAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: mockFactoryAddress, + transactionHash: mockTxHash, + masterCopy: mockMasterCopyAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue({ @@ -637,15 +614,13 @@ describe('useSafeCreationData', () => { const mockFactoryAddress = faker.finance.ethereumAddress() const mockMasterCopyAddress = getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress! jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: mockFactoryAddress, - transactionHash: mockTxHash, - masterCopy: mockMasterCopyAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: mockFactoryAddress, + transactionHash: mockTxHash, + masterCopy: mockMasterCopyAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue({ @@ -701,15 +676,13 @@ describe('useSafeCreationData', () => { const mockFactoryAddress = fakerChecksummedAddress() const mockMasterCopyAddress = getSafeSingletonDeployment({ version: '1.3.0' })?.defaultAddress! jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: fakerChecksummedAddress(), - factoryAddress: mockFactoryAddress, - transactionHash: mockTxHash, - masterCopy: mockMasterCopyAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: fakerChecksummedAddress(), + factoryAddress: mockFactoryAddress, + transactionHash: mockTxHash, + masterCopy: mockMasterCopyAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue({ @@ -777,15 +750,13 @@ describe('useSafeCreationData', () => { const mockMasterCopyAddress = getSafeSingletonDeployment({ version: '1.4.1' })?.defaultAddress! jest.spyOn(cgwSdk, 'getCreationTransaction').mockResolvedValue({ - data: { - created: new Date(Date.now()).toISOString(), - creator: faker.finance.ethereumAddress(), - factoryAddress: mockFactoryAddress, - transactionHash: mockTxHash, - masterCopy: mockMasterCopyAddress, - setupData, - }, - response: new Response(), + created: new Date(Date.now()).toISOString(), + creator: faker.finance.ethereumAddress(), + factoryAddress: mockFactoryAddress, + transactionHash: mockTxHash, + masterCopy: mockMasterCopyAddress, + setupData, + saltNonce: faker.string.hexadecimal({ length: 64 }), }) jest.spyOn(web3, 'createWeb3ReadOnly').mockReturnValue({ diff --git a/src/features/multichain/hooks/useSafeCreationData.ts b/src/features/multichain/hooks/useSafeCreationData.ts index b8e35abcb9..d4c60013f6 100644 --- a/src/features/multichain/hooks/useSafeCreationData.ts +++ b/src/features/multichain/hooks/useSafeCreationData.ts @@ -3,7 +3,7 @@ import { createWeb3ReadOnly } from '@/hooks/wallets/web3' import { type UndeployedSafe, selectRpc, type ReplayedSafeProps, selectUndeployedSafes } from '@/store/slices' import { Safe__factory, Safe_proxy_factory__factory } from '@/types/contracts' import { sameAddress } from '@/utils/addresses' -import { getCreationTransaction } from 'safe-client-gateway-sdk' +import { getCreationTransaction } from '@safe-global/safe-client-gateway-sdk' import type { ChainInfo } from '@safe-global/safe-gateway-typescript-sdk' import { useAppSelector } from '@/store' import { determineMasterCopyVersion, isPredictedSafeProps } from '@/features/counterfactual/utils' @@ -91,10 +91,12 @@ const getCreationDataForChain = async ( return undeployedCreationData } - const { data: creation } = await getCreationTransaction({ - path: { - chainId: chain.chainId, - safeAddress, + const creation = await getCreationTransaction({ + params: { + path: { + chainId: chain.chainId, + safeAddress, + }, }, }) @@ -172,6 +174,7 @@ export const useSafeCreationData = (safeAddress: string, chains: ChainInfo[]): A try { const creationData = await getCreationDataForChain(chain, undeployedSafe, safeAddress, customRpc) + console.log({ creationData }) return creationData } catch (err) { lastError = asError(err) diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 2fa0067620..70ff8bcfd2 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -8,7 +8,7 @@ import CssBaseline from '@mui/material/CssBaseline' import type { Theme } from '@mui/material/styles' import { ThemeProvider } from '@mui/material/styles' import { setBaseUrl as setGatewayBaseUrl } from '@safe-global/safe-gateway-typescript-sdk' -import { setBaseUrl as setNewGatewayBaseUrl } from 'safe-client-gateway-sdk' +import { setBaseUrl as setNewGatewayBaseUrl } from '@safe-global/safe-client-gateway-sdk' import { CacheProvider, type EmotionCache } from '@emotion/react' import SafeThemeProvider from '@/components/theme/SafeThemeProvider' import '@/styles/globals.css' diff --git a/yarn.lock b/yarn.lock index c149a12884..1ede7813c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4233,6 +4233,13 @@ "@safe-global/safe-gateway-typescript-sdk" "^3.5.3" viem "^2.1.1" +"@safe-global/safe-client-gateway-sdk@1.58.0-next-25bba61": + version "1.58.0-next-25bba61" + resolved "https://registry.yarnpkg.com/@safe-global/safe-client-gateway-sdk/-/safe-client-gateway-sdk-1.58.0-next-25bba61.tgz#1e5906d0a492ee72a77fbe1d782fee0376576968" + integrity sha512-sm19eckk6yjGOSgOOk4wE8pD7Ygdkr81ANyJUnOH1hr6RDxLgIkhvvatEI5aPB4vFD/iAKiJ2zMq19Pk1o41EA== + dependencies: + openapi-fetch "0.10.5" + "@safe-global/safe-core-sdk-types@^5.0.1": version "5.0.2" resolved "https://registry.yarnpkg.com/@safe-global/safe-core-sdk-types/-/safe-core-sdk-types-5.0.2.tgz#9552f5793581333c81676986b3eb19697e1c6627" @@ -14906,10 +14913,10 @@ open@^8.0.4: is-docker "^2.1.1" is-wsl "^2.2.0" -openapi-fetch@^0.10.5: - version "0.10.6" - resolved "https://registry.yarnpkg.com/openapi-fetch/-/openapi-fetch-0.10.6.tgz#255017e3e609c5e7be16bc1ed7a973977c085cdc" - integrity sha512-6xXfvIEL/POtLGOaFPsp3O+pDe+J3DZYxbD9BrsQHXOTeNK8z/gsWHT6adUy1KcpQOhmkerMzlQrJM6DbN55dQ== +openapi-fetch@0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/openapi-fetch/-/openapi-fetch-0.10.5.tgz#ea714c7738cd7632df23521d20f32d906a3b5232" + integrity sha512-lOHWzQDYrMakHSqAOqJJGawitSGQzLM8w8zXTrpffe7u9aWqzFvhdJJNqfcW1EzaXtNNdPdMzXaFLdrjgn68ow== dependencies: openapi-typescript-helpers "^0.0.11" @@ -16615,12 +16622,6 @@ safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -"safe-client-gateway-sdk@git+https://github.com/safe-global/safe-client-gateway-sdk.git#v1.53.0-next-7344903": - version "1.53.0-next-7344903" - resolved "git+https://github.com/safe-global/safe-client-gateway-sdk.git#b0b91319b8753b41edd117bb6425729634250e15" - dependencies: - openapi-fetch "^0.10.5" - safe-regex-test@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.3.tgz#a5b4c0f06e0ab50ea2c395c14d8371232924c377"