diff --git a/cypress/e2e/pages/create_tx.pages.js b/cypress/e2e/pages/create_tx.pages.js index 07eb587c89..a6afd9c3da 100644 --- a/cypress/e2e/pages/create_tx.pages.js +++ b/cypress/e2e/pages/create_tx.pages.js @@ -14,6 +14,7 @@ const gasLimitInput = '[name="gasLimit"]' const rotateLeftIcon = '[data-testid="RotateLeftIcon"]' export const transactionItem = '[data-testid="transaction-item"]' export const connectedWalletExecMethod = '[data-testid="connected-wallet-execution-method"]' +export const payNowExecMethod = '[data-testid="pay-now-execution-method"]' const addToBatchBtn = '[data-track="batching: Add to batch"]' const accordionDetails = '[data-testid="accordion-details"]' const copyIcon = '[data-testid="copy-btn-icon"]' diff --git a/cypress/e2e/pages/create_wallet.pages.js b/cypress/e2e/pages/create_wallet.pages.js index 655bfe7d93..44d8cce983 100644 --- a/cypress/e2e/pages/create_wallet.pages.js +++ b/cypress/e2e/pages/create_wallet.pages.js @@ -1,6 +1,7 @@ import * as main from '../pages/main.page' import { connectedWalletExecMethod } from '../pages/create_tx.pages' import * as sidebar from '../pages/sidebar.pages' +import * as constants from '../../support/constants' const welcomeLoginScreen = '[data-testid="welcome-login"]' const expandMoreIcon = 'svg[data-testid="ExpandMoreIcon"]' @@ -39,6 +40,7 @@ export const addFundsSection = '[data-testid="add-funds-section"]' export const noTokensAlert = '[data-testid="no-tokens-alert"]' const networkCheckbox = '[data-testid="network-checkbox"]' const cancelIcon = '[data-testid="CancelIcon"]' +const thresholdItem = '[data-testid="threshold-item"]' const sponsorStr = 'Your account is sponsored by Goerli' const safeCreationProcessing = 'Transaction is being executed' @@ -129,7 +131,7 @@ export function clickOnReviewStepNextBtn() { export function clickOnLetsGoBtn() { cy.get(creationModalLetsGoBtn).click() - cy.get(creationModalLetsGoBtn, { timeout: 60000 }).should('not.exist') + return cy.get(creationModalLetsGoBtn, { timeout: 60000 }).should('not.exist') } export function verifyOwnerInfoIsPresent() { @@ -197,10 +199,20 @@ export function selectNetwork(network) { } export function selectMultiNetwork(index, network) { - cy.get('input').eq(index).click() - cy.get('input').eq(index).type(network) + clickOnMultiNetworkInput(index) + enterNetwork(index, network) + clickOnNetwrokCheckbox() +} + +export function clickOnNetwrokCheckbox() { cy.get(networkCheckbox).eq(0).click() } +export function enterNetwork(index, network) { + cy.get('input').eq(index).type(network) +} +export function clickOnMultiNetworkInput(index) { + cy.get('input').eq(index).click() +} export function clearNetworkInput(index) { cy.get('input').eq(index).click() @@ -256,7 +268,7 @@ export function addNewOwner(name, address, index) { export function updateThreshold(number) { cy.get(thresholdInput).parent().click() - cy.contains('li', number).click() + cy.get(thresholdItem).contains(number).click() } export function removeOwner(index) { @@ -302,3 +314,31 @@ function getOwnerNameInput(index) { function getOwnerAddressInput(index) { return `input[name="owners.${index}.address"]` } + +export function assertCFSafeThresholdAndSigners(chainId, threshold, expectedOwnersCount, lsdata) { + const localStorageData = lsdata + const data = JSON.parse(localStorageData) + let thresholdFound = false + + for (const address in data[chainId]) { + const safe = data[chainId][address] + + if (safe.props.safeAccountConfig.threshold === threshold) { + thresholdFound = true + + const ownersCount = safe.props.safeAccountConfig.owners.length + if (ownersCount !== expectedOwnersCount) { + throw new Error( + `Safe at address ${address} on chain ID ${chainId} has ${ownersCount} owners, expected ${expectedOwnersCount}.`, + ) + } + + console.log(`Safe with threshold ${threshold} and ${expectedOwnersCount} owners exists on chain ID ${chainId}.`) + break + } + } + + if (!thresholdFound) { + throw new Error(`No safe found with threshold ${threshold} on chain ID ${chainId}.`) + } +} diff --git a/cypress/e2e/pages/nfts.pages.js b/cypress/e2e/pages/nfts.pages.js index d73593a756..52d1f9b64a 100644 --- a/cypress/e2e/pages/nfts.pages.js +++ b/cypress/e2e/pages/nfts.pages.js @@ -150,7 +150,7 @@ export function verifyReviewModalData(NFTcount) { if (NFTcount > 1) { const numbersArr = Array.from({ length: NFTcount }, (_, index) => index + 1) numbersArr.forEach((number) => { - cy.contains(number.toString()).should('be.visible') + cy.contains(number.toString()).scrollIntoView().should('be.visible') }) } } diff --git a/cypress/e2e/pages/owners.pages.js b/cypress/e2e/pages/owners.pages.js index bbbee06bf1..8d653bc327 100644 --- a/cypress/e2e/pages/owners.pages.js +++ b/cypress/e2e/pages/owners.pages.js @@ -7,6 +7,7 @@ import * as addressBook from '../pages/address_book.page' const tooltipLabel = (label) => `span[aria-label="${label}"]` export const removeOwnerBtn = 'span[data-track="settings: Remove owner"] > span > button' const replaceOwnerBtn = 'span[data-track="settings: Replace owner"] > span > button' +const changeThresholdBtn = 'span[data-track="settings: Change threshold"] > button' const tooltip = 'div[role="tooltip"]' const expandMoreIcon = 'svg[data-testid="ExpandMoreIcon"]' const sentinelStart = 'div[data-testid="sentinelStart"]' @@ -26,6 +27,7 @@ const addOwnerBtn = '[data-testid="add-owner-btn"]' const addOwnerNextBtn = '[data-testid="add-owner-next-btn"]' const modalHeader = '[data-testid="modal-header"]' const addressToBeRemoved = '[aria-label="Copy to clipboard"] span' +const thresholdNextBtn = '[data-testid="threshold-next-btn"]' const disconnectBtnStr = 'Disconnect' const notConnectedStatus = 'Connect' @@ -37,6 +39,7 @@ const removeOwnerStr = 'Remove signer' const selectedOwnerStr = 'Selected signer' const addNewOwnerStr = 'Add new signer' const processedTransactionStr = 'Transaction was successful' +const changeThresholdStr = 'Change threshold' export const safeAccountNonceStr = 'Safe Account nonce' export const nonOwnerErrorMsg = 'Your connected wallet is not a signer of this Safe Account' @@ -64,6 +67,10 @@ export function verifyExistingOwnerAddress(index, address) { cy.get(existingOwnerAddressInput(index)).should('have.value', address) } +export function typeOwnerAddressCreateSafeStep(index, address) { + cy.get(existingOwnerAddressInput(index)).clear().type(address) +} + export function verifyExistingOwnerName(index, name) { cy.get(existingOwnerNameInput(index)).should('have.value', name) } @@ -79,7 +86,7 @@ export function verifyOwnerDeletionWindowDisplayed() { cy.get('p').contains(selectedOwnerStr) } -function clickOnThresholdDropdown() { +export function clickOnThresholdDropdown() { cy.get(thresholdDropdown).eq(0).click() } @@ -179,8 +186,11 @@ export function waitForConnectionStatus() { cy.get(createWallet.accountInfoHeader).should('exist') } -export function openAddOwnerWindow() { +export function clickOnAddSignerBtn() { cy.get(addOwnerBtn).should('be.enabled').click() +} +export function openAddOwnerWindow() { + clickOnAddSignerBtn() cy.get(newOwnerName).should('be.visible') cy.get(newOwnerAddress).should('be.visible') } @@ -244,3 +254,14 @@ export function verifyThreshold(startValue, endValue) { cy.get(thresholdList).find('li').should('have.length', endValue) cy.get('body').click(0, 0) } + +export function clickOnChangeThresholdBtn() { + cy.get(changeThresholdBtn).click({ force: true }) + cy.get('div').contains(changeThresholdStr).should('exist') +} + +export function clickOnThresholdNextBtn() { + //TODO: Remove extra wait when init sdk is merged + cy.wait(3000) + cy.get(thresholdNextBtn).click() +} diff --git a/cypress/e2e/pages/sidebar.pages.js b/cypress/e2e/pages/sidebar.pages.js index 02503f5543..7da5e1cf85 100644 --- a/cypress/e2e/pages/sidebar.pages.js +++ b/cypress/e2e/pages/sidebar.pages.js @@ -59,10 +59,16 @@ export const undeployedSafe = 'Undeployed Sepolia' const notActivatedStr = 'Not activated' export const addingNetworkNotPossibleStr = 'Adding another network is not possible for this Safe.' export const createSafeMsg = (network) => `Successfully added your account on ${network}` +const signersNotConsistentMsg = 'Signers are not consistent' +const signersNotConsistentMsg2 = (network) => `Signers are different on these networks of this account:${network}` +const signersNotConsistentMsg3 = + 'To manage your account easier and to prevent lose of funds, we recommend keeping the same signers' +const signersNotConsistentConfirmTxViewMsg = (network) => + `Signers are not consistent across networks on this account. Changing signers will only affect the account on ${network}` export const addedSafesEth = ['0x8675...a19b'] export const addedSafesSepolia = ['0x6d0b...6dC1', '0x5912...fFdb', '0x0637...708e', '0xD157...DE9a'] -export const sideBarListItems = ['Home', 'Assets', 'Transactions', 'Address book', 'Apps', 'Settings'] +export const sideBarListItems = ['Home', 'Assets', 'Transactions', 'Address book', 'Apps', 'Settings', 'Swap'] export const sideBarSafes = { safe1: '0xBb26E3717172d5000F87DeFd391994f789D80aEB', safe2: '0x905934aA8758c06B2422F0C90D97d2fbb6677811', @@ -178,6 +184,10 @@ export function verifyTxCounter(counter) { cy.get(sideBarListItem).contains(sideBarListItems[2]).should('contain', counter) } +export function verifyNavItemDisabled(item) { + cy.get(sideBarListItem).contains(item).parents('li').invoke('attr', 'class').should('include', 'disabled') +} + export function verifySafeCount(count) { main.verifyMinimumElementsCount(sideSafeListItem, count) } @@ -279,7 +289,7 @@ export function checkThereIsNoOptionsMenu(index) { } export function checkUndeployedSafeExists(index) { - getSubAccountContainer(index).contains(notActivatedStr).should('exist') + return getSubAccountContainer(index).contains(notActivatedStr).should('exist') } export function checkAddNetworkBtnPosition(index) { @@ -454,3 +464,13 @@ export function checkNetworksInRange(expectedString, expectedCount, direction = return cy.wrap(liElements) }) } + +export function checkInconsistentSignersMsgDisplayed(network) { + cy.contains(signersNotConsistentMsg).should('exist') + cy.contains(signersNotConsistentMsg2(network)).should('exist') + cy.contains(signersNotConsistentMsg3).should('exist') +} + +export function checkInconsistentSignersMsgDisplayedConfirmTxView(network) { + cy.contains(signersNotConsistentConfirmTxViewMsg(network)).should('exist') +} diff --git a/cypress/e2e/pages/transactions.page.js b/cypress/e2e/pages/transactions.page.js index 2b0c1a5284..b602ccb094 100644 --- a/cypress/e2e/pages/transactions.page.js +++ b/cypress/e2e/pages/transactions.page.js @@ -7,6 +7,7 @@ const executeFormBtn = '[data-testid="execute-form-btn"]' const executeBtnStr = 'Execute' const txCompletedStr = 'Transaction was successful' +export const relayRemainingAttemptsStr = 'free transactions left today' export function selectExecuteNow() { cy.get(executeNowOption).click() diff --git a/cypress/e2e/prodhealthcheck/multichain_network.cy.js b/cypress/e2e/prodhealthcheck/multichain_network.cy.js index 670d04f8d0..0083e52720 100644 --- a/cypress/e2e/prodhealthcheck/multichain_network.cy.js +++ b/cypress/e2e/prodhealthcheck/multichain_network.cy.js @@ -36,4 +36,25 @@ describe('[PROD] Multichain add network tests', () => { create_wallet.openNetworkSelector() cy.contains(sideBar.addingNetworkNotPossibleStr) }) + + it('Verify that zkSync network is not available during multichain safe creation', () => { + cy.visit(constants.prodbaseUrl + constants.setupUrl + staticSafes.SEP_STATIC_SAFE_4) + wallet.connectSigner(signer) + cy.visit(constants.prodbaseUrl + constants.welcomeUrl + '?chain=sep') + create_wallet.clickOnContinueWithWalletBtn() + create_wallet.clickOnCreateNewSafeBtn() + create_wallet.selectMultiNetwork(1, constants.networks.polygon.toLowerCase()) + cy.contains('li', constants.networks.zkSync).should('have.attr', 'aria-disabled', 'true') + }) + + it('Verify that zkSync network is available as part of single safe creation flow ', () => { + cy.visit(constants.prodbaseUrl + constants.setupUrl + staticSafes.SEP_STATIC_SAFE_4) + wallet.connectSigner(signer) + cy.visit(constants.prodbaseUrl + constants.welcomeUrl + '?chain=sep') + create_wallet.clickOnContinueWithWalletBtn() + create_wallet.clickOnCreateNewSafeBtn() + create_wallet.clearNetworkInput(1) + create_wallet.enterNetwork(1, 'zkSync') + cy.contains('li', constants.networks.zkSync).should('not.have.attr', 'aria-disabled', 'true') + }) }) diff --git a/cypress/e2e/regression/multichain_create_safe.cy.js b/cypress/e2e/regression/multichain_create_safe.cy.js new file mode 100644 index 0000000000..6a4dae98a6 --- /dev/null +++ b/cypress/e2e/regression/multichain_create_safe.cy.js @@ -0,0 +1,97 @@ +import * as constants from '../../support/constants.js' +import * as main from '../pages/main.page.js' +import * as sideBar from '../pages/sidebar.pages.js' +import * as ls from '../../support/localstorage_data.js' +import { getSafes, CATEGORIES } from '../../support/safes/safesHandler.js' +import * as wallet from '../../support/utils/wallet.js' +import * as createwallet from '../pages/create_wallet.pages' +import * as createtx from '../pages/create_tx.pages.js' +import * as tx from '../pages/transactions.page.js' +import * as owner from '../pages/owners.pages' + +let staticSafes = [] + +const walletCredentials = JSON.parse(Cypress.env('CYPRESS_WALLET_CREDENTIALS')) +const signer = walletCredentials.OWNER_4_PRIVATE_KEY +// DO NOT use OWNER_2_PRIVATE_KEY for safe creation. Used for CF safes. +const signer2 = walletCredentials.OWNER_2_PRIVATE_KEY + +describe('Multichain safe creation tests', () => { + before(async () => { + staticSafes = await getSafes(CATEGORIES.static) + }) + + beforeEach(() => { + cy.visit(constants.welcomeUrl + '?chain=sep') + cy.wait(2000) + wallet.connectSigner(signer) + }) + + it('Verify that Pay now is not available for the multichain safe creation', () => { + createwallet.clickOnContinueWithWalletBtn() + createwallet.clickOnCreateNewSafeBtn() + createwallet.selectMultiNetwork(1, constants.networks.polygon.toLowerCase()) + createwallet.clickOnNextBtn() + createwallet.clickOnNextBtn() + main.verifyElementsCount(createwallet.payNowExecMethod, 0) + }) + + it('Verify that Pay now is available for single safe creation', () => { + createwallet.clickOnContinueWithWalletBtn() + createwallet.clickOnCreateNewSafeBtn() + createwallet.clearNetworkInput(1) + createwallet.enterNetwork(1, constants.networks.polygon) + createwallet.clickOnNetwrokCheckbox() + createwallet.clickOnNextBtn() + createwallet.clickOnNextBtn() + main.verifyElementsCount(createtx.payNowExecMethod, 1) + }) + + it('Verify that Relay is available for one safe creation', () => { + createwallet.clickOnContinueWithWalletBtn() + createwallet.clickOnCreateNewSafeBtn() + createwallet.clearNetworkInput(1) + createwallet.enterNetwork(1, constants.networks.polygon) + createwallet.clickOnNetwrokCheckbox() + createwallet.clickOnNextBtn() + createwallet.clickOnNextBtn() + tx.selectRelayOtion() + cy.contains(tx.relayRemainingAttemptsStr).should('exist') + }) + + it('Verify that multichain safe creation is available with 2/2 setup', () => { + createwallet.clickOnContinueWithWalletBtn() + createwallet.clickOnCreateNewSafeBtn() + createwallet.selectMultiNetwork(1, constants.networks.polygon.toLowerCase()) + createwallet.clickOnNextBtn() + owner.clickOnAddSignerBtn() + owner.typeOwnerAddressCreateSafeStep(1, constants.SEPOLIA_OWNER_2) + owner.clickOnThresholdDropdown() + owner.getThresholdOptions().eq(1).click() + createwallet.clickOnNextBtn() + createwallet.clickOnReviewStepNextBtn() + createwallet.clickOnLetsGoBtn().then(() => { + let data = localStorage.getItem(constants.localStorageKeys.SAFE_v2__undeployedSafes) + createwallet.assertCFSafeThresholdAndSigners(constants.networkKeys.polygon, 2, 2, data) + createwallet.assertCFSafeThresholdAndSigners(constants.networkKeys.sepolia, 2, 2, data) + }) + }) + + it('Verify that multichain safe creation is available for 1/2 set up', () => { + createwallet.clickOnContinueWithWalletBtn() + createwallet.clickOnCreateNewSafeBtn() + createwallet.selectMultiNetwork(1, constants.networks.polygon.toLowerCase()) + createwallet.clickOnNextBtn() + owner.clickOnAddSignerBtn() + owner.typeOwnerAddressCreateSafeStep(1, constants.SEPOLIA_OWNER_2) + owner.clickOnThresholdDropdown() + owner.getThresholdOptions().eq(0).click() + createwallet.clickOnNextBtn() + createwallet.clickOnReviewStepNextBtn() + createwallet.clickOnLetsGoBtn().then(() => { + let data = localStorage.getItem(constants.localStorageKeys.SAFE_v2__undeployedSafes) + createwallet.assertCFSafeThresholdAndSigners(constants.networkKeys.polygon, 1, 2, data) + createwallet.assertCFSafeThresholdAndSigners(constants.networkKeys.sepolia, 1, 2, data) + }) + }) +}) diff --git a/cypress/e2e/regression/multichain_setup.cy.js b/cypress/e2e/regression/multichain_setup.cy.js new file mode 100644 index 0000000000..b2ff738d4b --- /dev/null +++ b/cypress/e2e/regression/multichain_setup.cy.js @@ -0,0 +1,89 @@ +import * as constants from '../../support/constants.js' +import * as main from '../pages/main.page.js' +import * as sideBar from '../pages/sidebar.pages.js' +import * as ls from '../../support/localstorage_data.js' +import { getSafes, CATEGORIES } from '../../support/safes/safesHandler.js' +import * as wallet from '../../support/utils/wallet.js' +import * as navigation from '../pages/navigation.page.js' +import * as create_wallet from '../pages/create_wallet.pages.js' +import * as owner from '../pages/owners.pages.js' + +let staticSafes = [] + +const walletCredentials = JSON.parse(Cypress.env('CYPRESS_WALLET_CREDENTIALS')) +const signer = walletCredentials.OWNER_4_PRIVATE_KEY +// DO NOT use OWNER_2_PRIVATE_KEY for safe creation. Used for CF safes. +const signer2 = walletCredentials.OWNER_2_PRIVATE_KEY + +describe('Multichain setup tests', { defaultCommandTimeout: 30000 }, () => { + before(async () => { + staticSafes = await getSafes(CATEGORIES.static) + }) + + beforeEach(() => { + cy.visit(constants.BALANCE_URL + staticSafes.MATIC_STATIC_SAFE_28) + cy.wait(2000) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addedSafes, ls.addedSafes.set5) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.multichain) + wallet.connectSigner(signer) + }) + + it('Verify that batch tx with safe activation is not allowed for the CF safes', () => { + let safe = main.changeSafeChainName(staticSafes.MATIC_STATIC_SAFE_28, 'eth') + sideBar.openSidebar() + sideBar.addNetwork(constants.networks.ethereum) + cy.contains(sideBar.createSafeMsg(constants.networks.ethereum)) + sideBar.checkUndeployedSafeExists(0).click() + main.verifyElementsCount(navigation.newTxBtn, 0) + main.verifyElementsCount(create_wallet.activateAccountBtn, 2) + cy.visit(constants.setupUrl + safe) + owner.verifyAddOwnerBtnIsDisabled() + sideBar.verifyNavItemDisabled(sideBar.sideBarListItems[4]) + sideBar.verifyNavItemDisabled(sideBar.sideBarListItems[6]) + }) + + it('Verify notification if the owner set up was changed in original safe', () => { + sideBar.openSidebar() + sideBar.addNetwork(constants.networks.ethereum) + cy.contains(sideBar.createSafeMsg(constants.networks.ethereum)) + cy.visit(constants.homeUrl + staticSafes.MATIC_STATIC_SAFE_28) + sideBar.checkInconsistentSignersMsgDisplayed(constants.networks.ethereum) + }) + + it('Verify warning on add owner for one safe in the group', () => { + cy.visit(constants.setupUrl + staticSafes.MATIC_STATIC_SAFE_28) + owner.openAddOwnerWindow() + owner.typeOwnerAddress(constants.SEPOLIA_OWNER_2) + owner.clickOnNextBtn() + sideBar.checkInconsistentSignersMsgDisplayedConfirmTxView(constants.networks.polygon) + }) + + it('Verify warning on add owner for one safe in the group', () => { + cy.visit(constants.setupUrl + staticSafes.MATIC_STATIC_SAFE_28) + owner.openAddOwnerWindow() + owner.typeOwnerAddress(constants.SEPOLIA_OWNER_2) + owner.clickOnNextBtn() + sideBar.checkInconsistentSignersMsgDisplayedConfirmTxView(constants.networks.polygon) + }) + + it('Verify warning on remove owner for one safe in the group', () => { + let safe = main.changeSafeChainName(staticSafes.MATIC_STATIC_SAFE_28, 'sep') + cy.visit(constants.setupUrl + safe) + + owner.waitForConnectionStatus() + owner.openRemoveOwnerWindow(1) + cy.wait(1000) + create_wallet.clickOnNextBtn() + sideBar.checkInconsistentSignersMsgDisplayedConfirmTxView(constants.networks.sepolia) + }) + + it('Verify warning on change policy for one safe in the group', () => { + let safe = main.changeSafeChainName(staticSafes.MATIC_STATIC_SAFE_28, 'sep') + cy.visit(constants.setupUrl + safe) + owner.waitForConnectionStatus() + owner.clickOnChangeThresholdBtn() + create_wallet.updateThreshold(2) + owner.clickOnThresholdNextBtn() + sideBar.checkInconsistentSignersMsgDisplayedConfirmTxView(constants.networks.sepolia) + }) +}) diff --git a/cypress/e2e/regression/multichain_sidebar.cy.js b/cypress/e2e/regression/multichain_sidebar.cy.js index ce2532e6fd..4bfba0ff36 100644 --- a/cypress/e2e/regression/multichain_sidebar.cy.js +++ b/cypress/e2e/regression/multichain_sidebar.cy.js @@ -119,7 +119,7 @@ describe('Multichain sidebar tests', { defaultCommandTimeout: 20000 }, () => { it('Verify balance of the safe group', () => { wallet.connectSigner(signer) sideBar.openSidebar() - sideBar.checkSafeGroupBalance(0, '0.64') + sideBar.checkSafeGroupBalance(0, '0.73') }) it('Verify address of the safe group', () => { diff --git a/cypress/support/constants.js b/cypress/support/constants.js index 57053bfa59..f4ac4f3f44 100644 --- a/cypress/support/constants.js +++ b/cypress/support/constants.js @@ -105,6 +105,7 @@ export const TXActionNames = { export const networkKeys = { sepolia: '11155111', + polygon: '137', } export const mainSideMenuOptions = { home: 'Home', diff --git a/src/components/new-safe/create/steps/OwnerPolicyStep/index.tsx b/src/components/new-safe/create/steps/OwnerPolicyStep/index.tsx index 5e2b5077b8..1984ad8d07 100644 --- a/src/components/new-safe/create/steps/OwnerPolicyStep/index.tsx +++ b/src/components/new-safe/create/steps/OwnerPolicyStep/index.tsx @@ -144,7 +144,7 @@ const OwnerPolicyStep = ({ render={({ field }) => ( {ownerFields.map((_, idx) => ( - + {idx + 1} ))} diff --git a/src/components/tx-flow/flows/ChangeThreshold/ChooseThreshold.tsx b/src/components/tx-flow/flows/ChangeThreshold/ChooseThreshold.tsx index e88fa29db7..6d289b93ac 100644 --- a/src/components/tx-flow/flows/ChangeThreshold/ChooseThreshold.tsx +++ b/src/components/tx-flow/flows/ChangeThreshold/ChooseThreshold.tsx @@ -82,7 +82,7 @@ export const ChooseThreshold = ({ {safe.owners.map((_, idx) => ( - + {idx + 1} ))} @@ -118,6 +118,7 @@ export const ChooseThreshold = ({