Merge branch 'main' into saml33/follow-accounts
This commit is contained in:
commit
68ac136b75
Binary file not shown.
BIN
Sounds/coins.wav
BIN
Sounds/coins.wav
Binary file not shown.
|
@ -198,7 +198,7 @@ export const queryBirdeyeBars = async (
|
|||
high: bar.h,
|
||||
open: bar.o,
|
||||
close: bar.c,
|
||||
volume: bar.v,
|
||||
volume: bar.vQuote,
|
||||
timestamp,
|
||||
},
|
||||
]
|
||||
|
|
|
@ -3,7 +3,7 @@ import { Provider } from '@project-serum/anchor'
|
|||
import { MANGO_DATA_API_URL } from 'utils/constants'
|
||||
import { AnchorProvider } from '@coral-xyz/anchor'
|
||||
|
||||
export const DISTRIBUTION_NUMBER_PREFIX = 115
|
||||
export const DISTRIBUTION_NUMBER_PREFIX = 116
|
||||
|
||||
type AccountTier = {
|
||||
mango_account: string
|
||||
|
|
|
@ -348,7 +348,7 @@ const ListToken = ({ goBack }: { goBack: () => void }) => {
|
|||
true,
|
||||
)
|
||||
|
||||
const swapInfos = swaps?.bestRoute?.routePlan.map((x) => x.swapInfo)
|
||||
const swapInfos = swaps?.bestRoute?.routePlan?.map((x) => x.swapInfo)
|
||||
const orcaPool = swapInfos?.find(
|
||||
(x) => x.label?.toLowerCase().includes('orca'),
|
||||
)
|
||||
|
|
|
@ -57,9 +57,10 @@ const RoutesModal = ({
|
|||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col text-left">
|
||||
<div className="overflow-ellipsis font-bold">
|
||||
{route.routePlan.map((info, index) => {
|
||||
{route.routePlan?.map((info, index) => {
|
||||
let includeSeparator = false
|
||||
if (
|
||||
route.routePlan &&
|
||||
route.routePlan.length > 1 &&
|
||||
index !== route.routePlan.length - 1
|
||||
) {
|
||||
|
@ -74,9 +75,12 @@ const RoutesModal = ({
|
|||
</div>
|
||||
<div className="text-xs text-th-fgd-4">
|
||||
{inputTokenSymbol} →{' '}
|
||||
{route.routePlan.map((r, index) => {
|
||||
{route.routePlan?.map((r, index) => {
|
||||
const showArrow =
|
||||
index !== route.routePlan.length - 1 ? true : false
|
||||
route.routePlan &&
|
||||
index !== route.routePlan.length - 1
|
||||
? true
|
||||
: false
|
||||
return (
|
||||
<span key={index}>
|
||||
<span>
|
||||
|
|
|
@ -9,18 +9,18 @@ import { OUTPUT_TOKEN_DEFAULT, SWAP_MARGIN_KEY } from '../../utils/constants'
|
|||
import TokenVaultWarnings from '@components/shared/TokenVaultWarnings'
|
||||
import SwapSettings from './SwapSettings'
|
||||
import InlineNotification from '@components/shared/InlineNotification'
|
||||
// import Tooltip from '@components/shared/Tooltip'
|
||||
import Tooltip from '@components/shared/Tooltip'
|
||||
import MarketSwapForm from './MarketSwapForm'
|
||||
// import Switch from '@components/forms/Switch'
|
||||
import Switch from '@components/forms/Switch'
|
||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
import { SwapFormTokenListType } from './SwapFormTokenList'
|
||||
import { SwapTypes } from 'types'
|
||||
import TriggerSwapForm from './TriggerSwapForm'
|
||||
import WalletSwapForm from './WalletSwapForm'
|
||||
import TabButtons from '@components/shared/TabButtons'
|
||||
// import useMangoAccount from 'hooks/useMangoAccount'
|
||||
// import { useWallet } from '@solana/wallet-adapter-react'
|
||||
// import { useRouter } from 'next/router'
|
||||
import useMangoAccount from 'hooks/useMangoAccount'
|
||||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import { useRouter } from 'next/router'
|
||||
import SwapSummaryInfo from './SwapSummaryInfo'
|
||||
|
||||
const set = mangoStore.getState().set
|
||||
|
@ -52,17 +52,14 @@ export const handleTokenOutSelect = (
|
|||
|
||||
const SwapForm = () => {
|
||||
const { t } = useTranslation(['common', 'swap', 'trade'])
|
||||
// const groupLoaded = mangoStore((s) => s.groupLoaded)
|
||||
// const { mangoAccountAddress, initialLoad } = useMangoAccount()
|
||||
// const { connected } = useWallet()
|
||||
// const { query } = useRouter()
|
||||
const groupLoaded = mangoStore((s) => s.groupLoaded)
|
||||
const { mangoAccountAddress, initialLoad } = useMangoAccount()
|
||||
const { connected } = useWallet()
|
||||
const { query } = useRouter()
|
||||
const [showTokenSelect, setShowTokenSelect] =
|
||||
useState<SwapFormTokenListType>()
|
||||
const [showSettings, setShowSettings] = useState(false)
|
||||
const [
|
||||
walletSwap,
|
||||
// setWalletSwap
|
||||
] = useState(false)
|
||||
const [walletSwap, setWalletSwap] = useState(false)
|
||||
const [, setSavedSwapMargin] = useLocalStorageState<boolean>(
|
||||
SWAP_MARGIN_KEY,
|
||||
true,
|
||||
|
@ -76,32 +73,32 @@ const SwapForm = () => {
|
|||
} = mangoStore((s) => s.swap)
|
||||
|
||||
// enable wallet swap when connected and no mango account
|
||||
// useEffect(() => {
|
||||
// if (connected && !mangoAccountAddress && !initialLoad) {
|
||||
// setWalletSwap(true)
|
||||
// }
|
||||
// }, [connected, mangoAccountAddress, initialLoad])
|
||||
useEffect(() => {
|
||||
if (connected && !mangoAccountAddress && !initialLoad) {
|
||||
setWalletSwap(true)
|
||||
}
|
||||
}, [connected, mangoAccountAddress, initialLoad])
|
||||
|
||||
// setup swap from url query
|
||||
// useEffect(() => {
|
||||
// const { group } = mangoStore.getState()
|
||||
// if ('walletSwap' in query) {
|
||||
// setWalletSwap(true)
|
||||
// }
|
||||
// if (!groupLoaded) return
|
||||
// if (query.in) {
|
||||
// const inBank = group?.banksMapByName.get(query.in.toString())?.[0]
|
||||
// set((state) => {
|
||||
// state.swap.inputBank = inBank
|
||||
// })
|
||||
// }
|
||||
// if (query.out) {
|
||||
// const outBank = group?.banksMapByName.get(query.out.toString())?.[0]
|
||||
// set((state) => {
|
||||
// state.swap.outputBank = outBank
|
||||
// })
|
||||
// }
|
||||
// }, [groupLoaded, query])
|
||||
useEffect(() => {
|
||||
const { group } = mangoStore.getState()
|
||||
if ('walletSwap' in query) {
|
||||
setWalletSwap(true)
|
||||
}
|
||||
if (!groupLoaded) return
|
||||
if (query.in) {
|
||||
const inBank = group?.banksMapByName.get(query.in.toString())?.[0]
|
||||
set((state) => {
|
||||
state.swap.inputBank = inBank
|
||||
})
|
||||
}
|
||||
if (query.out) {
|
||||
const outBank = group?.banksMapByName.get(query.out.toString())?.[0]
|
||||
set((state) => {
|
||||
state.swap.outputBank = outBank
|
||||
})
|
||||
}
|
||||
}, [groupLoaded, query])
|
||||
|
||||
const handleSwapOrTrigger = useCallback(
|
||||
(orderType: SwapTypes) => {
|
||||
|
@ -164,7 +161,7 @@ const SwapForm = () => {
|
|||
<div className="relative">
|
||||
{swapOrTrigger === 'swap' ? (
|
||||
<>
|
||||
{/* <div className="flex justify-end pb-3 pt-4">
|
||||
<div className="flex justify-end pb-3 pt-4">
|
||||
<div className="flex justify-between px-4 md:px-6">
|
||||
<Switch
|
||||
checked={walletSwap}
|
||||
|
@ -178,13 +175,13 @@ const SwapForm = () => {
|
|||
</Tooltip>
|
||||
</Switch>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
{walletSwap ? (
|
||||
<div className="px-4 md:px-6">
|
||||
<WalletSwapForm setShowTokenSelect={setShowTokenSelect} />
|
||||
</div>
|
||||
) : (
|
||||
<div className="px-4 pt-4 md:px-6 md:pt-6">
|
||||
<div className="px-4 md:px-6">
|
||||
<MarketSwapForm setShowTokenSelect={setShowTokenSelect} />
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -25,12 +25,14 @@ const SwapFormSubmitButton = ({
|
|||
loadingSwapDetails,
|
||||
selectedRoute,
|
||||
setShowConfirm,
|
||||
walletSwap,
|
||||
}: {
|
||||
amountIn: Decimal
|
||||
amountOut: number | undefined
|
||||
loadingSwapDetails: boolean
|
||||
selectedRoute: JupiterV6RouteInfo | undefined | null
|
||||
setShowConfirm: (x: boolean) => void
|
||||
walletSwap?: boolean
|
||||
}) => {
|
||||
const { t } = useTranslation('common')
|
||||
const { mangoAccountAddress } = useMangoAccount()
|
||||
|
@ -45,7 +47,8 @@ const SwapFormSubmitButton = ({
|
|||
// check if the borrowed amount exceeds the net borrow limit in the current period
|
||||
const borrowExceedsLimitInPeriod = useMemo(() => {
|
||||
const mangoAccount = mangoStore.getState().mangoAccount.current
|
||||
if (!mangoAccount || !inputBank || !remainingBorrowsInPeriod) return false
|
||||
if (!mangoAccount || !inputBank || !remainingBorrowsInPeriod || walletSwap)
|
||||
return false
|
||||
|
||||
const balance = mangoAccount.getTokenDepositsUi(inputBank)
|
||||
const remainingBalance = balance - amountIn.toNumber()
|
||||
|
@ -81,7 +84,7 @@ const SwapFormSubmitButton = ({
|
|||
isLarge
|
||||
/>
|
||||
)}
|
||||
{tokenPositionsFull ? (
|
||||
{tokenPositionsFull && !walletSwap ? (
|
||||
<div className="pb-4">
|
||||
<InlineNotification
|
||||
type="error"
|
||||
|
|
|
@ -33,7 +33,7 @@ import { useTranslation } from 'next-i18next'
|
|||
import { formatNumericValue } from '../../utils/numbers'
|
||||
import { notify } from '../../utils/notifications'
|
||||
import useJupiterMints from '../../hooks/useJupiterMints'
|
||||
import { JupiterV6RouteInfo } from 'types/jupiter'
|
||||
import { JupiterV6RouteInfo, JupiterV6RoutePlan } from 'types/jupiter'
|
||||
import useJupiterSwapData from './useJupiterSwapData'
|
||||
// import { Transaction } from '@solana/web3.js'
|
||||
import {
|
||||
|
@ -52,6 +52,7 @@ import { isMangoError } from 'types'
|
|||
import { useWallet } from '@solana/wallet-adapter-react'
|
||||
import TokenLogo from '@components/shared/TokenLogo'
|
||||
import {
|
||||
Bank,
|
||||
TransactionErrors,
|
||||
parseTxForKnownErrors,
|
||||
} from '@blockworks-foundation/mango-v4'
|
||||
|
@ -112,6 +113,34 @@ const deserializeJupiterIxAndAlt = async (
|
|||
return [decompiledMessage.instructions, addressLookupTables]
|
||||
}
|
||||
|
||||
const calculateOutFees = (
|
||||
routePlan: JupiterV6RoutePlan[],
|
||||
inputBank: Bank,
|
||||
outputBank: Bank,
|
||||
outputDecimals: number,
|
||||
): [number, number] => {
|
||||
let outFee = 0
|
||||
for (let i = 0; i < routePlan.length; i++) {
|
||||
const r = routePlan[i].swapInfo
|
||||
const price = r.outAmount / r.inAmount
|
||||
outFee *= price
|
||||
if (r.feeMint === r.outputMint) {
|
||||
outFee += r.feeAmount
|
||||
} else {
|
||||
outFee += r.feeAmount * price
|
||||
}
|
||||
}
|
||||
const jupiterFee = outFee / 10 ** outputDecimals
|
||||
|
||||
const flashLoanSwapFeeRate = Math.max(
|
||||
inputBank.flashLoanSwapFeeRate,
|
||||
outputBank.flashLoanSwapFeeRate,
|
||||
)
|
||||
const mangoSwapFee = routePlan[0].swapInfo.inAmount * flashLoanSwapFeeRate
|
||||
|
||||
return [jupiterFee, mangoSwapFee]
|
||||
}
|
||||
|
||||
// const prepareMangoRouterInstructions = async (
|
||||
// selectedRoute: RouteInfo,
|
||||
// inputMint: PublicKey,
|
||||
|
@ -146,15 +175,14 @@ const deserializeJupiterIxAndAlt = async (
|
|||
// return [instructions, []]
|
||||
// }
|
||||
|
||||
export const fetchJupiterTransaction = async (
|
||||
connection: Connection,
|
||||
/** Given a Jupiter route, fetch the transaction for the user to sign.
|
||||
**This function should ONLY be used for wallet swaps* */
|
||||
export const fetchJupiterWalletSwapTransaction = async (
|
||||
selectedRoute: JupiterV6RouteInfo,
|
||||
userPublicKey: PublicKey,
|
||||
slippage: number,
|
||||
inputMint: PublicKey,
|
||||
outputMint: PublicKey,
|
||||
isDirectWalletSwap = false,
|
||||
): Promise<[TransactionInstruction[], AddressLookupTableAccount[]]> => {
|
||||
): Promise<VersionedTransaction> => {
|
||||
// TODO: replace by something that belongs to the DAO
|
||||
// https://referral.jup.ag/
|
||||
// EV4qhLE2yPKdUPdQ74EWJUn21xT3eGQxG3DRR1g9NNFc belongs to 8SSLjXBEVk9nesbhi9UMCA32uijbVBUqWoKPPQPTekzt
|
||||
|
@ -169,6 +197,63 @@ export const fetchJupiterTransaction = async (
|
|||
)
|
||||
const feeAccount = feeAccountPdas[0]
|
||||
|
||||
// docs https://station.jup.ag/api-v6/post-swap
|
||||
const transactions = await (
|
||||
await fetch(`${JUPITER_V6_QUOTE_API_MAINNET}/swap`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
// response from /quote api
|
||||
quoteResponse: selectedRoute,
|
||||
// user public key to be used for the swap
|
||||
userPublicKey,
|
||||
slippageBps: Math.ceil(slippage * 100),
|
||||
// docs
|
||||
// https://station.jup.ag/docs/additional-topics/referral-program
|
||||
// https://github.com/TeamRaccoons/referral
|
||||
// https://github.com/TeamRaccoons/referral/blob/main/packages/sdk/src/referral.ts
|
||||
platformFeeBps: 1,
|
||||
feeAccount,
|
||||
// limits
|
||||
}),
|
||||
})
|
||||
).json()
|
||||
|
||||
const { swapTransaction } = transactions
|
||||
|
||||
const parsedSwapTransaction = VersionedTransaction.deserialize(
|
||||
Buffer.from(swapTransaction, 'base64'),
|
||||
)
|
||||
return parsedSwapTransaction
|
||||
}
|
||||
/** Given a Jupiter route, fetch the transaction for the user to sign.
|
||||
**This function should be used for margin swaps* */
|
||||
export const fetchJupiterTransaction = async (
|
||||
connection: Connection,
|
||||
selectedRoute: JupiterV6RouteInfo,
|
||||
userPublicKey: PublicKey,
|
||||
slippage: number,
|
||||
inputMint: PublicKey,
|
||||
outputMint: PublicKey,
|
||||
): Promise<[TransactionInstruction[], AddressLookupTableAccount[]]> => {
|
||||
// TODO: replace by something that belongs to the DAO
|
||||
// https://referral.jup.ag/
|
||||
// EV4qhLE2yPKdUPdQ74EWJUn21xT3eGQxG3DRR1g9NNFc belongs to 8SSLjXBEVk9nesbhi9UMCA32uijbVBUqWoKPPQPTekzt
|
||||
// for now
|
||||
|
||||
const feeMint = selectedRoute.swapMode === 'ExactIn' ? outputMint : inputMint
|
||||
const feeAccountPdas = await PublicKey.findProgramAddressSync(
|
||||
[
|
||||
Buffer.from('referral_ata'),
|
||||
new PublicKey('EV4qhLE2yPKdUPdQ74EWJUn21xT3eGQxG3DRR1g9NNFc').toBuffer(),
|
||||
feeMint.toBuffer(),
|
||||
],
|
||||
new PublicKey('REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3'),
|
||||
)
|
||||
const feeAccount = feeAccountPdas[0]
|
||||
|
||||
// docs https://station.jup.ag/api-v6/post-swap
|
||||
const transactions = await (
|
||||
await fetch(`${JUPITER_V6_QUOTE_API_MAINNET}/swap`, {
|
||||
|
@ -212,10 +297,10 @@ export const fetchJupiterTransaction = async (
|
|||
)
|
||||
}
|
||||
|
||||
//if its in wallet swap we need ATA creation
|
||||
//remove ATA and compute setup from swaps in margin trades
|
||||
const filtered_jup_ixs = ixs
|
||||
.filter((ix) => (!isDirectWalletSwap ? !isSetupIx(ix.programId) : true))
|
||||
.filter((ix) => (!isDirectWalletSwap ? !isDuplicateAta(ix) : true))
|
||||
.filter((ix) => !isSetupIx(ix.programId))
|
||||
.filter((ix) => !isDuplicateAta(ix))
|
||||
|
||||
return [filtered_jup_ixs, alts]
|
||||
}
|
||||
|
@ -321,21 +406,26 @@ const SwapReviewRouteInfo = ({
|
|||
const onWalletSwap = useCallback(async () => {
|
||||
if (!selectedRoute || !inputBank || !outputBank || !wallet.publicKey) return
|
||||
const actions = mangoStore.getState().actions
|
||||
const client = mangoStore.getState().client
|
||||
const connection = mangoStore.getState().connection
|
||||
setSubmitting(true)
|
||||
try {
|
||||
const [ixs] = await fetchJupiterTransaction(
|
||||
connection,
|
||||
const vtx = await fetchJupiterWalletSwapTransaction(
|
||||
selectedRoute,
|
||||
wallet.publicKey,
|
||||
slippage,
|
||||
inputBank.mint,
|
||||
outputBank.mint,
|
||||
true,
|
||||
)
|
||||
|
||||
const tx = await client.sendAndConfirmTransaction(ixs)
|
||||
const sign = wallet.signTransaction!
|
||||
const signed = await sign(vtx)
|
||||
const rawTransaction = signed.serialize()
|
||||
|
||||
const txid = await connection.sendRawTransaction(rawTransaction, {
|
||||
skipPreflight: true,
|
||||
maxRetries: 2,
|
||||
})
|
||||
|
||||
await connection.confirmTransaction(txid)
|
||||
set((s) => {
|
||||
s.swap.amountIn = ''
|
||||
s.swap.amountOut = ''
|
||||
|
@ -343,7 +433,7 @@ const SwapReviewRouteInfo = ({
|
|||
notify({
|
||||
title: 'Transaction confirmed',
|
||||
type: 'success',
|
||||
txid: tx.signature,
|
||||
txid,
|
||||
})
|
||||
actions.fetchWalletTokens(wallet.publicKey)
|
||||
} catch (e) {
|
||||
|
@ -491,6 +581,24 @@ const SwapReviewRouteInfo = ({
|
|||
return [balance, borrowAmount]
|
||||
}, [amountIn])
|
||||
|
||||
const [jupiterFees] = useMemo(() => {
|
||||
if (
|
||||
!selectedRoute?.routePlan ||
|
||||
!inputBank ||
|
||||
!outputBank ||
|
||||
!outputTokenInfo
|
||||
) {
|
||||
return [0, 0]
|
||||
}
|
||||
|
||||
return calculateOutFees(
|
||||
selectedRoute?.routePlan,
|
||||
inputBank,
|
||||
outputBank,
|
||||
outputTokenInfo.decimals,
|
||||
)
|
||||
}, [selectedRoute])
|
||||
|
||||
const coinGeckoPriceDifference = useMemo(() => {
|
||||
return amountOut?.toNumber()
|
||||
? amountIn
|
||||
|
@ -705,6 +813,46 @@ const SwapReviewRouteInfo = ({
|
|||
: `${(selectedRoute?.priceImpactPct * 100).toFixed(2)}%`}
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex justify-between">
|
||||
<Tooltip
|
||||
content={
|
||||
<>
|
||||
<p>
|
||||
The fee displayed here is an estimate and is displayed in
|
||||
destination tokens for convenience. Note that each leg of
|
||||
the swap may collect its fee in different tokens, so fees
|
||||
may vary.
|
||||
</p>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<p className="tooltip-underline">Jupiter Fees</p>
|
||||
</Tooltip>
|
||||
<p className="text-right font-mono text-sm text-th-fgd-2">
|
||||
≈{' '}
|
||||
<FormatNumericValue
|
||||
value={jupiterFees}
|
||||
decimals={outputTokenInfo.decimals}
|
||||
/>{' '}
|
||||
<span className="font-body text-th-fgd-3">
|
||||
{outputTokenInfo?.symbol}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* <div className="flex justify-between">
|
||||
<p className="text-th-fgd-3">Mango Fees</p>
|
||||
<p className="text-right font-mono text-sm text-th-fgd-2">
|
||||
≈{' '}
|
||||
<FormatNumericValue
|
||||
value={mangoFees}
|
||||
decimals={outputTokenInfo.decimals}
|
||||
/>{' '}
|
||||
<span className="font-body text-th-fgd-3">
|
||||
{outputTokenInfo?.symbol}
|
||||
</span>
|
||||
</p>
|
||||
</div> */}
|
||||
{borrowAmount ? (
|
||||
<>
|
||||
<div className="flex justify-between">
|
||||
|
@ -814,9 +962,10 @@ const SwapReviewRouteInfo = ({
|
|||
onClick={() => setShowRoutesModal(true)}
|
||||
>
|
||||
<span className="overflow-ellipsis whitespace-nowrap">
|
||||
{selectedRoute?.routePlan.map((info, index) => {
|
||||
{selectedRoute?.routePlan?.map((info, index) => {
|
||||
let includeSeparator = false
|
||||
if (
|
||||
selectedRoute.routePlan &&
|
||||
selectedRoute?.routePlan.length > 1 &&
|
||||
index !== selectedRoute?.routePlan.length - 1
|
||||
) {
|
||||
|
@ -842,7 +991,7 @@ const SwapReviewRouteInfo = ({
|
|||
</div>
|
||||
</div>
|
||||
) : (
|
||||
selectedRoute?.routePlan.map((info, index) => {
|
||||
selectedRoute?.routePlan?.map((info, index) => {
|
||||
const feeToken = jupiterTokens.find(
|
||||
(item) => item?.address === info.swapInfo.feeMint,
|
||||
)
|
||||
|
|
|
@ -358,6 +358,7 @@ const WalletSwapForm = ({ setShowTokenSelect }: WalletSwapFormProps) => {
|
|||
setShowConfirm={setShowConfirm}
|
||||
amountIn={amountInAsDecimal}
|
||||
amountOut={selectedRoute ? amountOutAsDecimal.toNumber() : undefined}
|
||||
walletSwap
|
||||
/>
|
||||
</>
|
||||
)
|
||||
|
|
|
@ -50,7 +50,7 @@ const RateCurveChart = ({ bank }: { bank: Bank | undefined }) => {
|
|||
|
||||
const [currentRate, currentUtil] = useMemo(() => {
|
||||
if (!bank) return [0, 0]
|
||||
const currentRate = bank.getDepositRateUi()
|
||||
const currentRate = bank.getBorrowRateUi()
|
||||
const currentUtil = (bank.uiBorrows() / bank.uiDeposits()) * 100 || 0
|
||||
return [currentRate, currentUtil]
|
||||
}, [bank])
|
||||
|
@ -81,7 +81,7 @@ const RateCurveChart = ({ bank }: { bank: Bank | undefined }) => {
|
|||
{rateCurveChartData.length && bank ? (
|
||||
<>
|
||||
<div>
|
||||
<p className="mb-0.5 text-base">{t('token:rate-curve')}</p>
|
||||
<p className="mb-0.5 text-base">{t('token:borrow-rate-curve')}</p>
|
||||
{mouseData ? (
|
||||
<div>
|
||||
<div
|
||||
|
@ -212,7 +212,7 @@ const RateCurveChart = ({ bank }: { bank: Bank | undefined }) => {
|
|||
(bank.uiBorrows() / bank.uiDeposits()) *
|
||||
100
|
||||
).toString()}
|
||||
y={bank.getDepositRateUi()}
|
||||
y={bank.getBorrowRateUi()}
|
||||
r={4}
|
||||
fill={COLORS.BKG1[theme]}
|
||||
stroke={'var(--active)'}
|
||||
|
|
|
@ -708,11 +708,12 @@ export default function SpotMarketOrderSwapForm() {
|
|||
) : (
|
||||
<div className="flex items-center overflow-hidden text-th-fgd-2">
|
||||
<Tooltip
|
||||
content={selectedRoute?.routePlan.map((info, index) => {
|
||||
content={selectedRoute?.routePlan?.map((info, index) => {
|
||||
let includeSeparator = false
|
||||
if (
|
||||
selectedRoute?.routePlan.length > 1 &&
|
||||
index !== selectedRoute?.routePlan.length - 1
|
||||
selectedRoute?.routePlan &&
|
||||
selectedRoute?.routePlan?.length > 1 &&
|
||||
index !== selectedRoute?.routePlan?.length - 1
|
||||
) {
|
||||
includeSeparator = true
|
||||
}
|
||||
|
@ -724,11 +725,12 @@ export default function SpotMarketOrderSwapForm() {
|
|||
})}
|
||||
>
|
||||
<div className="tooltip-underline max-w-[140px] truncate whitespace-nowrap">
|
||||
{selectedRoute?.routePlan.map((info, index) => {
|
||||
{selectedRoute?.routePlan?.map((info, index) => {
|
||||
let includeSeparator = false
|
||||
if (
|
||||
selectedRoute?.routePlan.length > 1 &&
|
||||
index !== selectedRoute?.routePlan.length - 1
|
||||
selectedRoute?.routePlan &&
|
||||
selectedRoute?.routePlan?.length > 1 &&
|
||||
index !== selectedRoute?.routePlan?.length - 1
|
||||
) {
|
||||
includeSeparator = true
|
||||
}
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
"dependencies": {
|
||||
"@blockworks-foundation/mango-feeds": "0.1.7",
|
||||
"@blockworks-foundation/mango-mints-redemption": "^0.0.10",
|
||||
"@blockworks-foundation/mango-v4": "0.19.43",
|
||||
"@blockworks-foundation/mango-v4-settings": "0.2.16",
|
||||
"@blockworks-foundation/mango-v4": "0.19.49",
|
||||
"@blockworks-foundation/mango-v4-settings": "0.2.17",
|
||||
"@blockworks-foundation/mangolana": "0.0.1-beta.15",
|
||||
"@headlessui/react": "1.6.6",
|
||||
"@heroicons/react": "2.0.18",
|
||||
|
|
|
@ -287,14 +287,6 @@ const Dashboard: NextPage = () => {
|
|||
label="Dust"
|
||||
value={formattedBankValues.dust}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Deposits"
|
||||
value={`${formattedBankValues.deposits} ($${formattedBankValues.depositsPrice})`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Borrows"
|
||||
value={`${formattedBankValues.borrows} ($${formattedBankValues.borrowsPrice})`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Reduce Only"
|
||||
value={`${
|
||||
|
@ -315,10 +307,22 @@ const Dashboard: NextPage = () => {
|
|||
value={`${formattedBankValues.initAssetWeight} /
|
||||
${formattedBankValues.initLiabWeight}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Liquidation fee"
|
||||
value={`${formattedBankValues.liquidationFee}%`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Scaled Init Asset/Liab Weight"
|
||||
value={`${formattedBankValues.scaledInitAssetWeight} / ${formattedBankValues.scaledInitLiabWeight}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Deposits"
|
||||
value={`${formattedBankValues.deposits} ($${formattedBankValues.depositsPrice})`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Borrows"
|
||||
value={`${formattedBankValues.borrows} ($${formattedBankValues.borrowsPrice})`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Deposit weight scale start quote"
|
||||
value={`$${formattedBankValues.depositWeightScaleStartQuote}`}
|
||||
|
@ -327,6 +331,23 @@ const Dashboard: NextPage = () => {
|
|||
label="Borrow weight scale start quote"
|
||||
value={`$${formattedBankValues.borrowWeightScaleStartQuote}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label={`Net borrows in window (next window starts ${dayjs().to(
|
||||
dayjs().add(
|
||||
bank.getTimeToNextBorrowLimitWindowStartsTs(),
|
||||
'second',
|
||||
),
|
||||
)})`}
|
||||
value={`$${formattedBankValues.minVaultToDepositsRatio} / $${formattedBankValues.netBorrowLimitPerWindowQuote}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Group Insurance Fund"
|
||||
value={`${mintInfo!.groupInsuranceFund}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Min vault to deposits ratio"
|
||||
value={`${formattedBankValues.minVaultToDepositsRatio}%`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Rate params"
|
||||
value={
|
||||
|
@ -371,27 +392,7 @@ const Dashboard: NextPage = () => {
|
|||
label="Oracle: Max Staleness"
|
||||
value={`${bank.oracleConfig.maxStalenessSlots} slots (Last updated slot ${bank._oracleLastUpdatedSlot})`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Group Insurance Fund"
|
||||
value={`${mintInfo!.groupInsuranceFund}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Min vault to deposits ratio"
|
||||
value={`${formattedBankValues.minVaultToDepositsRatio}%`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label={`Net borrows in window (next window starts ${dayjs().to(
|
||||
dayjs().add(
|
||||
bank.getTimeToNextBorrowLimitWindowStartsTs(),
|
||||
'second',
|
||||
),
|
||||
)})`}
|
||||
value={`$${formattedBankValues.minVaultToDepositsRatio} / $${formattedBankValues.netBorrowLimitPerWindowQuote}`}
|
||||
/>
|
||||
<KeyValuePair
|
||||
label="Liquidation fee"
|
||||
value={`${formattedBankValues.liquidationFee}%`}
|
||||
/>
|
||||
|
||||
{bank.mint.toBase58() !== USDC_MINT && (
|
||||
<div className="mb-4 mt-2 flex">
|
||||
<Button
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"average-deposit-rate": "Average Deposit Rate",
|
||||
"borrowing": "Borrowing",
|
||||
"borrows": "Borrows",
|
||||
"borrow-rate-curve": "Borrow Interest Rate Curve",
|
||||
"borrow-rates": "Borrow Rates",
|
||||
"borrow-upkeep-rate": "Borrow Upkeep Rate",
|
||||
"chart-unavailable": "Chart Unavailable",
|
||||
|
@ -30,7 +31,6 @@
|
|||
"oracle-confidence": "Oracle Confidence",
|
||||
"oracle-staleness": "Oracle Staleness",
|
||||
"parameters": "Parameters",
|
||||
"rate-curve": "Interest Rate Curve",
|
||||
"token-stats": "{{token}} Stats",
|
||||
"token-fees-collected": "Token Fees Collected",
|
||||
"token-not-found": "Token Not Found",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"average-deposit-rate": "Average Deposit Rate",
|
||||
"borrowing": "Borrowing",
|
||||
"borrows": "Borrows",
|
||||
"borrow-rate-curve": "Borrow Interest Rate Curve",
|
||||
"borrow-rates": "Borrow Rates",
|
||||
"borrow-upkeep-rate": "Borrow Upkeep Rate",
|
||||
"chart-unavailable": "Chart Unavailable",
|
||||
|
@ -30,7 +31,6 @@
|
|||
"oracle-confidence": "Oracle Confidence",
|
||||
"oracle-staleness": "Oracle Staleness",
|
||||
"parameters": "Parameters",
|
||||
"rate-curve": "Interest Rate Curve",
|
||||
"token-stats": "{{token}} Stats",
|
||||
"token-fees-collected": "Token Fees Collected",
|
||||
"token-not-found": "Token Not Found",
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"average-deposit-rate": "Average Deposit Rate",
|
||||
"borrowing": "Borrowing",
|
||||
"borrows": "Borrows",
|
||||
"borrow-rate-curve": "Borrow Interest Rate Curve",
|
||||
"borrow-rates": "Borrow Rates",
|
||||
"borrow-upkeep-rate": "Borrow Upkeep Rate",
|
||||
"chart-unavailable": "Chart Unavailable",
|
||||
|
@ -30,7 +31,6 @@
|
|||
"oracle-confidence": "Oracle Confidence",
|
||||
"oracle-staleness": "Oracle Staleness",
|
||||
"parameters": "Parameters",
|
||||
"rate-curve": "Interest Rate Curve",
|
||||
"token-stats": "{{token}} Stats",
|
||||
"token-fees-collected": "Token Fees Collected",
|
||||
"token-not-found": "Token Not Found",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"borrow-upkeep-rate": "维持借贷的费用",
|
||||
"borrowing": "借入",
|
||||
"borrows": "借贷",
|
||||
"borrow-rate-curve": "Borrow Interest Rate Curve",
|
||||
"chart-unavailable": "无法显示图表",
|
||||
"circulating-supply": "流通供应量",
|
||||
"deposit-borrow-scaling-start": "存款/借款缩放起点",
|
||||
|
@ -30,7 +31,6 @@
|
|||
"oracle-confidence": "预言机可信度",
|
||||
"oracle-staleness": "预言机不新鲜性",
|
||||
"parameters": "参数",
|
||||
"rate-curve": "利率曲线",
|
||||
"token-stats": "币种细节",
|
||||
"token-fees-collected": "收取的币种费用",
|
||||
"token-not-found": "查不到币种",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"borrow-upkeep-rate": "維持借貸的費用",
|
||||
"borrowing": "借入",
|
||||
"borrows": "借貸",
|
||||
"borrow-rate-curve": "Borrow Interest Rate Curve",
|
||||
"chart-unavailable": "無法顯示圖表",
|
||||
"circulating-supply": "流通供應量",
|
||||
"deposit-borrow-scaling-start": "存款/借款縮放起點",
|
||||
|
@ -30,7 +31,6 @@
|
|||
"oracle-confidence": "預言機可信度",
|
||||
"oracle-staleness": "預言機不新鮮性",
|
||||
"parameters": "參數",
|
||||
"rate-curve": "利率曲線",
|
||||
"token-stats": "幣種細節",
|
||||
"token-fees-collected": "收取的幣種費用",
|
||||
"token-not-found": "查不到幣種",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { AccountInfo, PublicKey, TransactionInstruction } from '@solana/web3.js'
|
||||
import { AccountInfo } from '@solana/web3.js'
|
||||
|
||||
export declare type SideType = typeof Side.Ask | typeof Side.Bid
|
||||
export declare const Side: {
|
||||
|
@ -119,7 +119,7 @@ export interface JupiterV6RouteInfo {
|
|||
feeBps: number
|
||||
}
|
||||
priceImpactPct: number
|
||||
routePlan: JupiterV6RoutePlan[]
|
||||
routePlan: JupiterV6RoutePlan[] | undefined
|
||||
contextSlot?: number
|
||||
timeTaken?: number
|
||||
error?: string
|
||||
|
|
|
@ -112,7 +112,7 @@ export const TRADE_VOLUME_ALERT_KEY = 'tradeVolumeAlert-0.1'
|
|||
|
||||
export const PAGINATION_PAGE_LENGTH = 250
|
||||
|
||||
export const JUPITER_API_MAINNET = 'https://token.jup.ag/strict'
|
||||
export const JUPITER_API_MAINNET = 'https://token.jup.ag/all'
|
||||
|
||||
export const JUPITER_API_DEVNET = 'https://api.jup.ag/api/tokens/devnet'
|
||||
|
||||
|
|
16
yarn.lock
16
yarn.lock
|
@ -42,18 +42,18 @@
|
|||
keccak256 "^1.0.6"
|
||||
merkletreejs "^0.3.11"
|
||||
|
||||
"@blockworks-foundation/mango-v4-settings@0.2.16", "@blockworks-foundation/mango-v4-settings@^0.2.16":
|
||||
version "0.2.16"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.2.16.tgz#63f03c13d1677461ea42d3b1e9171042830c6cdc"
|
||||
integrity sha512-9GCRZkVqTQsEUkqx/488pmSWM8I74Ght5AEzMPsuS5XlRGWIDjytWoBE0Y9wFVPrnRw2THTj0ZQft+vDwCYDCA==
|
||||
"@blockworks-foundation/mango-v4-settings@0.2.17", "@blockworks-foundation/mango-v4-settings@^0.2.16":
|
||||
version "0.2.17"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4-settings/-/mango-v4-settings-0.2.17.tgz#ebc64eb037137bdd16df93cdb63badc7f178542b"
|
||||
integrity sha512-k4Hi0Rjq3XbWnN4Hvdd2aDrm24Ob+8+WDCz7hzR+XKCQ0HcYQXVrZn2Yz7e9IA4M3zQEP9n5HHnQopLQb8UgMw==
|
||||
dependencies:
|
||||
bn.js "^5.2.1"
|
||||
eslint-config-prettier "^9.0.0"
|
||||
|
||||
"@blockworks-foundation/mango-v4@0.19.43":
|
||||
version "0.19.43"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.19.43.tgz#82c2df9c63204e31c19473672329cba43ea40fbc"
|
||||
integrity sha512-son/flq/mvngtBppKbxXfNIq/Z4L7mp6zOP5k8cD11rVlZ3wmb3jfBkKqocgL3IqnRIWj3cL9R6dM37tqaFZzw==
|
||||
"@blockworks-foundation/mango-v4@0.19.49":
|
||||
version "0.19.49"
|
||||
resolved "https://registry.yarnpkg.com/@blockworks-foundation/mango-v4/-/mango-v4-0.19.49.tgz#36bfdce19aaf574ff8a366a49bbfdb9c5b8969a8"
|
||||
integrity sha512-RExHSpJZQCcX5Xq4XH5sZ+S+L9FkiYQYXazMkBws4BfEPTpjHIKkNTso/CkY32KkYYmKgtGsPEDcdzB5r/0/LQ==
|
||||
dependencies:
|
||||
"@blockworks-foundation/mango-v4-settings" "^0.2.16"
|
||||
"@coral-xyz/anchor" "^0.28.1-beta.2"
|
||||
|
|
Loading…
Reference in New Issue