Skip to content

Commit

Permalink
Merge branch 'dev' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
schmanu committed Oct 18, 2024
2 parents b381ba6 + 776c5ce commit 891cdce
Show file tree
Hide file tree
Showing 16 changed files with 260 additions and 183 deletions.
30 changes: 30 additions & 0 deletions cypress/e2e/pages/safeapps.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)'
Expand Down Expand Up @@ -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()
}
Expand Down
16 changes: 0 additions & 16 deletions cypress/e2e/prodhealthcheck/swaps_tokens.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
})
30 changes: 30 additions & 0 deletions cypress/e2e/regression/messages_popup.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
})
1 change: 1 addition & 0 deletions cypress/e2e/regression/swaps.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ describe('Swaps tests', () => {
navigation.clickOnDisconnectBtn()
wallet.connectSigner(signer3)

cy.wait(5000)
create_tx.verifyConfirmTransactionBtnIsVisible()
create_tx.clickOnConfirmTransactionBtn()
create_tx.clickOnNoLaterOption()
Expand Down
1 change: 0 additions & 1 deletion cypress/e2e/regression/swaps_tokens.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 0 additions & 10 deletions cypress/e2e/safe-apps/info_modal.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
})
})
9 changes: 5 additions & 4 deletions cypress/e2e/smoke/messages_offchain.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand Down Expand Up @@ -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()
Expand Down
3 changes: 2 additions & 1 deletion cypress/fixtures/safes/static.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
8 changes: 3 additions & 5 deletions jest.setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
// 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' } }))
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: [],
Expand Down Expand Up @@ -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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<>
<TxDataRow datatestid="tx-safe-hash" title="safeTxHash:">
{generateDataRowValue(safeTxHash, 'hash')}
</TxDataRow>
<TxDataRow datatestid="tx-domain-hash" title="Domain hash:">
{generateDataRowValue(domainHash, 'hash')}
</TxDataRow>
{messageHash && (
<TxDataRow datatestid="tx-message-hash" title="Message hash:">
{generateDataRowValue(messageHash, 'hash')}
</TxDataRow>
)}
</>
)
}
40 changes: 33 additions & 7 deletions src/components/transactions/TxDetails/Summary/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
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'
import type { TransactionDetails } from '@safe-global/safe-gateway-typescript-sdk'
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
Expand All @@ -18,6 +21,7 @@ interface Props {
}

const Summary = ({ txDetails, defaultExpanded = false, hideDecodedData = false }: Props): ReactElement => {
const { safe } = useSafeInfo()
const [expanded, setExpanded] = useState<boolean>(defaultExpanded)

const toggleExpanded = () => {
Expand All @@ -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)
Expand All @@ -41,9 +60,9 @@ const Summary = ({ txDetails, defaultExpanded = false, hideDecodedData = false }
{generateDataRowValue(txHash, 'hash', true)}{' '}
</TxDataRow>
)}
<TxDataRow datatestid="tx-safe-hash" title="safeTxHash:">
{generateDataRowValue(safeTxHash, 'hash')}
</TxDataRow>
{safeTxHash && (
<SafeTxHashDataRow safeTxHash={safeTxHash} safeTxData={safeTxData} safeVersion={safe.version as SafeVersion} />
)}
<TxDataRow datatestid="tx-created-at" title="Created:">
{submittedAt ? dateString(submittedAt) : null}
</TxDataRow>
Expand Down Expand Up @@ -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 && (
<SafeTxHashDataRow safeTxHash={safeTxHash} safeTxData={safeTx.data} safeVersion={safe.version as SafeVersion} />
)}
<TxDataRow datatestid="tx-executed-at" title="safeTxGas:">
<SafeTxGasForm />
</TxDataRow>
Expand Down
Loading

0 comments on commit 891cdce

Please sign in to comment.