Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
[presign] Safe swap tx display (#1652)
Browse files Browse the repository at this point in the history
* Display gnosis transaction in orders

* Add cancellation and expiration styles

* Fix error

* Improve signature messages

* Fix missing props

* Add executed flag

* Add message

* Inform when the transaction has not been executed

* Simplify messages

* Transaction/Orders styles update.

* Transaction/Orders styles update.

* Show enough signatures if the status os open

Co-authored-by: biocom <[email protected]>
Co-authored-by: Michel <[email protected]>
  • Loading branch information
3 people authored Oct 28, 2021
1 parent 02f035e commit 2218878
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 65 deletions.
112 changes: 77 additions & 35 deletions src/custom/components/AccountDetails/Transaction/ActivityDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react'
import { CurrencyAmount } from '@uniswap/sdk-core'

import { OrderStatus } from 'state/orders/actions'
import { EnhancedTransactionDetails } from 'state/enhancedTransactions/reducer'

import { formatSmart } from 'utils/format'
import {
Expand All @@ -25,6 +24,7 @@ import CurrencyLogo from 'components/CurrencyLogo'
import AttentionIcon from 'assets/cow-swap/attention.svg'
import { useToken } from 'hooks/Tokens'
import SVG from 'react-inlinesvg'
import { ActivityStatus } from '@src/custom/hooks/useRecentActivity'

const DEFAULT_ORDER_SUMMARY = {
from: '',
Expand All @@ -45,44 +45,97 @@ function unfillableAlert(): JSX.Element {
}

function GnosisSafeTxDetails(props: {
enhancedTransaction: EnhancedTransactionDetails | null
gnosisSafeThreshold: number
chainId: number
activityDerivedState: ActivityDerivedState
}): JSX.Element | null {
const { enhancedTransaction, gnosisSafeThreshold, chainId } = props
const { chainId, activityDerivedState } = props
const { gnosisSafeInfo, enhancedTransaction, status, isOrder, order, isExpired, isCancelled } = activityDerivedState
const gnosisSafeThreshold = gnosisSafeInfo?.threshold
const safeTransaction = enhancedTransaction?.safeTransaction || order?.presignGnosisSafeTx

if (!enhancedTransaction || !enhancedTransaction.safeTransaction) {
if (!gnosisSafeThreshold || !gnosisSafeInfo || !safeTransaction) {
return null
}

const { confirmations, nonce } = enhancedTransaction.safeTransaction
// The activity is executed Is tx mined or is the swap executed
const isExecutedActivity = isOrder
? order?.fulfillmentTime !== undefined
: enhancedTransaction?.confirmedTime !== undefined

// Check if its in a state where we dont need more signatures. We do this, because this state comes from CowSwap API, which
// sometimes can be faster getting the state than Gnosis Safe API (that would give us the pending signatures). We use
// this check to infer that we don't need to sign anything anymore
const alreadySigned = isOrder ? status !== ActivityStatus.PRESIGNATURE_PENDING : status !== ActivityStatus.PENDING

const { confirmations, nonce, isExecuted } = safeTransaction

const numConfirmations = confirmations?.length ?? 0
const pendingSignaturesCount = gnosisSafeThreshold - numConfirmations
const isPendingSignatures = pendingSignaturesCount > 0

let signaturesMessage: JSX.Element

const areIsMessage = pendingSignaturesCount > 1 ? 's are' : ' is'

if (isExecutedActivity) {
signaturesMessage = <span>Executed</span>
} else if (isCancelled) {
signaturesMessage = <span>Cancelled order</span>
} else if (isExpired) {
signaturesMessage = <span>Expired order</span>
} else if (alreadySigned) {
signaturesMessage = <span>Enough signatures</span>
} else if (numConfirmations == 0) {
signaturesMessage = (
<>
<span>
<b>No signatures yet</b>
</span>
<TextAlert isPending={isPendingSignatures} isCancelled={isCancelled} isExpired={isExpired}>
{gnosisSafeThreshold} signature{areIsMessage} required
</TextAlert>
</>
)
} else if (numConfirmations >= gnosisSafeThreshold) {
signaturesMessage = isExecuted ? (
<span>
<b>Enough signatures</b>
</span>
) : (
<>
<span>
Enough signatures, <b>but not executed</b>
</span>
<TextAlert isPending={isPendingSignatures} isCancelled={isCancelled} isExpired={isExpired}>
Execute Gnosis Safe transaction
</TextAlert>
</>
)
} else {
signaturesMessage = (
<>
<span>
Signed:{' '}
<b>
{numConfirmations} out of {gnosisSafeThreshold} signers
</b>
</span>
<TextAlert isPending={isPendingSignatures} isCancelled={isCancelled} isExpired={isExpired}>
{pendingSignaturesCount} more signature{areIsMessage} required
</TextAlert>
</>
)
}

return (
<TransactionInnerDetail>
<span>
Safe Nonce: <b>{nonce}</b>
</span>
<span>
Signed:{' '}
<b>
{numConfirmations} out of {gnosisSafeThreshold} signers
</b>
</span>
{isPendingSignatures && (
<TextAlert isPending={isPendingSignatures}>
{pendingSignaturesCount} more signature{pendingSignaturesCount > 1 ? 's are' : ' is'} required
</TextAlert>
)}
{signaturesMessage}

{/* View in: Gnosis Safe */}
<GnosisSafeLink
chainId={chainId}
enhancedTransaction={enhancedTransaction}
gnosisSafeThreshold={gnosisSafeThreshold}
/>
<GnosisSafeLink chainId={chainId} safeTransaction={safeTransaction} gnosisSafeThreshold={gnosisSafeThreshold} />
</TransactionInnerDetail>
)
}
Expand All @@ -105,7 +158,7 @@ export function ActivityDetails(props: {
creationTime?: string | undefined
}) {
const { activityDerivedState, chainId, activityLinkUrl, disableMouseActions, creationTime } = props
const { id, isOrder, summary, order, enhancedTransaction, isCancelled, isExpired, isUnfillable, gnosisSafeInfo } =
const { id, isOrder, summary, order, enhancedTransaction, isCancelled, isExpired, isUnfillable } =
activityDerivedState
const approvalToken = useToken(enhancedTransaction?.approval?.tokenAddress) || null

Expand Down Expand Up @@ -249,18 +302,7 @@ export function ActivityDetails(props: {

{isUnfillable && unfillableAlert()}

{/*
TODO: Load gnosisSafeThreshold (not default!)
`enhancedTransaction` currently returns undefined (no data yet!)
for regular orders done with a Safe. Only works for token approvals with a Safe.
*/}
{gnosisSafeInfo && enhancedTransaction?.safeTransaction && (
<GnosisSafeTxDetails
chainId={chainId}
enhancedTransaction={enhancedTransaction}
gnosisSafeThreshold={gnosisSafeInfo.threshold}
/>
)}
<GnosisSafeTxDetails chainId={chainId} activityDerivedState={activityDerivedState} />
</SummaryInner>
</Summary>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,21 @@ import OrderOpenImage from 'assets/cow-swap/order-open.svg'
import { StatusLabel, StatusLabelWrapper, StatusLabelBelow } from './styled'
import { ActivityDerivedState, determinePillColour } from './index'
import { CancellationModal } from './CancelationModal'
import { EnhancedTransactionDetails } from 'state/enhancedTransactions/reducer'
import { getSafeWebUrl } from 'api/gnosisSafe'
import { SafeMultisigTransactionResponse } from '@gnosis.pm/safe-service-client'

export function GnosisSafeLink(props: {
chainId: number
enhancedTransaction: EnhancedTransactionDetails | null
safeTransaction?: SafeMultisigTransactionResponse
gnosisSafeThreshold: number
}): JSX.Element | null {
const { chainId, enhancedTransaction } = props
const { chainId, safeTransaction } = props

if (!enhancedTransaction?.safeTransaction) {
if (!safeTransaction) {
return null
}

const { safe } = enhancedTransaction.safeTransaction
const { safe } = safeTransaction
const safeUrl = getSafeWebUrl(chainId, safe)

// Only show the link to the safe, if we have the "safeUrl"
Expand Down
13 changes: 8 additions & 5 deletions src/custom/components/AccountDetails/Transaction/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ export const SummaryInner = styled.div`
margin: 16px 0 0;
width: 100%;
display: grid;
grid-template-columns: fit-content(100%) fit-content(100%);
grid-template-columns: 1fr;
grid-gap: 0 18px;
justify-items: flex-start;
align-items: flex-start;
Expand Down Expand Up @@ -438,13 +438,16 @@ export const TransactionInnerDetail = styled.div`
}
`

export const TextAlert = styled.div<{ isPending: boolean }>`
background: ${({ isPending }) => (isPending ? 'rgb(255 87 34 / 15%)' : 'rgb(0 216 151 / 15%)')};
margin: 6px 0 3px;
export const TextAlert = styled.div<{ isPending: boolean; isExpired: boolean; isCancelled: boolean }>`
background: ${({ theme, isPending }) =>
isPending ? transparentize(0.85, theme.attention) : transparentize(0.85, theme.success)};
margin: 6px 0 16px;
padding: 8px 12px;
color: ${({ isPending }) => (isPending ? '#ff5722' : '#00d897')};
color: ${({ theme, isPending }) => (isPending ? theme.attention : theme.success)};
text-decoration: ${({ isExpired, isCancelled }) => (isExpired || isCancelled) && 'line-through'};
border-radius: 8px;
text-align: center;
font-weight: 600;
`

export const CreationDateText = styled.div`
Expand Down
25 changes: 5 additions & 20 deletions src/custom/components/AccountDetails/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ export const Wrapper = styled.div`
padding: 0;
height: 100%;
${({ theme }) => theme.mediaWidth.upToMedium`padding: 12px 0 0;`};
${({ theme }) => theme.mediaWidth.upToMedium`
padding: 12px 0 0;
`};
${WalletName},
${AddressLink},
Expand Down Expand Up @@ -249,34 +251,17 @@ const NetworkCardUni = styled(YellowCard)`
`};
`

// export const NetworkCard = styled(NetworkCardUni)`
// background-color: ${({ theme }) => theme.networkCard.background};
// color: ${({ theme }) => theme.networkCard.text};

// padding: 6px 8px;
// font-size: 13px;
// margin: 0 8px 0 0;
// letter-spacing: 0.7px;

// ${({ theme }) => theme.mediaWidth.upToSmall`
// flex-shrink: 0;
// `};
// `

export const NetworkCard = styled(NetworkCardUni)`
background-color: ${({ theme }) => theme.networkCard.background};
color: ${({ theme }) => theme.networkCard.text};
padding: 6px 8px;
font-size: 13px;
margin: 0 8px 0 0;
letter-spacing: 0.7px;
/* width: auto; */
min-width: initial;
flex: 0 0 fit-content;
${({ theme }) => theme.mediaWidth.upToSmall`
flex-shrink: 0;
// margin: 12px auto 0;
// order: 1;
margin: 0 auto 12px;
`};
`

0 comments on commit 2218878

Please sign in to comment.