-
Notifications
You must be signed in to change notification settings - Fork 8
Adding Competition Solver tab to settlements page #590
Changes from all commits
b67c3b1
c0c8fdf
27605de
b083b62
439a82b
1b938a4
1dad41b
857783f
63c6676
56f76c6
d655359
616ebae
84eae43
a9d0509
e450c8a
5d6362a
08bb57e
a5efe4a
9647448
20685c5
3a26f19
4640729
4ff36d0
4b87d3c
3782e0b
8b22c10
0a2da0b
5f05d1b
ef5ceca
9594f68
657e099
7a3a8bb
2a761b6
6d9e2e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,7 +2,16 @@ import { Network } from 'types' | |
import { buildSearchString } from 'utils/url' | ||
import { isProd, isStaging } from 'utils/env' | ||
|
||
import { GetOrderParams, GetOrdersParams, RawOrder, RawTrade, GetTxOrdersParams, WithNetworkId } from './types' | ||
import { | ||
GetOrderParams, | ||
GetOrdersParams, | ||
RawOrder, | ||
RawTrade, | ||
GetTxOrdersParams, | ||
WithNetworkId, | ||
GetTxSolverCompetitionParams, | ||
RawSolverCompetition, | ||
} from './types' | ||
import { fetchQuery } from 'api/baseApi' | ||
import { orderBookSDK } from 'cowSdk' | ||
import { Address, UID } from '@cowprotocol/cow-sdk' | ||
|
@@ -150,6 +159,24 @@ export async function getTrades( | |
return [...trades[0], ...trades[1]] | ||
} | ||
|
||
/** | ||
* Gets information about solver competition By Transaction Hash | ||
* Required params: | ||
* - txHash: string | ||
* | ||
*/ | ||
export async function getSolverCompetitionByTx(params: GetTxSolverCompetitionParams): Promise<RawSolverCompetition> { | ||
const { networkId, txHash } = params | ||
|
||
console.log( | ||
`[getSolverCompetitionByTx] Fetching Solver Competition on network ${networkId} with filters: tx_hash=${txHash}`, | ||
) | ||
|
||
const queryString = '/solver_competition/by_tx_hash/' + txHash | ||
|
||
return _fetchQuery(networkId, queryString) | ||
} | ||
Comment on lines
+168
to
+178
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This unfortunately doesn't work with See for example this goerli batch It returns a 404 for barn while it has the proper response on prod But I think you'd be aware of that as it for sure happened while developing/testing. Long story short, there are 2 databases, and we usually query the one corresponding to the loaded environment. https://github.com/cowprotocol/explorer/blob/develop/src/api/operator/operatorApi.ts#L104-L119 Also, this endpoint should be moved to the https://github.com/cowprotocol/cow-sdk/. I'll raise this internally and see that we include it in the next release. No action from your part on this regard, just mentioning it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Upon further investigation, it seems that even batches which were made against Looks like it's something on the backend side. A quick fix would be to always query I'll reach out internally about this as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is odd. The same query now is returning values properly o.O There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got an answer that clarifies why it suddenly became available.
I suggest you to watch for the current block and compare with the tx block. |
||
|
||
function _fetchQuery<T>(networkId: Network, queryString: string): Promise<T> | ||
function _fetchQuery<T>(networkId: Network, queryString: string, nullOn404: true): Promise<T | null> | ||
function _fetchQuery<T>(networkId: Network, queryString: string, nullOn404?: boolean): Promise<T | null> { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,11 @@ import { | |
GetTradesParams, | ||
RawOrder, | ||
RawTrade, | ||
GetTxSolverCompetitionParams, | ||
RawSolverCompetition, | ||
} from './types' | ||
|
||
import { RAW_ORDER, RAW_TRADE } from '../../../test/data' | ||
import { RAW_ORDER, RAW_SOLVER_COMPETITION, RAW_TRADE } from '../../../test/data' | ||
import { GetAccountOrdersResponse } from './accountOrderUtils' | ||
|
||
export async function getOrder(params: GetOrderParams): Promise<RawOrder> { | ||
|
@@ -57,3 +59,11 @@ export async function getTrades(params: GetTradesParams): Promise<RawTrade[]> { | |
|
||
return [trade] | ||
} | ||
|
||
export async function getSolverCompetitionByTx(params: GetTxSolverCompetitionParams): Promise<RawSolverCompetition[]> { | ||
const { txHash } = params | ||
const solverCompetition = { ...RAW_SOLVER_COMPETITION } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: return [{
...RAW_SOLVER_COMPETITION,
transactionHash: txHash || solverCompetition.transactionHash
}] |
||
solverCompetition.transactionHash = txHash || solverCompetition.transactionHash | ||
|
||
return [solverCompetition] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import React, { useCallback, useEffect, useState } from 'react' | ||
import { faListUl, faProjectDiagram } from '@fortawesome/free-solid-svg-icons' | ||
import { faListUl, faProjectDiagram, faHandshakeAngle } from '@fortawesome/free-solid-svg-icons' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @fairlighteth any suggestion for the tab icon? |
||
|
||
import { useQuery, useUpdateQueryString } from 'hooks/useQuery' | ||
import { BlockchainNetwork, TransactionsTableContext } from './context/TransactionsTableContext' | ||
|
@@ -17,6 +17,7 @@ import { Notification } from 'components/Notification' | |
import { TransactionBatchGraph } from 'apps/explorer/components/TransanctionBatchGraph' | ||
import CowLoading from 'components/common/CowLoading' | ||
import { TAB_QUERY_PARAM_KEY } from 'apps/explorer/const' | ||
import { SolverCompetition } from 'components/transaction/SolverCompetition' | ||
|
||
interface Props { | ||
txHash: string | ||
|
@@ -27,6 +28,7 @@ interface Props { | |
enum TabView { | ||
ORDERS = 1, | ||
GRAPH, | ||
SOLVER = 3, | ||
} | ||
|
||
const DEFAULT_TAB = TabView[1] | ||
|
@@ -48,6 +50,11 @@ const tabItems = (orders: Order[] | undefined, networkId: BlockchainNetwork, txH | |
tab: <TabIcon title="Graph" iconFontName={faProjectDiagram} />, | ||
content: <TransactionBatchGraph orders={orders} networkId={networkId} txHash={txHash} />, | ||
}, | ||
{ | ||
id: TabView.SOLVER, | ||
tab: <TabIcon title="Solver Competition" iconFontName={faHandshakeAngle} />, | ||
content: <SolverCompetition orders={orders} networkId={networkId} txHash={txHash} />, | ||
}, | ||
] | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import React, { useState } from 'react' | ||
import { Avatar } from '@material-ui/core' | ||
|
||
type BoringAvatarProps = { | ||
alt?: string | ||
} | ||
const BoringAvatar: React.FC<BoringAvatarProps> = ({ alt }) => { | ||
const [colors] = useState<string[]>( | ||
Array.from({ length: 6 }, () => Math.floor(Math.random() * 16777215).toString(16)), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why this random logic? also, nit, since you are creating a component call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Was getting a lot of close colors avatars without it. |
||
) | ||
return <Avatar alt={alt} src={`https://source.boringavatars.com/pixel/120/${alt}?colors=${colors.join(',')}`} /> | ||
} | ||
export default BoringAvatar | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: I would avoid default export. With named one is enough There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import React, { useState } from 'react' | ||
import { useNetworkId } from 'state/network' | ||
import { EmptyItemWrapper } from 'components/common/StyledUserDetailsTable' | ||
import { PricesCard } from 'components/transaction/SolverCompetition/styled' | ||
import { formatSmart, safeTokenName, TokenErc20 } from '@gnosis.pm/dex-js' | ||
import { Network } from 'types' | ||
import TokenImg from 'components/common/TokenImg' | ||
import { HIGH_PRECISION_SMALL_LIMIT, NO_ADJUSTMENT_NEEDED_PRECISION } from 'apps/explorer/const' | ||
import { getImageAddress } from 'utils' | ||
import { invertPrice } from '@gnosis.pm/dex-js/build-esm/utils/price' | ||
import Icon from 'components/Icon' | ||
import { faExchangeAlt } from '@fortawesome/free-solid-svg-icons' | ||
import BigNumber from 'bignumber.js' | ||
import { NATIVE_TOKEN_PER_NETWORK, TEN_BIG_NUMBER } from 'const' | ||
import { Order } from 'api/operator' | ||
import { AuctionPrices } from '@cowprotocol/cow-sdk' | ||
|
||
type Props = { | ||
orders: Order[] | ||
prices: AuctionPrices | ||
} | ||
|
||
type ItemProps = { | ||
token: TokenErc20 | ||
amount: BigNumber | ||
network: Network | ||
} | ||
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type | ||
const Item: React.FC<ItemProps> = (props) => { | ||
const { token, network, amount } = props | ||
|
||
const [invertedPrice, setInvertedPrice] = useState<boolean>(false) | ||
console.log(token, amount.toNumber()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. console.log should be removed |
||
const calculatedPrice = amount.div(TEN_BIG_NUMBER.exponentiatedBy(36 - token.decimals.valueOf())) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is 36? Would be great to move it to a const with an appropriate name + comment |
||
const displayPrice = (invertedPrice ? invertPrice(calculatedPrice) : calculatedPrice).toString(10) | ||
const formattedPrice = formatSmart({ | ||
amount: displayPrice, | ||
precision: NO_ADJUSTMENT_NEEDED_PRECISION, | ||
smallLimit: HIGH_PRECISION_SMALL_LIMIT, | ||
decimals: 6, | ||
isLocaleAware: false, | ||
}) | ||
|
||
const tokenImage = getImageAddress(token?.address ?? '', network) | ||
const tokenSymbol = token && safeTokenName(token) | ||
|
||
const tokenNames = !invertedPrice | ||
? [tokenSymbol, NATIVE_TOKEN_PER_NETWORK[network].symbol] | ||
: [NATIVE_TOKEN_PER_NETWORK[network].symbol, tokenSymbol] | ||
return ( | ||
<div key={token?.address}> | ||
<TokenImg address={tokenImage} /> | ||
{`1 ${tokenNames[0]}`} = {formattedPrice} {`${tokenNames[1]}`} | ||
{<Icon icon={faExchangeAlt} onClick={(): void => setInvertedPrice(!invertedPrice)} />} | ||
</div> | ||
) | ||
} | ||
|
||
const ClearingPrices: React.FC<Props> = (props) => { | ||
const { orders, prices } = props | ||
const networkId = useNetworkId() ?? undefined | ||
const tokens: { [p: string]: TokenErc20 | null | undefined } = Object.assign( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be meoized? |
||
{}, | ||
...orders.map((o): { [p: string]: TokenErc20 | null | undefined } => ({ | ||
[o.buyTokenAddress]: o.buyToken, | ||
[o.sellTokenAddress]: o.sellToken, | ||
})), | ||
) | ||
console.log(tokens) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. delete console logs |
||
if (!networkId) { | ||
return <EmptyItemWrapper>{'Can't load details'}</EmptyItemWrapper> | ||
} | ||
return ( | ||
<PricesCard> | ||
{Object.values(tokens).map((token, key) => { | ||
return ( | ||
<>{token && <Item key={key} token={token} amount={BigNumber(prices[token.address])} network={networkId} />}</> | ||
) | ||
})} | ||
</PricesCard> | ||
) | ||
} | ||
export default ClearingPrices | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please, use named exports instead of default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed, this endpoint is available from
orderBookSDK
since version https://github.com/cowprotocol/cow-sdk/releases/tag/v2.3.0Update to the latest and you can use it directly.
You will still HAVE TO query both
barn
andprod
envs, like it's done here: https://github.com/cowprotocol/explorer/blob/develop/src/api/operator/operatorApi.ts#L104-L119