placeperporders
This commit is contained in:
parent
7c34ed0bcb
commit
420b0270da
|
@ -1,4 +1,7 @@
|
|||
import {
|
||||
PerpMarket,
|
||||
PerpOrderSide,
|
||||
PerpOrderType,
|
||||
Serum3Market,
|
||||
Serum3OrderType,
|
||||
Serum3SelfTradeBehavior,
|
||||
|
@ -24,6 +27,8 @@ import { QuestionMarkCircleIcon } from '@heroicons/react/20/solid'
|
|||
import Loading from '@components/shared/Loading'
|
||||
import { Market } from '@project-serum/serum'
|
||||
import TabUnderline from '@components/shared/TabUnderline'
|
||||
import { group } from 'console'
|
||||
import PerpSlider from './PerpSlider'
|
||||
|
||||
const TABS: [string, number][] = [
|
||||
['Limit', 0],
|
||||
|
@ -40,7 +45,7 @@ const AdvancedTradeForm = () => {
|
|||
const [placingOrder, setPlacingOrder] = useState(false)
|
||||
|
||||
const baseSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split('/')[0]
|
||||
return selectedMarket?.name.split(/-|\//)[0]
|
||||
}, [selectedMarket])
|
||||
|
||||
const baseLogoURI = useMemo(() => {
|
||||
|
@ -52,10 +57,20 @@ const AdvancedTradeForm = () => {
|
|||
return ''
|
||||
}, [baseSymbol, jupiterTokens])
|
||||
|
||||
const quoteSymbol = useMemo(() => {
|
||||
return selectedMarket?.name.split('/')[1]
|
||||
const quoteBank = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!group || !selectedMarket) return
|
||||
const tokenIdx =
|
||||
selectedMarket instanceof Serum3Market
|
||||
? selectedMarket.baseTokenIndex
|
||||
: selectedMarket?.settleTokenIndex
|
||||
return group?.getFirstBankByTokenIndex(tokenIdx)
|
||||
}, [selectedMarket])
|
||||
|
||||
const quoteSymbol = useMemo(() => {
|
||||
return quoteBank?.name
|
||||
}, [quoteBank])
|
||||
|
||||
const quoteLogoURI = useMemo(() => {
|
||||
if (!quoteSymbol || !jupiterTokens.length) return ''
|
||||
const token = jupiterTokens.find((t) => t.symbol === quoteSymbol)
|
||||
|
@ -187,12 +202,6 @@ const AdvancedTradeForm = () => {
|
|||
if (!group || !mangoAccount) return
|
||||
setPlacingOrder(true)
|
||||
try {
|
||||
const orderType = tradeForm.ioc
|
||||
? Serum3OrderType.immediateOrCancel
|
||||
: tradeForm.postOnly
|
||||
? Serum3OrderType.postOnly
|
||||
: Serum3OrderType.limit
|
||||
|
||||
let baseSize = new Decimal(tradeForm.baseSize).toNumber()
|
||||
let price = new Decimal(tradeForm.price).toNumber()
|
||||
if (tradeForm.tradeType === 'Market') {
|
||||
|
@ -201,6 +210,11 @@ const AdvancedTradeForm = () => {
|
|||
}
|
||||
|
||||
if (selectedMarket instanceof Serum3Market) {
|
||||
const spotOrderType = tradeForm.ioc
|
||||
? Serum3OrderType.immediateOrCancel
|
||||
: tradeForm.postOnly
|
||||
? Serum3OrderType.postOnly
|
||||
: Serum3OrderType.limit
|
||||
const tx = await client.serum3PlaceOrder(
|
||||
group,
|
||||
mangoAccount,
|
||||
|
@ -209,7 +223,7 @@ const AdvancedTradeForm = () => {
|
|||
price,
|
||||
baseSize,
|
||||
Serum3SelfTradeBehavior.decrementTake,
|
||||
orderType,
|
||||
spotOrderType,
|
||||
Date.now(),
|
||||
10
|
||||
)
|
||||
|
@ -220,6 +234,35 @@ const AdvancedTradeForm = () => {
|
|||
title: 'Transaction successful',
|
||||
txid: tx,
|
||||
})
|
||||
} else if (selectedMarket instanceof PerpMarket) {
|
||||
const perpOrderType =
|
||||
tradeForm.tradeType === 'Market'
|
||||
? PerpOrderType.market
|
||||
: tradeForm.ioc
|
||||
? PerpOrderType.immediateOrCancel
|
||||
: tradeForm.postOnly
|
||||
? PerpOrderType.postOnly
|
||||
: PerpOrderType.limit
|
||||
const tx = await client.perpPlaceOrder(
|
||||
group,
|
||||
mangoAccount,
|
||||
selectedMarket.perpMarketIndex,
|
||||
tradeForm.side === 'buy' ? PerpOrderSide.bid : PerpOrderSide.ask,
|
||||
price,
|
||||
baseSize,
|
||||
undefined, // maxQuoteQuantity
|
||||
Date.now(),
|
||||
perpOrderType,
|
||||
undefined,
|
||||
undefined
|
||||
)
|
||||
actions.reloadMangoAccount()
|
||||
actions.fetchSerumOpenOrders()
|
||||
notify({
|
||||
type: 'success',
|
||||
title: 'Transaction successful',
|
||||
txid: tx,
|
||||
})
|
||||
}
|
||||
} catch (e: any) {
|
||||
notify({
|
||||
|
@ -342,7 +385,11 @@ const AdvancedTradeForm = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="mt-4 flex">
|
||||
<SpotSlider />
|
||||
{selectedMarket instanceof Serum3Market ? (
|
||||
<SpotSlider />
|
||||
) : (
|
||||
<PerpSlider />
|
||||
)}
|
||||
</div>
|
||||
<div className="flex flex-wrap px-5">
|
||||
{tradeForm.tradeType === 'Limit' ? (
|
||||
|
@ -381,20 +428,22 @@ const AdvancedTradeForm = () => {
|
|||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mt-4" id="trade-step-eight">
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content={t('trade:tooltip-enable-margin')}
|
||||
>
|
||||
<Checkbox
|
||||
checked={useMargin}
|
||||
onChange={(e) => setUseMargin(e.target.checked)}
|
||||
{selectedMarket instanceof Serum3Market ? (
|
||||
<div className="mt-4" id="trade-step-eight">
|
||||
<Tooltip
|
||||
delay={250}
|
||||
placement="left"
|
||||
content={t('trade:tooltip-enable-margin')}
|
||||
>
|
||||
{t('trade:margin')}
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<Checkbox
|
||||
checked={useMargin}
|
||||
onChange={(e) => setUseMargin(e.target.checked)}
|
||||
>
|
||||
{t('trade:margin')}
|
||||
</Checkbox>
|
||||
</Tooltip>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mt-6 flex px-4">
|
||||
<Button
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
import { PerpMarket, Serum3Market } from '@blockworks-foundation/mango-v4'
|
||||
import LeverageSlider from '@components/swap/LeverageSlider'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import Decimal from 'decimal.js'
|
||||
import { useCallback, useMemo } from 'react'
|
||||
import { notify } from 'utils/notifications'
|
||||
|
||||
const PerpSlider = () => {
|
||||
const side = mangoStore((s) => s.tradeForm.side)
|
||||
const selectedMarket = mangoStore((s) => s.selectedMarket.current)
|
||||
const mangoAccount = mangoStore((s) => s.mangoAccount.current)
|
||||
const tradeForm = mangoStore((s) => s.tradeForm)
|
||||
|
||||
const leverageMax = useMemo(() => {
|
||||
const group = mangoStore.getState().group
|
||||
if (!mangoAccount || !group || !selectedMarket) return 100
|
||||
if (!(selectedMarket instanceof PerpMarket)) return 100
|
||||
|
||||
try {
|
||||
if (side === 'buy') {
|
||||
return mangoAccount.getMaxQuoteForPerpBidUi(
|
||||
group,
|
||||
selectedMarket.perpMarketIndex
|
||||
)
|
||||
} else {
|
||||
return mangoAccount.getMaxBaseForPerpAskUi(
|
||||
group,
|
||||
selectedMarket.perpMarketIndex
|
||||
)
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('PerpSlider: ', e)
|
||||
notify({
|
||||
type: 'error',
|
||||
title: 'Error calculating max leverage.',
|
||||
})
|
||||
return 0
|
||||
}
|
||||
}, [side, selectedMarket, mangoAccount])
|
||||
|
||||
const handleSlide = useCallback((val: string) => {
|
||||
const set = mangoStore.getState().set
|
||||
|
||||
set((s) => {
|
||||
if (s.tradeForm.side === 'buy') {
|
||||
s.tradeForm.quoteSize = val
|
||||
|
||||
if (Number(s.tradeForm.price)) {
|
||||
s.tradeForm.baseSize = (
|
||||
parseFloat(val) / parseFloat(s.tradeForm.price)
|
||||
).toString()
|
||||
} else {
|
||||
s.tradeForm.baseSize = ''
|
||||
}
|
||||
} else if (s.tradeForm.side === 'sell') {
|
||||
s.tradeForm.baseSize = val
|
||||
|
||||
if (Number(s.tradeForm.price)) {
|
||||
s.tradeForm.quoteSize = (
|
||||
parseFloat(val) * parseFloat(s.tradeForm.price)
|
||||
).toString()
|
||||
}
|
||||
}
|
||||
})
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className="w-full px-4">
|
||||
<LeverageSlider
|
||||
amount={
|
||||
tradeForm.side === 'buy'
|
||||
? parseFloat(tradeForm.quoteSize)
|
||||
: parseFloat(tradeForm.baseSize)
|
||||
}
|
||||
leverageMax={leverageMax}
|
||||
onChange={handleSlide}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PerpSlider
|
Loading…
Reference in New Issue