Skip to content

Commit

Permalink
Add status screen
Browse files Browse the repository at this point in the history
  • Loading branch information
iamacook committed Nov 28, 2024
1 parent f9e5761 commit e5c50ac
Show file tree
Hide file tree
Showing 15 changed files with 300 additions and 199 deletions.
7 changes: 1 addition & 6 deletions public/images/sidebar/subaccounts-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/components/sidebar/SafeListContextMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const SafeListContextMenu = ({
{!undeployedSafe && subaccounts?.safes && subaccounts.safes.length > 0 && (
<MenuItem
onClick={handleOpenModal(ModalType.SUBACCOUNTS, {
...SUBACCOUNT_EVENTS.OPEN,
...SUBACCOUNT_EVENTS.OPEN_LIST,
label: SUBACCOUNT_LABELS.sidebar,
})}
>
Expand Down
2 changes: 1 addition & 1 deletion src/components/sidebar/SidebarHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const SafeHeader = (): ReactElement => {
<ExplorerButton {...blockExplorerLink} className={css.iconButton} icon={LinkIconBold} />
</Track>

<Track {...SUBACCOUNT_EVENTS.OPEN} label={SUBACCOUNT_LABELS.header}>
<Track {...SUBACCOUNT_EVENTS.OPEN_LIST} label={SUBACCOUNT_LABELS.header}>
<SubaccountsButton chainId={safe.chainId} safeAddress={safe.address.value} />
</Track>

Expand Down
4 changes: 3 additions & 1 deletion src/components/sidebar/SubaccountsList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export function SubaccountsList({ subaccounts }: { subaccounts: Array<string> })
return (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1, alignItems: 'center' }}>
{subaccountsToShow.map((subaccount) => {
// TODO: Turn into link to Subaccount
return (
<Box
sx={{
Expand All @@ -37,7 +38,7 @@ export function SubaccountsList({ subaccounts }: { subaccounts: Array<string> })
}}
key={subaccount}
>
<EthHashInfo address={subaccount} />
<EthHashInfo address={subaccount} showPrefix={false} />
<ChevronRight color="border" />
</Box>
)
Expand All @@ -49,6 +50,7 @@ export function SubaccountsList({ subaccounts }: { subaccounts: Array<string> })
color="text.secondary"
sx={{
textTransform: 'uppercase',
fontWeight: 700,
}}
onClick={onShowAll}
>
Expand Down
153 changes: 102 additions & 51 deletions src/components/tx-flow/flows/CreateSubaccount/ReviewSubaccount.tsx
Original file line number Diff line number Diff line change
@@ -1,83 +1,101 @@
import { useContext, useEffect } from 'react'
import { useContext, useEffect, useMemo } from 'react'

import SignOrExecuteForm from '@/components/tx/SignOrExecuteForm'
import { SafeTxContext } from '@/components/tx-flow/SafeTxProvider'
import { createSubaccount } from '@/components/tx-flow/flows/CreateSubaccount/create-subaccount-tx'
import useSafeInfo from '@/hooks/useSafeInfo'
import useBalances from '@/hooks/useBalances'
import { useCurrentChain } from '@/hooks/useChains'
import useWallet from '@/hooks/wallets/useWallet'
import { useAppDispatch } from '@/store'
import { upsertAddressBookEntries } from '@/store/addressBookSlice'
import { getLatestSafeVersion } from '@/utils/chains'
import { getReadOnlyFallbackHandlerContract } from '@/services/contracts/safeContracts'
import useAsync from '@/hooks/useAsync'
import { computeNewSafeAddress } from '@/components/new-safe/create/logic'
import type { SetupSubaccountForm } from '@/components/tx-flow/flows/CreateSubaccount/SetupSubaccount'
import { createNewUndeployedSafeWithoutSalt, encodeSafeCreationTx } from '@/components/new-safe/create/logic'
import {
SetupSubaccountFormAssetFields,
type SetupSubaccountForm,
} from '@/components/tx-flow/flows/CreateSubaccount/SetupSubaccount'
import { useGetSafesByOwnerQuery } from '@/store/slices'
import { predictAddressBasedOnReplayData } from '@/features/multichain/utils/utils'
import { useWeb3ReadOnly } from '@/hooks/wallets/web3'
import { createTokenTransferParams } from '@/services/tx/tokenTransferParams'
import { createMultiSendCallOnlyTx, createTx } from '@/services/tx/tx-sender'
import type { SafeTransaction } from '@safe-global/safe-core-sdk-types'
import EthHashInfo from '@/components/common/EthHashInfo'
import { Grid, Typography } from '@mui/material'

export function ReviewSubaccount({ params }: { params: SetupSubaccountForm }) {
const dispatch = useAppDispatch()
const wallet = useWallet()
const { safeAddress, safe } = useSafeInfo()
const chain = useCurrentChain()
const { setSafeTx, setSafeTxError } = useContext(SafeTxContext)
const { balances } = useBalances()
const safeVersion = getLatestSafeVersion(chain)
const provider = useWeb3ReadOnly()
const { data: subaccounts } = useGetSafesByOwnerQuery({ chainId: safe.chainId, ownerAddress: safe.address.value })
const saltNonce = (subaccounts?.safes.length ?? 0).toString()
const version = getLatestSafeVersion(chain)

const [safeAccountConfig] = useAsync(async () => {
const fallbackHandler = await getReadOnlyFallbackHandlerContract(safeVersion)
const owners = [safeAddress]
return {
owners,
threshold: owners.length,
fallbackHandler: fallbackHandler?.contractAddress,
}
}, [safeVersion, safeAddress])

const [predictedSafeAddress] = useAsync(async () => {
if (!wallet?.provider || !safeAccountConfig || !chain || !safeVersion) {
const safeAccountConfig = useMemo(() => {
if (!chain || !subaccounts) {
return
}
return computeNewSafeAddress(
wallet.provider,

const undeployedSafe = createNewUndeployedSafeWithoutSalt(
version,
{
safeAccountConfig,
saltNonce,
owners: [safeAddress],
threshold: 1,
},
chain,
safeVersion,
)
}, [wallet?.provider, safeAccountConfig, chain, safeVersion, saltNonce])
const saltNonce = subaccounts.safes.length.toString()

return {
...undeployedSafe,
saltNonce,
}
}, [chain, safeAddress, subaccounts, version])

const [predictedSafeAddress] = useAsync(async () => {
if (provider && safeAccountConfig) {
return predictAddressBasedOnReplayData(safeAccountConfig, provider)
}
}, [provider, safeAccountConfig])

useEffect(() => {
if (!wallet?.provider || !safeAccountConfig || !predictedSafeAddress) {
if (!chain || !safeAccountConfig || !predictedSafeAddress) {
return
}
createSubaccount({
provider: wallet.provider,
assets: params.assets,
safeAccountConfig,
safeDeploymentConfig: {
saltNonce,
},
predictedSafeAddress,
balances,
})
.then(setSafeTx)
.catch(setSafeTxError)
}, [
wallet?.provider,
params.assets,
safeAccountConfig,
predictedSafeAddress,
balances,
setSafeTx,
setSafeTxError,
saltNonce,
])

const deploymentTx = {
to: safeAccountConfig.factoryAddress,
data: encodeSafeCreationTx(safeAccountConfig, chain),
value: '0',
}

const fundingTxs = params.assets
.map((asset) => {
const token = balances.items.find((item) => {
return item.tokenInfo.address === asset[SetupSubaccountFormAssetFields.tokenAddress]
})
if (token) {
return createTokenTransferParams(
predictedSafeAddress,
asset[SetupSubaccountFormAssetFields.amount],
token.tokenInfo.decimals,
token.tokenInfo.address,
)
}
})
.filter((tx) => {
return tx != null
})

const createSafeTx = async (): Promise<SafeTransaction> => {
const isMultiSend = fundingTxs.length > 0
return isMultiSend ? createMultiSendCallOnlyTx([deploymentTx, ...fundingTxs]) : createTx(deploymentTx)
}

createSafeTx().then(setSafeTx).catch(setSafeTxError)
}, [chain, params.assets, safeAccountConfig, predictedSafeAddress, balances.items, setSafeTx, setSafeTxError])

const onSubmit = () => {
if (!predictedSafeAddress) {
Expand All @@ -92,5 +110,38 @@ export function ReviewSubaccount({ params }: { params: SetupSubaccountForm }) {
)
}

return <SignOrExecuteForm onSubmit={onSubmit} />
return (
<SignOrExecuteForm onSubmit={onSubmit}>
{predictedSafeAddress && (
<Grid
container
sx={{
gap: 1,
}}
>
<Grid item md>
<Typography
variant="body2"
sx={{
color: 'text.secondary',
}}
>
Subaccount
</Typography>
</Grid>

<Grid data-testid="beneficiary-address" item md={10}>
<EthHashInfo
name={params.name}
address={predictedSafeAddress}
shortAddress={false}
hasExplorer
showCopyButton
showAvatar={false}
/>
</Grid>
</Grid>
)}
</SignOrExecuteForm>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ import InfoIcon from '@/public/images/notifications/info.svg'
import AddIcon from '@/public/images/common/add.svg'
import DeleteIcon from '@/public/images/common/delete.svg'
import TxCard from '@/components/tx-flow/common/TxCard'
import { useMnemonicSafeName } from '@/hooks/useMnemonicName'
import useSafeAddress from '@/hooks/useSafeAddress'
import useAddressBook from '@/hooks/useAddressBook'
import NameInput from '@/components/common/NameInput'
import tokenInputCss from '@/components/common/TokenAmountInput/styles.module.css'
import NumberField from '@/components/common/NumberField'
Expand Down Expand Up @@ -54,7 +55,10 @@ export function SetUpSubaccount({
params: SetupSubaccountForm
onSubmit: (params: SetupSubaccountForm) => void
}) {
const fallbackName = useMnemonicSafeName()
const addressBook = useAddressBook()
const safeAddress = useSafeAddress()
const fallbackName = `${addressBook[safeAddress]} Subaccount`

const formMethods = useForm<SetupSubaccountForm>({
defaultValues: params,
mode: 'onChange',
Expand Down
111 changes: 0 additions & 111 deletions src/components/tx-flow/flows/CreateSubaccount/create-subaccount-tx.ts

This file was deleted.

Loading

0 comments on commit e5c50ac

Please sign in to comment.