Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: pending safes per chainId #2295

Merged
merged 5 commits into from
Aug 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading