Skip to content

Commit

Permalink
fix: Adjust useApprovalInfos hook for non-approval txs
Browse files Browse the repository at this point in the history
  • Loading branch information
usame-algan committed Jul 11, 2023
1 parent 2aaa859 commit 312bd89
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/components/tx/ApprovalEditor/ApprovalEditor.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ describe('ApprovalEditor', () => {
expect(result.container).toBeEmptyDOMElement()
})

it.skip('renders an error', async () => {
it('renders an error', async () => {
jest
.spyOn(approvalInfos, 'useApprovalInfos')
.mockReturnValue([undefined, new Error('Error parsing approvals'), false])
Expand All @@ -35,7 +35,7 @@ describe('ApprovalEditor', () => {
expect(await result.queryByText('Error while decoding approval transactions.')).toBeInTheDocument()
})

it.skip('renders a loading skeleton', async () => {
it('renders a loading skeleton', async () => {
jest.spyOn(approvalInfos, 'useApprovalInfos').mockReturnValue([undefined, undefined, true])
const mockSafeTx = createMockSafeTransaction({ to: '0x1', data: '0x', operation: OperationType.DelegateCall })

Expand Down
23 changes: 16 additions & 7 deletions src/components/tx/ApprovalEditor/hooks/useApprovalInfos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { type SafeTransaction } from '@safe-global/safe-core-sdk-types'
import { type TokenInfo } from '@safe-global/safe-gateway-typescript-sdk'
import { ethers } from 'ethers'
import { PSEUDO_APPROVAL_VALUES } from '../utils/approvals'
import { useMemo } from 'react'

export type ApprovalInfo = {
tokenInfo: (Omit<TokenInfo, 'logoUri' | 'name'> & { logoUri?: string }) | undefined
Expand All @@ -17,22 +18,28 @@ export type ApprovalInfo = {

const ApprovalModuleInstance = new ApprovalModule()

export const useApprovalInfos = (safeTransaction: SafeTransaction | undefined) => {
export const useApprovalInfos = (
safeTransaction: SafeTransaction | undefined,
): [ApprovalInfo[] | undefined, Error | undefined, boolean] => {
const { balances } = useBalances()
const approvals = useMemo(() => {
if (!safeTransaction) return

return useAsync<ApprovalInfo[] | undefined>(
async () => {
if (!safeTransaction) return
return ApprovalModuleInstance.scanTransaction({ safeTransaction })
}, [safeTransaction])

const approvals = await ApprovalModuleInstance.scanTransaction({ safeTransaction })
const hasApprovalSignatures = !!approvals && !!approvals.payload && approvals.payload.length > 0

if (!approvals || !approvals.payload || approvals.payload.length === 0) return Promise.resolve([])
const [approvalInfos, error, loading] = useAsync<ApprovalInfo[] | undefined>(
async () => {
if (!hasApprovalSignatures) return

return Promise.all(
approvals.payload.map(async (approval) => {
let tokenInfo: Omit<TokenInfo, 'name' | 'logoUri'> | undefined = balances.items.find(
(item) => item.tokenInfo.address === approval.tokenAddress,
)?.tokenInfo

if (!tokenInfo) {
tokenInfo = await getERC20TokenInfoOnChain(approval.tokenAddress)
}
Expand All @@ -45,7 +52,9 @@ export const useApprovalInfos = (safeTransaction: SafeTransaction | undefined) =
}),
)
},
[safeTransaction, balances.items.length],
[hasApprovalSignatures, balances.items.length],
false, // Do not clear data on balance updates
)

return [hasApprovalSignatures ? approvalInfos : [], error, loading]
}
12 changes: 8 additions & 4 deletions src/components/tx/ApprovalEditor/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Divider, SvgIcon, Typography } from '@mui/material'
import { Alert, Box, Divider, Skeleton, SvgIcon, Typography } from '@mui/material'
import { type MetaTransactionData, type SafeTransaction } from '@safe-global/safe-core-sdk-types'
import css from './styles.module.css'
import { ApprovalEditorForm } from './ApprovalEditorForm'
Expand Down Expand Up @@ -32,9 +32,9 @@ export const ApprovalEditor = ({
safeTransaction: SafeTransaction | undefined
updateTransaction?: (txs: MetaTransactionData[]) => void
}) => {
const [readableApprovals] = useApprovalInfos(safeTransaction)
const [readableApprovals, error, loading] = useApprovalInfos(safeTransaction)

if (!readableApprovals || readableApprovals?.length === 0 || !safeTransaction) {
if (readableApprovals?.length === 0 || !safeTransaction) {
return null
}

Expand All @@ -52,7 +52,11 @@ export const ApprovalEditor = ({
return (
<Box display="flex" flexDirection="column" gap={2} mb={3}>
<Title />
{isReadOnly ? (
{error ? (
<Alert severity="error">Error while decoding approval transactions.</Alert>
) : loading || !readableApprovals ? (
<Skeleton variant="rounded" height={100} data-testid="approval-editor-loading" />
) : isReadOnly ? (
<Approvals approvalInfos={readableApprovals} />
) : (
<ApprovalEditorForm approvalInfos={readableApprovals} updateApprovals={updateApprovals} />
Expand Down
2 changes: 1 addition & 1 deletion src/services/security/modules/ApprovalModule/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class ApprovalModule implements SecurityModule<ApprovalModuleRequest, App
return []
}

async scanTransaction(request: ApprovalModuleRequest): Promise<SecurityResponse<ApprovalModuleResponse>> {
scanTransaction(request: ApprovalModuleRequest): SecurityResponse<ApprovalModuleResponse> {
const { safeTransaction } = request
const safeTxData = safeTransaction.data.data
const approvalInfos: Approval[] = []
Expand Down
2 changes: 1 addition & 1 deletion src/services/security/modules/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ export type SecurityResponse<Res> =
}

export interface SecurityModule<Req, Res> {
scanTransaction(request: Req): Promise<SecurityResponse<Res>>
scanTransaction(request: Req): Promise<SecurityResponse<Res>> | SecurityResponse<Res>
}

0 comments on commit 312bd89

Please sign in to comment.