Skip to content
This repository was archived by the owner on Feb 2, 2024. It is now read-only.

Commit

Permalink
feat(batch-graph): special addresses (#508)
Browse files Browse the repository at this point in the history
* feat: add node type Special

* feat: add 2 special addresses

* feat: classify special nodes

* feat: styling for special nodes

* fix: fix css

* feat: make CoW Protocol Buffer node clickable

* refactor: move SPECIAL_ADDRESSES to constants file
  • Loading branch information
alfetopito authored Jun 12, 2023
1 parent a0caab5 commit e5c3a86
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 31 deletions.
13 changes: 11 additions & 2 deletions src/api/tenderly/tenderlyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
TxTradesAndTransfers,
} from './types'
import { abbreviateString } from 'utils'
import { SPECIAL_ADDRESSES } from 'apps/explorer/const'

export const ALIAS_TRADER_NAME = 'Trader'
const COW_PROTOCOL_CONTRACT_NAME = 'GPv2Settlement'
Expand Down Expand Up @@ -155,7 +156,7 @@ export function accountAddressesInvolved(
// See https://github.com/cowprotocol/explorer/issues/491
if (!result.has(trade.owner)) {
result.set(trade.owner, {
alias: ALIAS_TRADER_NAME,
alias: getAliasFromAddress(trade.owner),
address: trade.owner,
})
}
Expand All @@ -168,7 +169,7 @@ export function accountAddressesInvolved(
.forEach((address) => {
if (!result.get(address)) {
result.set(address, {
alias: abbreviateString(address, 6, 4),
alias: getAliasFromAddress(address, true),
address,
})
}
Expand All @@ -186,3 +187,11 @@ function _contractName(name: string): string {

return name
}

export function getAliasFromAddress(address: string, isUnknown = false): string {
const lowerCaseAddress = address.toLowerCase()

if (SPECIAL_ADDRESSES[lowerCaseAddress]) return SPECIAL_ADDRESSES[lowerCaseAddress]

return isUnknown ? abbreviateString(address, 6, 4) : ALIAS_TRADER_NAME
}
60 changes: 37 additions & 23 deletions src/apps/explorer/components/TransanctionBatchGraph/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Stylesheet } from 'cytoscape'
import styled, { DefaultTheme, css } from 'styled-components'

import TraderIcon from 'assets/img/Trader.svg'
import SpecialIcon from 'assets/img/Trader-variant.svg'
import CowProtocolIcon from 'assets/img/CoW-protocol.svg'
import DexIcon from 'assets/img/Dex.svg'
import { MEDIA } from 'const'
Expand Down Expand Up @@ -45,40 +46,45 @@ const FloatingButton = css`
}
`
export const ResetButton = styled.button`
${FloatingButton}
min-width: 6.586rem;
transition: all 0.2s ease-in-out;
${FloatingButton} {
min-width: 6.586rem;
transition: all 0.2s ease-in-out;
}
`
export const LayoutButton = styled.span`
${FloatingButton}
display: flex;
color: ${({ theme }): string => theme.textPrimary1};
font-size: ${({ theme }): string => theme.fontSizeDefault};
font-weight: normal;
white-space: nowrap;
align-items: center;
padding: 0 0.6rem 0 0.6rem;
${FloatingButton} {
display: flex;
color: ${({ theme }): string => theme.textPrimary1};
font-size: ${({ theme }): string => theme.fontSizeDefault};
font-weight: normal;
white-space: nowrap;
align-items: center;
padding: 0 0.6rem 0 0.6rem;
}
`

export const DropdownWrapper = styled(Dropdown)`
&.dropdown-container {
${ArrowIconCSS}
width: 100%;
height: 100%;
display: flex;
align-items: center;
& div:first-child {
${ArrowIconCSS} {
width: 100%;
height: 100%;
display: flex;
align-items: center;
gap: 0.6rem;
@media ${MEDIA.mediumDown} {
justify-content: center;
& div:first-child {
width: 100%;
height: 100%;
display: flex;
align-items: center;
gap: 0.6rem;
@media ${MEDIA.mediumDown} {
justify-content: center;
}
}
> .dropdown-options {
min-width: 7rem;
}
}
> .dropdown-options {
min-width: 7rem;
}
}
`
Expand Down Expand Up @@ -178,6 +184,14 @@ export function STYLESHEET(theme: DefaultTheme): Stylesheet[] {
'text-margin-y': 8,
},
},
{
selector: 'node[type="special"]',
style: {
'background-image': `url(${SpecialIcon})`,
'text-valign': 'bottom',
'text-margin-y': 8,
},
},
{
selector: 'node[type="dex"]',
style: {
Expand Down
2 changes: 2 additions & 0 deletions src/apps/explorer/components/TransanctionBatchGraph/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export enum TypeNodeOnTx {
CowProtocol = 'cowProtocol',
Trader = 'trader',
Dex = 'dex',
Special = 'special',
}

export enum TypeEdgeOnTx {
Expand All @@ -21,3 +22,4 @@ export type Node =
| NodeType<TypeNodeOnTx.CowProtocol, Account>
| NodeType<TypeNodeOnTx.Trader, Account>
| NodeType<TypeNodeOnTx.Dex, Account>
| NodeType<TypeNodeOnTx.Special, Account>
15 changes: 11 additions & 4 deletions src/apps/explorer/components/TransanctionBatchGraph/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@ import { Settlement as TxSettlement } from 'hooks/useTxBatchTrades'
import { Network } from 'types'
import { networkOptions } from 'components/NetworkSelector'
import ElementsBuilder, { buildGridLayout } from 'apps/explorer/components/TransanctionBatchGraph/elementsBuilder'
import { TOKEN_SYMBOL_UNKNOWN } from 'apps/explorer/const'
import { SPECIAL_ADDRESSES, TOKEN_SYMBOL_UNKNOWN } from 'apps/explorer/const'
import BigNumber from 'bignumber.js'
import { APP_NAME } from 'const'
import { getExplorerUrl } from 'utils/getExplorerUrl'

const PROTOCOL_NAME = APP_NAME
const INTERNAL_NODE_NAME = `${APP_NAME} Buffer`
Expand Down Expand Up @@ -105,7 +106,9 @@ export const removePopper = (popperInstance: React.MutableRefObject<PopperInstan
popperInstance.current?.destroy()

function getTypeNode(account: Account & { owner?: string }): TypeNodeOnTx {
if (account.alias === ALIAS_TRADER_NAME || account.owner) {
if (account.address && SPECIAL_ADDRESSES[account.address]) {
return TypeNodeOnTx.Special
} else if (account.alias === ALIAS_TRADER_NAME || account.owner) {
return TypeNodeOnTx.Trader
} else if (account.alias === PROTOCOL_NAME) {
return TypeNodeOnTx.CowProtocol
Expand Down Expand Up @@ -210,9 +213,13 @@ export function getNodes(
// Set flag to prevent creating more
internalNodeCreated = true

const account = { alias: fromId }
const account = { alias: fromId, href: getExplorerUrl(networkId, 'address', transfer.from) }
builder.node(
{ type: TypeNodeOnTx.Trader, entity: account, id: fromId },
{
type: TypeNodeOnTx.Special,
entity: account,
id: fromId,
},
// Put it inside the parent node
getInternalParentNode(groupNodes, transfer),
)
Expand Down
5 changes: 5 additions & 0 deletions src/apps/explorer/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,8 @@ export const COWWIKI_LINK = 'https://en.wikipedia.org/wiki/Coincidence_of_wants'
export const GNOSIS_FORUM_ROADTODECENT_LINK = 'https://forum.gnosis.io/t/gpv2-road-to-decentralization/1245'

export const APP_TITLE = 'CoW Protocol Explorer'

export const SPECIAL_ADDRESSES = {
'0xa03be496e67ec29bc62f01a428683d7f9c204930': 'Solver Rewards Safe',
'0xca771eda0c70aa7d053ab1b25004559b918fe662': 'CoW DAO',
}
4 changes: 2 additions & 2 deletions src/hooks/useTxBatchTrades.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState, useCallback, useEffect } from 'react'

import { Network } from 'types'
import { getTradesAccount, getTradesAndTransfers, Trade, Transfer, Account, ALIAS_TRADER_NAME } from 'api/tenderly'
import { getTradesAccount, getTradesAndTransfers, Trade, Transfer, Account, getAliasFromAddress } from 'api/tenderly'
import { useMultipleErc20 } from './useErc20'
import { SingleErc20State } from 'state/erc20'
import { Order } from 'api/operator'
Expand Down Expand Up @@ -104,7 +104,7 @@ export function useTxBatchTrades(
filteredOrders?.forEach((order) => {
if (!(order.receiver in _accounts)) {
accountsWithReceiver[order.receiver] = {
alias: ALIAS_TRADER_NAME,
alias: getAliasFromAddress(order.receiver),
address: order.receiver,
}
}
Expand Down

0 comments on commit e5c3a86

Please sign in to comment.