load order books both from perp & spot
This commit is contained in:
parent
2307246dd0
commit
4d3dae3b1a
|
@ -94,7 +94,7 @@ const getCumulativeOrderbookSide = (
|
|||
|
||||
export default function Orderbook({ depth = 8 }) {
|
||||
const markPrice = useMarkPrice()
|
||||
const [orderbook] = useOrderbook()
|
||||
const { orderbook } = useOrderbook()
|
||||
const { baseCurrency, quoteCurrency } = useMarket()
|
||||
|
||||
const currentOrderbookData = useRef(null)
|
||||
|
|
|
@ -7,7 +7,7 @@ const TVChartContainer = dynamic(
|
|||
)
|
||||
import { useEffect, useState } from 'react'
|
||||
import FloatingElement from '../components/FloatingElement'
|
||||
// import Orderbook from '../components/Orderbook'
|
||||
import Orderbook from '../components/Orderbook'
|
||||
// import MarginInfo from './MarginInfo'
|
||||
import MarginBalances from './MarginBalances'
|
||||
// import TradeForm from './TradeForm'
|
||||
|
@ -101,7 +101,7 @@ const TradePageGrid = () => {
|
|||
<TVChartContainer />
|
||||
</FloatingElement>
|
||||
</div>
|
||||
<div key="orderbook">{/* <Orderbook /> */}</div>
|
||||
<div key="orderbook">{<Orderbook />}</div>
|
||||
<div key="tradeForm">{/* <TradeForm /> */}</div>
|
||||
<div key="marginInfo">{/* <MarginInfo /> */}</div>
|
||||
<div key="userInfo">{/* <UserInfo /> */}</div>
|
||||
|
|
|
@ -7,23 +7,20 @@ import useMangoStore from '../stores/useMangoStore'
|
|||
// import useSerumStore from '../stores/useSerumStore'
|
||||
// import useMarketList from './useMarketList'
|
||||
import useInterval from './useInterval'
|
||||
import { PerpMarket } from '@blockworks-foundation/mango-client'
|
||||
|
||||
const SECONDS = 1000
|
||||
// const _SLOW_REFRESH_INTERVAL = 60 * SECONDS
|
||||
|
||||
// const mangoGroupMarketsSelector = (s) => s.selectedMangoGroup.markets
|
||||
// const websocketConnectionSelector = (s) => s.connection.websocket
|
||||
// const selectedMarketKindSelector = (s) => s.selectedMarket.kind
|
||||
const selectedMarketAddressSelector = (s) => s.selectedMarket.address
|
||||
|
||||
const useHydrateStore = () => {
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
// const setSerumStore = useSerumStore((s) => s.set)
|
||||
// const marketsForSelectedMangoGroup = useMangoStore(mangoGroupMarketsSelector)
|
||||
// const websocketConnection = useMangoStore(websocketConnectionSelector)
|
||||
const selectedMarketAddress = useMangoStore(selectedMarketAddressSelector)
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const { connection, dexProgramId } = useConnection()
|
||||
const groupConfig = useMangoStore((s) => s.selectedMangoGroup.config)
|
||||
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
||||
const mangoClient = useMangoStore((s) => s.mangoClient);
|
||||
|
||||
const { connection } = useConnection()
|
||||
// const { marketList } = useMarketList()
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -36,11 +33,12 @@ const useHydrateStore = () => {
|
|||
|
||||
// load the selected market and orderbook
|
||||
useEffect(() => {
|
||||
if (marketConfig.kind === 'spot') {
|
||||
Market.load(
|
||||
connection,
|
||||
new PublicKey(selectedMarketAddress),
|
||||
marketConfig.key,
|
||||
{},
|
||||
dexProgramId
|
||||
groupConfig.serum_program_id
|
||||
)
|
||||
.then(async (market) => {
|
||||
const bidAccount = market['_decoded'].bids
|
||||
|
@ -48,10 +46,11 @@ const useHydrateStore = () => {
|
|||
const askAccount = market['_decoded'].asks
|
||||
const askInfo = await connection.getAccountInfo(askAccount)
|
||||
|
||||
console.log('spot', market, bidAccount.toString(), bidInfo, askAccount.toString(), askInfo);
|
||||
setMangoStore((state) => {
|
||||
state.selectedMarket.current = market
|
||||
state.accountInfos[askAccount.toString()] = askInfo
|
||||
state.accountInfos[bidAccount.toString()] = bidInfo
|
||||
state.selectedMarket.askInfo = askInfo
|
||||
state.selectedMarket.bidInfo = bidInfo
|
||||
})
|
||||
})
|
||||
.catch((e) => {
|
||||
|
@ -61,31 +60,21 @@ const useHydrateStore = () => {
|
|||
type: 'error',
|
||||
})
|
||||
})
|
||||
}, [selectedMarketAddress])
|
||||
} else {
|
||||
mangoClient.getPerpMarket(marketConfig.key).then(async (market) => {
|
||||
const bidInfo = await connection.getAccountInfo(market.bids);
|
||||
const askInfo = await connection.getAccountInfo(market.asks);
|
||||
|
||||
// // load all markets for mangoGroup
|
||||
// useEffect(() => {
|
||||
// Promise.all(
|
||||
// marketList.map((mkt) => {
|
||||
// return Market.load(connection, mkt.address, {}, mkt.programId)
|
||||
// })
|
||||
// ).then((markets) => {
|
||||
// setMangoStore((state) => {
|
||||
// state.selectedMarket.current = markets[0]
|
||||
// markets.forEach((market) => {
|
||||
// state.selectedMangoGroup.markets[market.publicKey.toString()] = market
|
||||
// const bidAcctAddress = market['_decoded'].bids.toString()
|
||||
// if (!(bidAcctAddress in state.accountInfos)) {
|
||||
// state.accountInfos[bidAcctAddress] = null
|
||||
// }
|
||||
// const askAcctAddress = market['_decoded'].asks.toString()
|
||||
// if (!(askAcctAddress in state.accountInfos)) {
|
||||
// state.accountInfos[askAcctAddress] = null
|
||||
// }
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }, [marketList])
|
||||
console.log('perp', market, market.bids.toString(), bidInfo, market.asks.toString(), askInfo);
|
||||
|
||||
setMangoStore((state) => {
|
||||
state.selectedMarket.current = market
|
||||
state.selectedMarket.askInfo = askInfo
|
||||
state.selectedMarket.bidInfo = bidInfo
|
||||
})
|
||||
});
|
||||
}
|
||||
}, [connection, mangoClient, marketConfig, groupConfig, setMangoStore])
|
||||
|
||||
// // hydrate orderbook with all markets in mango group
|
||||
// useEffect(() => {
|
||||
|
|
|
@ -21,7 +21,7 @@ export default function useMarkPrice() {
|
|||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
const markPrice = useMangoStore((s) => s.selectedMarket.markPrice)
|
||||
|
||||
const [orderbook] = useOrderbook()
|
||||
const orderbook = useOrderbook()
|
||||
const trades = useTrades()
|
||||
|
||||
useEffect(() => {
|
||||
|
|
|
@ -2,6 +2,8 @@ import { useEffect, useMemo } from 'react'
|
|||
import { Orderbook, Market } from '@project-serum/serum'
|
||||
import useMarket from './useMarket'
|
||||
import useMangoStore from '../stores/useMangoStore'
|
||||
import { BookSide, BookSideLayout, PerpMarket } from '@blockworks-foundation/mango-client'
|
||||
import { AccountInfo } from '@solana/web3.js'
|
||||
|
||||
export function useAccountData(publicKey) {
|
||||
const account = publicKey ? publicKey.toString() : null
|
||||
|
@ -9,45 +11,36 @@ export function useAccountData(publicKey) {
|
|||
return accountInfo && Buffer.from(accountInfo.data)
|
||||
}
|
||||
|
||||
export function useOrderbookAccounts(market: Market) {
|
||||
// @ts-ignore
|
||||
const bidData = useAccountData(market && market._decoded.bids)
|
||||
// @ts-ignore
|
||||
const askData = useAccountData(market && market._decoded.asks)
|
||||
return {
|
||||
bidOrderbook: market && bidData ? Orderbook.decode(market, bidData) : null,
|
||||
askOrderbook: market && askData ? Orderbook.decode(market, askData) : null,
|
||||
function decodeBook(market, accInfo: AccountInfo<Buffer>): number[][] {
|
||||
if (market && accInfo) {
|
||||
const depth = 20;
|
||||
if (market instanceof Market) {
|
||||
const book = Orderbook.decode(market, accInfo.data);
|
||||
return book.getL2(depth).map(([price, size]) => [price, size])
|
||||
} else if (market instanceof PerpMarket) {
|
||||
const book = new BookSide(null, market, BookSideLayout.decode(accInfo.data));
|
||||
return book.getL2(depth).map(([price, size]) => [price, size])
|
||||
}
|
||||
} else {
|
||||
return [[]]
|
||||
}
|
||||
}
|
||||
|
||||
export default function useOrderbook(
|
||||
depth = 20
|
||||
): [{ bids: number[][]; asks: number[][] }, boolean] {
|
||||
export default function useOrderbook():
|
||||
{ bids: number[][]; asks: number[][] } {
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
const { market } = useMarket()
|
||||
const { bidOrderbook, askOrderbook } = useOrderbookAccounts(market)
|
||||
const market = useMangoStore((state) => state.selectedMarket.current)
|
||||
const askInfo = useMangoStore((state) => state.selectedMarket.askInfo)
|
||||
const bidInfo = useMangoStore((state) => state.selectedMarket.bidInfo)
|
||||
|
||||
const bids = useMemo(
|
||||
() =>
|
||||
!bidOrderbook || !market
|
||||
? []
|
||||
: bidOrderbook.getL2(depth).map(([price, size]) => [price, size]),
|
||||
[bidOrderbook, depth, market]
|
||||
)
|
||||
|
||||
const asks = useMemo(
|
||||
() =>
|
||||
!askOrderbook || !market
|
||||
? []
|
||||
: askOrderbook.getL2(depth).map(([price, size]) => [price, size]),
|
||||
[askOrderbook, depth, market]
|
||||
)
|
||||
const bids = useMemo(() => decodeBook(market, bidInfo), [bidInfo, market])
|
||||
const asks = useMemo(() => decodeBook(market, askInfo), [askInfo, market])
|
||||
|
||||
useEffect(() => {
|
||||
setMangoStore((state) => {
|
||||
state.selectedMarket.orderBook = [{ bids, asks }, !!bids || !!asks]
|
||||
state.selectedMarket.orderBook = {bids, asks}
|
||||
})
|
||||
}, [bids, asks])
|
||||
}, [bids, asks, setMangoStore])
|
||||
|
||||
return [{ bids, asks }, !!bids || !!asks]
|
||||
return { bids, asks }
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
TokenAccount,
|
||||
nativeToUi,
|
||||
MerpsCache,
|
||||
PerpMarket,
|
||||
} from '@blockworks-foundation/mango-client'
|
||||
// import { SRM_DECIMALS } from '@project-serum/serum/lib/token-instructions'
|
||||
import { AccountInfo, Connection, PublicKey, TokenAmount } from '@solana/web3.js'
|
||||
|
@ -106,9 +107,11 @@ interface MangoStore extends State {
|
|||
config: MarketConfig
|
||||
name: string
|
||||
address: string
|
||||
current: Market | null
|
||||
current: Market | PerpMarket | null
|
||||
mangoProgramId: number | null
|
||||
markPrice: number
|
||||
askInfo: AccountInfo<Buffer> | null
|
||||
bidInfo: AccountInfo<Buffer> | null
|
||||
orderBook: any[]
|
||||
}
|
||||
mangoClient: MangoClient
|
||||
|
@ -265,7 +268,7 @@ const useMangoStore = create<MangoStore>((set, get) => ({
|
|||
.slice()
|
||||
.sort(
|
||||
(a, b) =>
|
||||
(a.publicKey.toBase58() > b.publicKey.toBase58() && 1) || -1
|
||||
a.publicKey.toBase58() > b.publicKey.toBase58() ? 1 : -1
|
||||
)
|
||||
set((state) => {
|
||||
state.marginAccounts = sortedAccounts
|
||||
|
|
|
@ -995,7 +995,7 @@
|
|||
|
||||
"@blockworks-foundation/mango-client@git+ssh://git@github.com/blockworks-foundation/merps-ts#ts/ui-exports":
|
||||
version "0.0.0"
|
||||
resolved "git+ssh://git@github.com/blockworks-foundation/merps-ts#62854b395fa6eee3c4092dfd90e892fa8ae52517"
|
||||
resolved "git+ssh://git@github.com/blockworks-foundation/merps-ts#2bc25e6ba4a76b5acc57fd642e2cfbef7352717c"
|
||||
dependencies:
|
||||
"@project-serum/serum" "^0.13.38"
|
||||
"@project-serum/sol-wallet-adapter" "^0.2.0"
|
||||
|
|
Loading…
Reference in New Issue