Skip to content
This repository has been archived by the owner on Sep 29, 2023. It is now read-only.

Commit

Permalink
Merge pull request #58 from brave/compat
Browse files Browse the repository at this point in the history
Compatibility fixes and spot prices optimisation
  • Loading branch information
onyb authored Oct 12, 2022
2 parents 79de805 + c8246e0 commit e098f4a
Show file tree
Hide file tree
Showing 14 changed files with 201 additions and 287 deletions.
4 changes: 2 additions & 2 deletions interface/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion interface/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@brave/swap-interface",
"version": "0.3.0",
"version": "0.4.0",
"description": "Brave Swap - an open-source swap interface by Brave, focussed on usability and multi-chain support.",
"type": "module",
"license": "MPL-2.0",
Expand Down
6 changes: 5 additions & 1 deletion interface/src/components/swap/header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { Row, HorizontalSpacer } from '~/components/shared.styles'
export const Header = () => {
// Wallet State
const { state } = useWalletState()
const { selectedNetwork, isNetworkSupported } = state
const { selectedNetwork, supportedNetworks } = state

// Dispatch
const { dispatch } = useWalletDispatch()
Expand Down Expand Up @@ -91,6 +91,10 @@ export const Header = () => {
showNetworkSelector
)

const isNetworkSupported = React.useMemo(() => {
return supportedNetworks.some((network) => network.chainId === selectedNetwork?.chainId)
}, [selectedNetwork, supportedNetworks])

return (
<Wrapper>
<BraveLogo />
Expand Down
11 changes: 6 additions & 5 deletions interface/src/components/swap/quote-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const QuoteInfo = (props: Props) => {

// Wallet State
const { state } = useWalletState()
const { tokenSpotPrices, selectedNetwork } = state
const { spotPrices, selectedNetwork } = state

// Memos
const swapRate: string = React.useMemo(() => {
Expand All @@ -70,19 +70,20 @@ export const QuoteInfo = (props: Props) => {
if (
fromToken !== undefined &&
toToken !== undefined &&
tokenSpotPrices &&
spotPrices.makerAsset &&
spotPrices.takerAsset &&
selectedQuoteOption !== undefined
) {
const fromTokenPrice = tokenSpotPrices[fromToken.contractAddress]
const toTokenPrice = tokenSpotPrices[toToken.contractAddress]
const fromTokenPrice = spotPrices.makerAsset
const toTokenPrice = spotPrices.takerAsset
const coinGeckoRate = Number(toTokenPrice) / Number(fromTokenPrice)
const coinGeckoMinimumReceived = Number(toAmount) * coinGeckoRate
const impact =
selectedQuoteOption.toAmount.toNumber() / coinGeckoMinimumReceived
return impact.toFixed(2)
}
return ''
}, [tokenSpotPrices, fromToken, toToken, selectedQuoteOption, toAmount])
}, [spotPrices, fromToken, toToken, selectedQuoteOption, toAmount])

const swapImpact: string = React.useMemo(() => {
if (selectedQuoteOption === undefined) {
Expand Down
40 changes: 21 additions & 19 deletions interface/src/constants/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,16 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// you can obtain one at http://mozilla.org/MPL/2.0/.

import Amount from "~/utils/amount";
import Amount from '~/utils/amount'

export type BlockchainToken = {
contractAddress: string
name: string
logo: string
isErc20: boolean
isErc721: boolean
isToken: boolean
visible: boolean
decimals: number
symbol: string
tokenId: string
coingeckoId: string
chainId: string
coin: number
Expand Down Expand Up @@ -59,6 +57,12 @@ export type QuoteOption = {

export type Registry = Record<string, string>

export type SpotPrices = {
nativeAsset: string
makerAsset: string
takerAsset: string
}

export type WalletAccount = {
id: string
name: string
Expand Down Expand Up @@ -105,17 +109,15 @@ export type GasEstimate = {
time?: string
}

export type AmountValidationErrorType =
| 'fromAmountDecimalsOverflow'
| 'toAmountDecimalsOverflow'
export type AmountValidationErrorType = 'fromAmountDecimalsOverflow' | 'toAmountDecimalsOverflow'

export type SwapValidationErrorType =
| AmountValidationErrorType
| 'insufficientBalance'
| 'insufficientFundsForGas'
| 'insufficientAllowance'
| 'insufficientLiquidity'
| 'unknownError'
| AmountValidationErrorType
| 'insufficientBalance'
| 'insufficientFundsForGas'
| 'insufficientAllowance'
| 'insufficientLiquidity'
| 'unknownError'

export type SwapParams = {
fromToken?: BlockchainToken
Expand Down Expand Up @@ -169,7 +171,7 @@ export interface ZeroExSwapResponse extends ZeroExQuoteResponse {
export interface ZeroExErrorResponse {
code: number
reason: string
validationErrors?: Array<{ field: string, code: number, reason: string }>
validationErrors?: Array<{ field: string; code: number; reason: string }>
}

export type JupiterQuoteParams = {
Expand Down Expand Up @@ -232,11 +234,11 @@ export interface JupiterErrorResponse {

// ETH Wallet Adapter
export type GasPrice1559 = {
slowMaxPriorityFeePerGas: string,
slowMaxPriorityFeePerGas: string
slowMaxFeePerGas: string
avgMaxPriorityFeePerGas: string,
avgMaxPriorityFeePerGas: string
avgMaxFeePerGas: string
fastMaxPriorityFeePerGas: string,
fastMaxPriorityFeePerGas: string
fastMaxFeePerGas: string
baseFeePerGas: string
}
Expand Down Expand Up @@ -266,8 +268,8 @@ export type SOLSendTransactionParams = {
encodedTransaction: string
from: string
sendOptions?: {
maxRetries?: number,
preflightCommitment?: string,
maxRetries?: number
preflightCommitment?: string
skipPreflight?: boolean
}
}
12 changes: 7 additions & 5 deletions interface/src/context/swap.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ import {
interface SwapContextInterface {
getLocale: (key: string) => string
getBalance: (address: string, coin: number, chainId: string) => Promise<string>
getTokenBalance: (contractAddress: string, address: string, chainId: string) => Promise<string>
getAllTokens: (
chainId: string,
coin: number
) => Promise<BlockchainToken[]>
getTokenBalance: (
contractAddress: string,
address: string,
coin: number,
chainId: string
) => Promise<string>
getAllTokens: (chainId: string, coin: number) => Promise<BlockchainToken[]>
getSelectedAccount: () => Promise<WalletAccount>
getSelectedNetwork: () => Promise<NetworkInfo>
getSupportedNetworks: () => Promise<NetworkInfo[]>
Expand Down
10 changes: 7 additions & 3 deletions interface/src/hooks/useNetworkFees.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,23 @@ import { NetworkInfo } from '~/constants/types'
export const useNetworkFees = () => {
// Wallet State
const {
state: { tokenSpotPrices, networkFeeEstimates, defaultBaseCurrency }
state: { spotPrices, networkFeeEstimates, defaultBaseCurrency }
} = useWalletState()

const getNetworkFeeFiatEstimate = React.useCallback(
(network: NetworkInfo) => {
if (!networkFeeEstimates[network.chainId]) {
return ''
}
return new Amount(tokenSpotPrices[network.symbol])
if (spotPrices.nativeAsset === '') {
return ''
}

return new Amount(spotPrices.nativeAsset)
.times(networkFeeEstimates[network.chainId].gasFee)
.formatAsFiat(defaultBaseCurrency)
},
[tokenSpotPrices, networkFeeEstimates, defaultBaseCurrency]
[spotPrices, networkFeeEstimates, defaultBaseCurrency]
)

return {
Expand Down
48 changes: 38 additions & 10 deletions interface/src/hooks/useSwap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { SwapAndSendOptions } from '~/options/select-and-send-options'
import { gasFeeOptions } from '~/options/gas-fee-options'

// Hooks
import { useWalletState } from '~/state/wallet'
import { useWalletDispatch, useWalletState } from '~/state/wallet'
import { useJupiter } from './useJupiter'
import { useZeroEx } from './useZeroEx'
import { useSwapContext } from '~/context/swap.context'
Expand Down Expand Up @@ -54,13 +54,12 @@ export const useSwap = () => {
selectedNetwork,
selectedAccount,
defaultBaseCurrency,
isConnected
isConnected,
spotPrices
}
} = useWalletState()
const { getLocale } = useSwapContext()

// ToDo: Setup useSwap hook where all this kind of state will be handled.
const price = 1519.28
const { getLocale, getTokenPrice } = useSwapContext()
const { dispatch } = useWalletDispatch()

// State
const [fromToken, setFromToken] = React.useState<BlockchainToken | undefined>(undefined)
Expand Down Expand Up @@ -216,6 +215,28 @@ export const useSwap = () => {
[quoteOptions, jupiter.quote, zeroEx.quote, selectedNetwork]
)

const refreshMakerAssetSpotPrice = React.useCallback(
async (token: BlockchainToken) => {
const price = await getTokenPrice(token.isToken ? token.contractAddress : token.symbol)
dispatch({
type: 'updateSpotPrices',
payload: token.isToken ? { makerAsset: price } : { makerAsset: price, nativeAsset: price }
})
},
[getTokenPrice]
)

const refreshTakerAssetSpotPrice = React.useCallback(
async (token: BlockchainToken) => {
const price = await getTokenPrice(token.isToken ? token.contractAddress : token.symbol)
dispatch({
type: 'updateSpotPrices',
payload: token.isToken ? { takerAsset: price } : { takerAsset: price, nativeAsset: price }
})
},
[getTokenPrice]
)

// Methods
const handleJupiterQuoteRefresh = React.useCallback(
async (overrides: Partial<SwapParams>) => {
Expand Down Expand Up @@ -307,14 +328,19 @@ export const useSwap = () => {

const onClickFlipSwapTokens = React.useCallback(async () => {
setFromToken(toToken)
toToken && (await refreshMakerAssetSpotPrice(toToken))

setToToken(fromToken)
fromToken && (await refreshTakerAssetSpotPrice(fromToken))

await handleOnSetFromAmount('')
}, [fromToken, toToken, handleOnSetFromAmount])

const onSelectToToken = React.useCallback(
async (token: BlockchainToken) => {
setToToken(token)
setSelectingFromOrTo(undefined)
await refreshTakerAssetSpotPrice(token)

if (selectedNetwork?.coin === CoinType.Solana) {
await handleJupiterQuoteRefresh({
Expand All @@ -334,6 +360,7 @@ export const useSwap = () => {
async (token: BlockchainToken) => {
setFromToken(token)
setSelectingFromOrTo(undefined)
await refreshMakerAssetSpotPrice(token)

if (selectedNetwork?.coin === CoinType.Solana) {
await handleJupiterQuoteRefresh({
Expand Down Expand Up @@ -376,11 +403,12 @@ export const useSwap = () => {
}, [fromToken, tokenBalances, isConnected, getTokenBalance])

const fiatValue: string | undefined = React.useMemo(() => {
if (fromAmount && price) {
return new Amount(fromAmount).times(price).formatAsFiat(defaultBaseCurrency)
if (fromAmount && spotPrices.makerAsset) {
return new Amount(fromAmount).times(spotPrices.makerAsset).formatAsFiat(defaultBaseCurrency)
}
}, [price, fromAmount, defaultBaseCurrency])
}, [spotPrices.makerAsset, fromAmount, defaultBaseCurrency])

// FIXME - replace with swapValidationError
const insufficientBalance: boolean = React.useMemo(() => {
if (fromAmount && fromTokenBalance !== undefined) {
return Number(fromAmount) > fromTokenBalance
Expand Down Expand Up @@ -471,7 +499,7 @@ export const useSwap = () => {

// 0x specific validations
if (selectedNetwork.coin === CoinType.Ethereum) {
if (fromToken.isErc20 && !zeroEx.hasAllowance) {
if (fromToken.isToken && !zeroEx.hasAllowance) {
return 'insufficientAllowance'
}

Expand Down
Loading

0 comments on commit e098f4a

Please sign in to comment.