load order books both from perp & spot

This commit is contained in:
Maximilian Schneider 2021-06-17 17:07:10 -04:00
parent 2307246dd0
commit 4d3dae3b1a
7 changed files with 78 additions and 93 deletions

View File

@ -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)

View File

@ -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>

View File

@ -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(() => {

View File

@ -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(() => {

View File

@ -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 }
}

View File

@ -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

View File

@ -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"