Skip to content

Commit

Permalink
feat: pending safes per chainId (#2295)
Browse files Browse the repository at this point in the history
  • Loading branch information
schmanu authored Aug 8, 2023
1 parent 84b6419 commit 9750cec
Show file tree
Hide file tree
Showing 14 changed files with 285 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,27 @@ import useSyncSafeCreationStep from '@/components/new-safe/create/useSyncSafeCre
import * as wallet from '@/hooks/wallets/useWallet'
import * as localStorage from '@/services/local-storage/useLocalStorage'
import type { ConnectedWallet } from '@/services/onboard'
import * as usePendingSafe from '../steps/StatusStep/usePendingSafe'
import * as useIsWrongChain from '@/hooks/useIsWrongChain'

describe('useSyncSafeCreationStep', () => {
const mockPendingSafe = {
name: 'joyful-rinkeby-safe',
threshold: 1,
owners: [],
saltNonce: 123,
address: '0x10',
}
const setPendingSafeSpy = jest.fn()

beforeEach(() => {
jest.clearAllMocks()
const setPendingSafeSpy = jest.fn()
})

it('should go to the first step if no wallet is connected', async () => {
jest.spyOn(wallet, 'default').mockReturnValue(null)
jest.spyOn(usePendingSafe, 'usePendingSafe').mockReturnValue([undefined, setPendingSafeSpy])
const mockSetStep = jest.fn()

renderHook(() => useSyncSafeCreationStep(mockSetStep))
Expand All @@ -21,16 +34,34 @@ describe('useSyncSafeCreationStep', () => {
it('should go to the fourth step if there is a pending safe', async () => {
jest.spyOn(localStorage, 'default').mockReturnValue([{}, jest.fn()])
jest.spyOn(wallet, 'default').mockReturnValue({ address: '0x1' } as ConnectedWallet)
jest.spyOn(usePendingSafe, 'usePendingSafe').mockReturnValue([mockPendingSafe, setPendingSafeSpy])

const mockSetStep = jest.fn()

renderHook(() => useSyncSafeCreationStep(mockSetStep))

expect(mockSetStep).toHaveBeenCalledWith(4)
})

it('should go to the second step if the wrong chain is connected', async () => {
jest.spyOn(localStorage, 'default').mockReturnValue([{}, jest.fn()])
jest.spyOn(wallet, 'default').mockReturnValue({ address: '0x1' } as ConnectedWallet)
jest.spyOn(usePendingSafe, 'usePendingSafe').mockReturnValue([undefined, setPendingSafeSpy])
jest.spyOn(useIsWrongChain, 'default').mockReturnValue(true)

const mockSetStep = jest.fn()

renderHook(() => useSyncSafeCreationStep(mockSetStep))

expect(mockSetStep).toHaveBeenCalledWith(1)
})

it('should not do anything if wallet is connected and there is no pending safe', async () => {
jest.spyOn(localStorage, 'default').mockReturnValue([undefined, jest.fn()])
jest.spyOn(wallet, 'default').mockReturnValue({ address: '0x1' } as ConnectedWallet)
jest.spyOn(usePendingSafe, 'usePendingSafe').mockReturnValue([undefined, setPendingSafeSpy])
jest.spyOn(useIsWrongChain, 'default').mockReturnValue(false)

const mockSetStep = jest.fn()

renderHook(() => useSyncSafeCreationStep(mockSetStep))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,14 @@ import type { NewSafeFormData } from '@/components/new-safe/create'
import type { StepRenderProps } from '@/components/new-safe/CardStepper/useCardStepper'
import useSyncSafeCreationStep from '@/components/new-safe/create/useSyncSafeCreationStep'
import layoutCss from '@/components/new-safe/create/styles.module.css'
import useLocalStorage from '@/services/local-storage/useLocalStorage'
import { type PendingSafeData, SAFE_PENDING_CREATION_STORAGE_KEY } from '@/components/new-safe/create/steps/StatusStep'
import useConnectWallet from '@/components/common/ConnectWallet/useConnectWallet'
import KeyholeIcon from '@/components/common/icons/KeyholeIcon'
import PairingDescription from '@/components/common/PairingDetails/PairingDescription'
import PairingQRCode from '@/components/common/PairingDetails/PairingQRCode'
import { usePendingSafe } from '../StatusStep/usePendingSafe'

const ConnectWalletStep = ({ onSubmit, setStep }: StepRenderProps<NewSafeFormData>) => {
const [pendingSafe] = useLocalStorage<PendingSafeData | undefined>(SAFE_PENDING_CREATION_STORAGE_KEY)
const [pendingSafe] = usePendingSafe()
const wallet = useWallet()
const chain = useCurrentChain()
const isSupported = isPairingSupported(chain?.disabledWallets)
Expand Down
5 changes: 2 additions & 3 deletions src/components/new-safe/create/steps/ReviewStep/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ import { getReadOnlyFallbackHandlerContract } from '@/services/contracts/safeCon
import { computeNewSafeAddress } from '@/components/new-safe/create/logic'
import useWallet from '@/hooks/wallets/useWallet'
import { useWeb3 } from '@/hooks/wallets/web3'
import useLocalStorage from '@/services/local-storage/useLocalStorage'
import { type PendingSafeData, SAFE_PENDING_CREATION_STORAGE_KEY } from '@/components/new-safe/create/steps/StatusStep'
import useSyncSafeCreationStep from '@/components/new-safe/create/useSyncSafeCreationStep'
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
import NetworkWarning from '@/components/new-safe/create/NetworkWarning'
Expand All @@ -27,6 +25,7 @@ import { useLeastRemainingRelays } from '@/hooks/useRemainingRelays'
import classnames from 'classnames'
import { hasRemainingRelays } from '@/utils/relaying'
import { BigNumber } from 'ethers'
import { usePendingSafe } from '../StatusStep/usePendingSafe'

const ReviewStep = ({ data, onSubmit, onBack, setStep }: StepRenderProps<NewSafeFormData>) => {
const isWrongChain = useIsWrongChain()
Expand All @@ -36,7 +35,7 @@ const ReviewStep = ({ data, onSubmit, onBack, setStep }: StepRenderProps<NewSafe
const provider = useWeb3()
const [gasPrice] = useGasPrice()
const saltNonce = useMemo(() => Date.now(), [])
const [_, setPendingSafe] = useLocalStorage<PendingSafeData | undefined>(SAFE_PENDING_CREATION_STORAGE_KEY)
const [_, setPendingSafe] = usePendingSafe()
const [executionMethod, setExecutionMethod] = useState(ExecutionMethod.RELAY)

const ownerAddresses = useMemo(() => data.owners.map((owner) => owner.address), [data.owners])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Box, Step, StepConnector, Stepper, Typography } from '@mui/material'
import css from '@/components/new-safe/create/steps/StatusStep/styles.module.css'
import EthHashInfo from '@/components/common/EthHashInfo'
import { SafeCreationStatus } from '@/components/new-safe/create/steps/StatusStep/useSafeCreation'
import type { PendingSafeData } from '@/components/new-safe/create/steps/StatusStep/index'
import StatusStep from '@/components/new-safe/create/steps/StatusStep/StatusStep'
import { usePendingSafe } from './usePendingSafe'

const StatusStepper = ({ pendingSafe, status }: { pendingSafe: PendingSafeData; status: SafeCreationStatus }) => {
const StatusStepper = ({ status }: { status: SafeCreationStatus }) => {
const [pendingSafe] = usePendingSafe()
if (!pendingSafe?.safeAddress) return null

return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,6 @@ describe('StatusStep', () => {
/>,
)

expect(useSafeCreationSpy).toHaveBeenCalledWith(
undefined,
expect.anything(),
SafeCreationStatus.PROCESSING,
expect.anything(),
true,
)
expect(useSafeCreationSpy).toHaveBeenCalledWith(SafeCreationStatus.PROCESSING, expect.anything(), true)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { renderHook } from '@/tests/test-utils'
import { usePendingSafe } from '../usePendingSafe'

import { hexZeroPad } from 'ethers/lib/utils'
import { useCurrentChain } from '@/hooks/useChains'

// mock useCurrentChain
jest.mock('@/hooks/useChains', () => ({
useCurrentChain: jest.fn(() => ({
shortName: 'gor',
chainId: '5',
chainName: 'Goerli',
features: [],
})),
}))

describe('usePendingSafe()', () => {
const mockPendingSafe1 = {
name: 'joyful-rinkeby-safe',
threshold: 1,
owners: [],
saltNonce: 123,
address: hexZeroPad('0x10', 20),
}
const mockPendingSafe2 = {
name: 'joyful-rinkeby-safe',
threshold: 1,
owners: [],
saltNonce: 123,
address: hexZeroPad('0x10', 20),
}

beforeEach(() => {
window.localStorage.clear()
})
it('Should initially be undefined', () => {
const { result } = renderHook(() => usePendingSafe())
expect(result.current[0]).toBeUndefined()
})

it('Should set the pendingSafe per ChainId', async () => {
const { result, rerender } = renderHook(() => usePendingSafe())

result.current[1](mockPendingSafe1)

rerender()

expect(result.current[0]).toEqual(mockPendingSafe1)
;(useCurrentChain as jest.Mock).mockImplementation(() => ({
shortName: 'eth',
chainId: '1',
chainName: 'Ethereum',
features: [],
}))

rerender()
expect(result.current[0]).toEqual(undefined)

result.current[1](mockPendingSafe2)
rerender()
expect(result.current[0]).toEqual(mockPendingSafe2)
;(useCurrentChain as jest.Mock).mockImplementation(() => ({
shortName: 'gor',
chainId: '5',
chainName: 'Goerli',
features: [],
}))
rerender()
expect(result.current[0]).toEqual(mockPendingSafe1)
})
})
Loading

0 comments on commit 9750cec

Please sign in to comment.