Skip to content

Commit

Permalink
Merge branch 'main' of github.com:balancer/frontend-v3 into feat/cros…
Browse files Browse the repository at this point in the history
…s-chain-sync
  • Loading branch information
alter-eggo committed Oct 3, 2024
2 parents 76a0495 + 1a6ffc2 commit 78e5b3f
Show file tree
Hide file tree
Showing 24 changed files with 227 additions and 87 deletions.
1 change: 0 additions & 1 deletion .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ PRIVATE_HYPERNATIVE_API_SECRET=xxx
PRIVATE_CURRENCYAPI_KEY=xxx

# For integration tests and rpc proxy routes (optional)
NEXT_PRIVATE_ALCHEMY_KEY=xxx
NEXT_PRIVATE_DRPC_KEY=xxx

# Allow skip transaction (optional)
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ on:
env:
NEXT_PUBLIC_BALANCER_API_URL: https://api-v3.balancer.fi/graphql
NEXT_PUBLIC_WALLET_CONNECT_ID: ${{ secrets.NEXT_PUBLIC_WALLET_CONNECT_ID }}
NEXT_PRIVATE_ALCHEMY_KEY: ${{ secrets.PRIVATE_ALCHEMY_KEY }}
NEXT_PRIVATE_DRPC_KEY: ${{ secrets.PRIVATE_DRPC_KEY }}

jobs:
Expand Down Expand Up @@ -53,5 +52,7 @@ jobs:
uses: ./.github/actions/setup
- name: Set up foundry (includes anvil)
uses: foundry-rs/foundry-toolchain@v1
with:
cache: false
- name: Run integration tests
run: pnpm test:integration
4 changes: 2 additions & 2 deletions app/(app)/pools/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { Suspense } from 'react'
// import { getProjectConfig } from '@/lib/config/getProjectConfig'
// import { GetFeaturedPoolsDocument } from '@/lib/shared/services/api/generated/graphql'
// import { FeaturedPools } from '@/lib/modules/featured-pools/FeaturedPools'
import { CowGalxeQuestPromoBanner } from '@/lib/shared/components/promos/CowGalxeQuestPromoBanner'
import { CowPromoBanner } from '@/lib/shared/components/promos/CowPromoBanner'

