mango-v4-ui/components/swap/useJupiter.ts

124 lines
3.5 KiB
TypeScript
Raw Normal View History

2022-08-03 14:46:37 -07:00
import { toUiDecimals } from '@blockworks-foundation/mango-v4'
import { Jupiter, RouteInfo } from '@jup-ag/core'
import { useEffect, useState } from 'react'
import JSBI from 'jsbi'
2022-08-15 21:19:09 -07:00
import Decimal from 'decimal.js'
2022-08-03 14:46:37 -07:00
import mangoStore, { CLUSTER } from '../../store/state'
import { Token } from '../../types/jupiter'
type useJupiterPropTypes = {
inputTokenSymbol: string
outputTokenSymbol: string
inputAmount: string
2022-08-03 14:46:37 -07:00
slippage: number
}
type RouteParams = {
routes: RouteInfo[]
outputTokenInfo: Token | undefined
amountOut: number
}
const defaultComputedInfo = {
routes: [],
outputTokenInfo: undefined,
amountOut: 0,
}
const useJupiter = ({
inputTokenSymbol,
outputTokenSymbol,
inputAmount,
slippage,
}: useJupiterPropTypes) => {
const [jupiter, setJupiter] = useState<Jupiter>()
const [computedInfo, setComputedInfo] =
useState<RouteParams>(defaultComputedInfo)
useEffect(() => {
const connection = mangoStore.getState().connection
const loadJupiter = async () => {
const jupiter = await Jupiter.load({
connection,
cluster: CLUSTER,
wrapUnwrapSOL: false,
2022-08-03 14:46:37 -07:00
// platformFeeAndAccounts: NO_PLATFORM_FEE,
routeCacheDuration: 30_000, // Will not refetch data on computeRoutes for up to 10 seconds
2022-08-03 14:46:37 -07:00
})
setJupiter(jupiter)
}
try {
loadJupiter()
} catch (e) {
console.warn(e)
}
}, [])
useEffect(() => {
const group = mangoStore.getState().group
if (!group) return
const tokens = mangoStore.getState().jupiterTokens
const loadRoutes = async () => {
const inputBank = group.banksMap.get(inputTokenSymbol)
const outputBank = group.banksMap.get(outputTokenSymbol)
if (!inputBank || !outputBank) return
if (!inputAmount) {
setComputedInfo(defaultComputedInfo)
} else {
try {
const computedRoutes = await jupiter
?.computeRoutes({
inputMint: inputBank.mint, // Mint address of the input token
outputMint: outputBank.mint, // Mint address of the output token
amount: JSBI.BigInt(
2022-08-17 18:26:38 -07:00
new Decimal(inputAmount).mul(10 ** inputBank.mintDecimals)
),
2022-08-03 14:46:37 -07:00
slippage, // The slippage in % terms
filterTopNResult: 10,
onlyDirectRoutes: true,
})
.catch((e) => {
console.error('Error computing Jupiter routes:', e)
return
})
const tokenOut = tokens.find(
(t: any) => t.address === outputBank.mint.toString()
)
const routesInfosWithoutRaydium = computedRoutes?.routesInfos.filter(
(r) => {
2022-08-10 13:34:30 -07:00
for (const mkt of r.marketInfos) {
if (mkt.amm.label === 'Raydium' || mkt.amm.label === 'Serum')
return false
2022-08-03 14:46:37 -07:00
}
2022-08-10 13:34:30 -07:00
2022-08-03 14:46:37 -07:00
return true
}
)
if (routesInfosWithoutRaydium?.length) {
const bestRoute = routesInfosWithoutRaydium[0]
setComputedInfo({
routes: routesInfosWithoutRaydium,
outputTokenInfo: tokenOut,
amountOut: toUiDecimals(
JSBI.toNumber(bestRoute.outAmount),
tokenOut?.decimals!
),
2022-08-03 14:46:37 -07:00
})
}
} catch (e) {
console.warn(e)
}
}
}
loadRoutes()
}, [inputTokenSymbol, outputTokenSymbol, jupiter, slippage, inputAmount])
return { jupiter, ...computedInfo }
}
export default useJupiter