Skip to content

Commit

Permalink
feat #244 Avnu hooks integration (#247)
Browse files Browse the repository at this point in the history
Co-authored-by: Charles Lanier <[email protected]>
  • Loading branch information
rfulop and 0xChqrles authored May 6, 2024
1 parent 493ef84 commit 24c6e49
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 9 deletions.
2 changes: 1 addition & 1 deletion packages/frontend/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module.exports = {
root: true,
extends: ['../../.eslintrc.js', '@uniswap/eslint-config/react'],
extends: ['@uniswap/eslint-config/react', '../../.eslintrc.js'],
}
Empty file removed packages/frontend/.gitignore
Empty file.
10 changes: 4 additions & 6 deletions packages/frontend/craco.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,19 @@ const path = require('path')

const isProduction = process.env.NODE_ENV === 'production'

const shouldLintOrTypeCheck = !isProduction

module.exports = {
eslint: {
enable: shouldLintOrTypeCheck,
enable: true,
pluginOptions(eslintConfig) {
return Object.assign(eslintConfig, {
cache: true,
cacheLocation: 'node_modules/.cache/eslint/',
ignorePath: '.gitignore',
ignorePath: '../../.gitignore',
})
},
},
typescript: {
enableTypeChecking: shouldLintOrTypeCheck,
enableTypeChecking: true,
},
webpack: {
plugins: [
Expand Down Expand Up @@ -69,7 +67,7 @@ module.exports = {
chunks: 'all',
},
}
: {}
: {},
)

return webpackConfig
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"lint:fix": "eslint src --fix"
},
"dependencies": {
"@avnu/avnu-sdk": "^2.0.0",
"@hookform/resolvers": "^3.3.2",
"@starknet-react/chains": "^0.1.0",
"@starknet-react/core": "^2.2.4",
Expand All @@ -21,6 +22,7 @@
"clsx": "^2.0.0",
"core": "*",
"eslint": "^8.0.0",
"ethers": "^6.12.0",
"hooks": "*",
"lucide-react": "^0.294.0",
"moment": "^2.30.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend/src/constants/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export const FOREVER = 'Forever'

export const STARKNET_POLLING = 3_000 // 3s
export const STARKNET_MAX_BLOCK_TIME = 3600 * 2 // 2h

export const SLIPPAGE_PRECISION = 2
71 changes: 71 additions & 0 deletions packages/frontend/src/hooks/useAvnu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* eslint-disable import/no-unused-modules */
import { fetchBuildExecuteTransaction, fetchQuotes, Quote, QuoteRequest } from '@avnu/avnu-sdk'
import { useAccount, useBlockNumber } from '@starknet-react/core'
import { Percent } from '@uniswap/sdk-core'
import { useCallback, useEffect, useState } from 'react'
import { SLIPPAGE_PRECISION, STARKNET_POLLING } from 'src/constants/misc'
import { getAvnuOptions } from 'src/utils/avnu'
import { Call } from 'starknet'

export function useGetAvnuQuotes(
tokenAddressFrom: string,
tokenAddressTo: string,
amount: string | number,
): Quote | null {
const account = useAccount()

const [quote, setQuote] = useState<Quote | null>(null)

const { data: blockNumber } = useBlockNumber({ refetchInterval: STARKNET_POLLING })

useEffect(() => {
if (!blockNumber) return

const AVNU_OPTIONS = getAvnuOptions(account.chainId)

const abortController = new AbortController()

const params: QuoteRequest = {
sellTokenAddress: tokenAddressFrom,
buyTokenAddress: tokenAddressTo,
sellAmount: BigInt(amount),
}

fetchQuotes(params, { ...AVNU_OPTIONS, abortSignal: abortController.signal })
.then((quotes) => {
setQuote(quotes.length > 0 ? quotes[0] : null)
})
.catch((error) => {
if (!abortController.signal.aborted) {
// TODO: handle error
console.log(error)
}
})

return () => abortController.abort()
}, [account.chainId, tokenAddressFrom, tokenAddressTo, amount, blockNumber])

return quote
}

export function useAvnuSwapBuilder(slippage: Percent): (quote: Quote) => Promise<Call[] | undefined> {
const account = useAccount()

return useCallback(
async (quote: Quote) => {
if (!account.address) return

const AVNU_OPTIONS = getAvnuOptions(account.chainId)

const { calls } = await fetchBuildExecuteTransaction(
quote.quoteId,
account.address,
+slippage.toFixed(SLIPPAGE_PRECISION),
true,
AVNU_OPTIONS,
)
return calls
},
[account.address, account.chainId, slippage],
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ export default function LaunchTemplate({ liquidityPrice, teamAllocationPrice, pr
loading
? 'Loading...'
: hasEnoughQuoteTokenBalance
? `Launch on ${amm}`
: `Insufficient ${quoteToken.symbol} balance`
? `Launch on ${amm}`
: `Insufficient ${quoteToken.symbol} balance`
}
onNext={next}
disableNext={loading || !hasEnoughQuoteTokenBalance}
Expand Down
11 changes: 11 additions & 0 deletions packages/frontend/src/utils/avnu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { BASE_URL, SEPOLIA_BASE_URL } from '@avnu/avnu-sdk'
import { starknetChainId } from '@starknet-react/core'
import { constants } from 'starknet'

export function getAvnuOptions(chainId: bigint | undefined): { baseUrl: string } {
const actualChainId = chainId ?? BigInt(constants.StarknetChainId.SN_MAIN)

return {
baseUrl: starknetChainId(actualChainId) === constants.StarknetChainId.SN_MAIN ? BASE_URL : SEPOLIA_BASE_URL,
}
}

0 comments on commit 24c6e49

Please sign in to comment.