export default async function PoolsPage() {
// Featured pools set up
Expand All @@ -33,7 +33,7 @@ export default async function PoolsPage() {
<DefaultPageContainer pt={['xl', '40px']} pb={['xl', '2xl']}>
<FadeInOnView animateOnce={false}>
<Box>
<CowGalxeQuestPromoBanner />
<CowPromoBanner />
</Box>
</FadeInOnView>
{/* <FadeInOnView animateOnce={false}>
Expand Down
32 changes: 14 additions & 18 deletions app/api/rpc/[chain]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,23 @@ type Params = {
}
}

const ALCHEMY_KEY = process.env.NEXT_PRIVATE_ALCHEMY_KEY || ''
const DRPC_KEY = process.env.NEXT_PRIVATE_DRPC_KEY || ''
const dRpcUrl = (chainName: string) =>
`https://lb.drpc.org/ogrpc?network=${chainName}&dkey=${DRPC_KEY}`

const chainToRpcMap: Record<GqlChain, string | undefined> = {
[GqlChain.Mainnet]: `https://eth-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Arbitrum]: `https://arb-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Optimism]: `https://opt-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Base]: `https://base-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Polygon]: `https://polygon-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Avalanche]: `https://avax-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Fantom]: `https://fantom-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Sepolia]: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Fraxtal]: `https://frax-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Gnosis]: `https://lb.drpc.org/ogrpc?network=gnosis&dkey=${DRPC_KEY}`,
[GqlChain.Mode]: undefined,
[GqlChain.Zkevm]: `https://polygonzkevm-mainnet.g.alchemy.com/v2/${ALCHEMY_KEY}`,
[GqlChain.Mainnet]: dRpcUrl('ethereum'),
[GqlChain.Arbitrum]: dRpcUrl('arbitrum'),
[GqlChain.Optimism]: dRpcUrl('optimism'),
[GqlChain.Base]: dRpcUrl('base'),
[GqlChain.Polygon]: dRpcUrl('polygon'),
[GqlChain.Avalanche]: dRpcUrl('avalanche'),
[GqlChain.Fantom]: dRpcUrl('fantom'),
[GqlChain.Sepolia]: dRpcUrl('sepolia'),
[GqlChain.Fraxtal]: dRpcUrl('fraxtal'),
[GqlChain.Gnosis]: dRpcUrl('gnosis'),
[GqlChain.Mode]: dRpcUrl('mode'),
[GqlChain.Zkevm]: dRpcUrl('polygon-zkevm'),
}

function getRpcUrl(chain: string) {
Expand All @@ -35,11 +36,6 @@ function getRpcUrl(chain: string) {
}

export async function POST(request: Request, { params: { chain } }: Params) {
if (!ALCHEMY_KEY) {
return new Response(JSON.stringify({ error: 'NEXT_PRIVATE_ALCHEMY_KEY is missing' }), {
status: 500,
})
}
if (!DRPC_KEY) {
return new Response(JSON.stringify({ error: 'NEXT_PRIVATE_DRPC_KEY is missing' }), {
status: 500,
Expand Down
4 changes: 2 additions & 2 deletions lib/modules/pool/actions/PoolActionsPriceImpactDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { NumberText } from '@/lib/shared/components/typography/NumberText'
import { fNum, bn } from '@/lib/shared/utils/numbers'
import { HStack, VStack, Text, Tooltip, Icon, Box, Skeleton } from '@chakra-ui/react'
import { usePriceImpact } from '@/lib/modules/price-impact/PriceImpactProvider'
import { useUserSettings } from '@/lib/modules/user/settings/UserSettingsProvider'
import { useCurrency } from '@/lib/shared/hooks/useCurrency'
import { usePool } from '../PoolProvider'
import { ArrowRight } from 'react-feather'
Expand All @@ -13,17 +12,18 @@ import { InfoIcon } from '@/lib/shared/components/icons/InfoIcon'
interface PoolActionsPriceImpactDetailsProps {
bptAmount: bigint | undefined
totalUSDValue: string
slippage: string
isAddLiquidity?: boolean
isLoading?: boolean
}

export function PoolActionsPriceImpactDetails({
bptAmount,
totalUSDValue,
slippage,
isAddLiquidity = false,
isLoading = false,
}: PoolActionsPriceImpactDetailsProps) {
const { slippage } = useUserSettings()
const { toCurrency } = useCurrency()
const { pool } = usePool()

Expand Down
13 changes: 11 additions & 2 deletions lib/modules/pool/actions/add-liquidity/AddLiquidityProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { HumanTokenAmountWithAddress } from '@/lib/modules/tokens/token.types'
import { isUnhandledAddPriceImpactError } from '@/lib/modules/price-impact/price-impact.utils'
import { useModalWithPoolRedirect } from '../../useModalWithPoolRedirect'
import { getPoolTokens } from '../../pool.helpers'
import { useUserSettings } from '@/lib/modules/user/settings/UserSettingsProvider'

export type UseAddLiquidityResponse = ReturnType<typeof _useAddLiquidity>
export const AddLiquidityContext = createContext<UseAddLiquidityResponse | null>(null)
Expand All @@ -39,12 +40,14 @@ export function _useAddLiquidity(urlTxHash?: Hash) {
const [acceptPoolRisks, setAcceptPoolRisks] = useState(false)
const [wethIsEth, setWethIsEth] = useState(false)
const [totalUSDValue, setTotalUSDValue] = useState('0')
const [proportionalSlippage, setProportionalSlippage] = useState<string>('0')

const { pool, refetch: refetchPool, isLoading } = usePool()
const { getToken, getNativeAssetToken, getWrappedNativeAssetToken, isLoadingTokenPrices } =
useTokens()
const { isConnected } = useUserAccount()
const { hasValidationErrors } = useTokenInputsValidation()
const { slippage: userSlippage } = useUserSettings()

const handler = useMemo(() => selectAddLiquidityHandler(pool), [pool.id, isLoading])

Expand All @@ -56,7 +59,8 @@ export function _useAddLiquidity(urlTxHash?: Hash) {
const chain = pool.chain
const nativeAsset = getNativeAssetToken(chain)
const wNativeAsset = getWrappedNativeAssetToken(chain)

const isForcedProportionalAdd = requiresProportionalInput(pool.type)
const slippage = isForcedProportionalAdd ? proportionalSlippage : userSlippage
const tokens = getPoolTokens(pool, getToken)

function setInitialHumanAmountsIn() {
Expand Down Expand Up @@ -115,6 +119,7 @@ export function _useAddLiquidity(urlTxHash?: Hash) {
handler,
humanAmountsIn,
simulationQuery,
slippage,
})
const transactionSteps = useTransactionSteps(steps, isLoadingSteps)

Expand All @@ -126,7 +131,7 @@ export function _useAddLiquidity(urlTxHash?: Hash) {
const hasQuoteContext = !!simulationQuery.data

async function refetchQuote() {
if (requiresProportionalInput(pool.type)) {
if (isForcedProportionalAdd) {
/*
This is the only edge-case where the SDK needs pool onchain data from the frontend
(calculateProportionalAmounts uses pool.dynamicData.totalShares in its parameters)
Expand Down Expand Up @@ -186,6 +191,10 @@ export function _useAddLiquidity(urlTxHash?: Hash) {
addLiquidityTxHash,
hasQuoteContext,
addLiquidityTxSuccess,
slippage,
proportionalSlippage,
isForcedProportionalAdd,
setProportionalSlippage,
refetchQuote,
setHumanAmountIn,
setHumanAmountsIn,
Expand Down
35 changes: 25 additions & 10 deletions lib/modules/pool/actions/add-liquidity/form/AddLiquidityForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ import { Address } from 'viem'
import { AddLiquidityModal } from '../modal/AddLiquidityModal'
import { useAddLiquidity } from '../AddLiquidityProvider'
import { bn, fNum } from '@/lib/shared/utils/numbers'
import { TransactionSettings } from '@/lib/modules/user/settings/TransactionSettings'
import {
ProportionalTransactionSettings,
TransactionSettings,
} from '@/lib/modules/user/settings/TransactionSettings'
import { TokenInputs } from './TokenInputs'
import { TokenInputsWithAddable } from './TokenInputsWithAddable'
import { usePool } from '../../../PoolProvider'
Expand Down Expand Up @@ -52,10 +55,10 @@ import { useTokens } from '@/lib/modules/tokens/TokensProvider'

// small wrapper to prevent out of context error
export function AddLiquidityForm() {
const { validTokens } = useAddLiquidity()
const { validTokens, proportionalSlippage } = useAddLiquidity()

return (
<TokenBalancesProvider extTokens={validTokens}>
<TokenBalancesProvider extTokens={validTokens} bufferPercentage={proportionalSlippage}>
<AddLiquidityMainForm />
</TokenBalancesProvider>
)
Expand All @@ -78,6 +81,9 @@ function AddLiquidityMainForm() {
nativeAsset,
wNativeAsset,
previewModalDisclosure,
proportionalSlippage,
slippage,
setProportionalSlippage,
} = useAddLiquidity()

const nextBtn = useRef(null)
Expand Down Expand Up @@ -144,26 +150,34 @@ function AddLiquidityMainForm() {
})
}

useEffect(() => {
if (addLiquidityTxHash) {
previewModalDisclosure.onOpen()
}
}, [addLiquidityTxHash])

function onModalClose() {
// restart polling for token prices when modal is closed again
startTokenPricePolling()

previewModalDisclosure.onClose()
}

useEffect(() => {
if (addLiquidityTxHash) {
previewModalDisclosure.onOpen()
}
}, [addLiquidityTxHash])

return (
<Box w="full" maxW="lg" mx="auto" pb="2xl">
<Card>
<CardHeader>
<HStack w="full" justify="space-between">
<span>Add liquidity</span>
<TransactionSettings size="sm" />
{requiresProportionalInput(pool.type) ? (
<ProportionalTransactionSettings
slippage={proportionalSlippage}
setSlippage={setProportionalSlippage}
size="sm"
/>
) : (
<TransactionSettings size="sm" />
)}
</HStack>
</CardHeader>
<VStack spacing="md" align="start" w="full">
Expand Down Expand Up @@ -204,6 +218,7 @@ function AddLiquidityMainForm() {
<PoolActionsPriceImpactDetails
totalUSDValue={totalUSDValue}
bptAmount={simulationQuery.data?.bptOut.amount}
slippage={slippage}
isAddLiquidity
isLoading={isFetching}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export function TokenInputsWithAddable({
<TokenInputs
tokenSelectDisclosureOpen={tokenSelectDisclosureOpen}
customSetAmountIn={setAmountIn}
></TokenInputs>
/>
</VStack>
)
}
14 changes: 9 additions & 5 deletions lib/modules/pool/actions/add-liquidity/form/useMaximumInputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useMemo, useState } from 'react'
import { usePool } from '../../../PoolProvider'
import { useAddLiquidity } from '../AddLiquidityProvider'
import { useTotalUsdValue } from '@/lib/modules/tokens/useTotalUsdValue'
import { TokenAmount } from '@/lib/modules/tokens/token.types'

export function useMaximumInputs() {
const { isConnected } = useUserAccount()
Expand All @@ -20,12 +21,15 @@ export function useMaximumInputs() {
const { isLoadingTokenPrices } = useTokens()
const [isMaximized, setIsMaximized] = useState(false)

// Depending on if the user is using WETH or ETH, we need to filter out the
// native asset or wrapped native asset.
const nativeAssetFilter = (balance: TokenAmount) =>
wethIsEth
? wNativeAsset && balance.address !== wNativeAsset.address
: nativeAsset && balance.address !== nativeAsset.address

const filteredBalances = useMemo(() => {
return balances.filter(balance =>
wethIsEth
? wNativeAsset && balance.address !== wNativeAsset.address
: nativeAsset && balance.address !== nativeAsset.address
)
return balances.filter(nativeAssetFilter)
}, [wethIsEth, isBalancesLoading])

function handleMaximizeUserAmounts() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
} from '../../LiquidityActionHelpers'
import { useAddLiquidity } from '../AddLiquidityProvider'
import { useTotalUsdValue } from '@/lib/modules/tokens/useTotalUsdValue'
import { HumanTokenAmountWithAddress } from '@/lib/modules/tokens/token.types'
import { HumanTokenAmountWithAddress, TokenAmount } from '@/lib/modules/tokens/token.types'
import { swapWrappedWithNative } from '@/lib/modules/tokens/token.helpers'

type OptimalToken = {
Expand All @@ -42,13 +42,16 @@ export function useProportionalInputs() {
const [isMaximized, setIsMaximized] = useState(false)
const { isLoadingTokenPrices } = useTokens()

// Depending on if the user is using WETH or ETH, we need to filter out the
// native asset or wrapped native asset.
const nativeAssetFilter = (balance: TokenAmount) =>
wethIsEth
? wNativeAsset && balance.address !== wNativeAsset.address
: nativeAsset && balance.address !== nativeAsset.address

const filteredBalances = useMemo(() => {
return balances.filter(balance =>
wethIsEth
? wNativeAsset && balance.address !== wNativeAsset.address
: nativeAsset && balance.address !== nativeAsset.address
)
}, [wethIsEth, isBalancesLoading])
return balances.filter(nativeAssetFilter)
}, [wethIsEth, isBalancesLoading, balances])

function clearAmountsIn(changedAmount?: HumanTokenAmountWithAddress) {
setHumanAmountsIn(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,13 @@ export class ProportionalAddLiquidityHandler implements AddLiquidityHandler {
account,
queryOutput,
humanAmountsIn,
slippagePercent,
}: SdkBuildAddLiquidityInput): Promise<TransactionConfig> {
const addLiquidity = new AddLiquidity()

const { callData, to, value } = addLiquidity.buildCall({
...queryOutput.sdkQueryOutput,
// Setting slippage to zero ensures the build call can't fail if the user
// maxes out their balance. It can result in a tx failure if the pool
// state changes significantly in the background. The assumption is that
// this should be rare. If not, we will have to re-introduce slippage here
// and limit the user input amounts to their balance - slippage.
slippage: Slippage.fromPercentage('0' as HumanAmount),
slippage: Slippage.fromPercentage(slippagePercent as HumanAmount),
sender: account,
recipient: account,
wethIsEth: this.helpers.isNativeAssetIn(humanAmountsIn),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function AddLiquiditySummary({
tokens,
addLiquidityTxHash,
addLiquidityTxSuccess,
slippage,
} = useAddLiquidity()
const { pool } = usePool()
const { isMobile } = useBreakpoints()
Expand Down Expand Up @@ -123,6 +124,7 @@ export function AddLiquiditySummary({
<PoolActionsPriceImpactDetails
totalUSDValue={totalUSDValue}
bptAmount={simulationQuery.data?.bptOut.amount}
slippage={slippage}
isAddLiquidity
/>
</VStack>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { useUserSettings } from '@/lib/modules/user/settings/UserSettingsProvider'
import { useUserAccount } from '@/lib/modules/web3/UserAccountProvider'
import { defaultDebounceMs, onlyExplicitRefetch } from '@/lib/shared/utils/queries'
import { useQuery } from '@tanstack/react-query'
Expand All @@ -19,19 +18,20 @@ export type AddLiquidityBuildQueryParams = {
handler: AddLiquidityHandler
humanAmountsIn: HumanTokenAmountWithAddress[]
simulationQuery: AddLiquiditySimulationQueryResult
slippage: string
}

// Uses the SDK to build a transaction config to be used by wagmi's useManagedSendTransaction
export function useAddLiquidityBuildCallDataQuery({
handler,
humanAmountsIn,
simulationQuery,
slippage,
enabled,
}: AddLiquidityBuildQueryParams & {
enabled: boolean
}) {
const { userAddress, isConnected } = useUserAccount()
const { slippage } = useUserSettings()
const { pool, chainId } = usePool()
const { data: blockNumber } = useBlockNumber({ chainId })
const { relayerApprovalSignature } = useRelayerSignature()
Expand Down
Loading

0 comments on commit 78e5b3f

Please sign in to comment.