Skip to content

Commit

Permalink
feat(Markets): markets module supports get all market data by getMark…
Browse files Browse the repository at this point in the history
…etDataAll function
  • Loading branch information
DylanYang0523 committed Oct 11, 2022
1 parent 13f9a86 commit 9793502
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 6 deletions.
5 changes: 4 additions & 1 deletion src/core/PerpetualProtocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,10 @@ class PerpetualProtocol {
// this.provider = getRetryProvider(providerConfigs)
// TODO:clean up
console.log("provider", providerConfigs[0].rpcUrl)
this.provider = getProvider({ rpcUrl: providerConfigs[0].rpcUrl })
// this.provider = getProvider({ rpcUrl: providerConfigs[0].rpcUrl })
this.provider = getProvider({
rpcUrl: "https://twilight-small-butterfly.optimism.quiknode.pro/9054785eeae7ef809e1215354d835a0de381ccd4",
})
}

async init() {
Expand Down
135 changes: 131 additions & 4 deletions src/core/market/Markets.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
import Big from "big.js"

import { ContractName } from "../../contracts"
import { ArgumentError, TypeError } from "../../errors"
import { Channel, ChannelEventSource, DEFAULT_PERIOD } from "../../internal"
import { Pool } from "../../metadata"
import { assertExist, getTickerSymbol, invariant, isEmptyObject } from "../../utils"
import type { PerpetualProtocol } from "../PerpetualProtocol"
import { Market } from "./Market"
import {
assertExist,
bigNumber2BigAndScaleDown,
fromSqrtX96,
getTickerSymbol,
invariant,
isEmptyObject,
poll,
} from "../../utils"
import { ContractCall, MulticallReader } from "../contractReader/MulticallReader"
import { Market, MarketStatus } from "./Market"

import type { PerpetualProtocol } from "../PerpetualProtocol"
export interface MarketMap {
[key: string]: Market
}
Expand All @@ -20,11 +33,24 @@ export interface marketInfo {
tradingVolume: string // NOTE: Total accumulated from day 1.
tradingFee: string // NOTE: Total accumulated from day 1.
}
class Markets {

type MarketsEventName = "updateError" | "updated"

export interface MarketDataAll {
[key: string]: {
status: MarketStatus
markPrice: Big
indexPrice: Big
indexTwapPrice: Big
}
}

class Markets extends Channel<MarketsEventName> {
private readonly _perp: PerpetualProtocol
private readonly _marketMap: MarketMap

constructor(perp: PerpetualProtocol) {
super(perp.channelRegistry)
this._perp = perp
this._marketMap = this._getMarketMap()
}
Expand Down Expand Up @@ -88,9 +114,110 @@ class Markets {

return market
}

async getMarketsBaseQuoteAmount(marketsInfo: marketInfo[]): Promise<any> {
return this._perp.contractReader.getMarketsBaseTokenAndQuoteTokenAmount(marketsInfo)
}

// NOTE: call by Channel -> constructor
protected _getEventSourceMap() {
const fetchAndEmitUpdated = this.getMarketDataAll.bind(this)
const updateDataEventSource = new ChannelEventSource<MarketsEventName>({
eventSourceStarter: () => {
const { cancel } = poll(fetchAndEmitUpdated, this._perp.moduleConfigs?.market?.period || DEFAULT_PERIOD)
return cancel
},
initEventEmitter: () => fetchAndEmitUpdated(),
})

// TODO: eventName typing protection, should error when invalid eventName is provided
return {
updated: updateDataEventSource,
updateError: updateDataEventSource,
}
}

protected async getMarketDataAll() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const countMap = window.countMap
countMap["getMarketDataAll"] ? (countMap["getMarketDataAll"] += 1) : (countMap["getMarketDataAll"] = 1)
countMap.sum += 1

const contracts = this._perp.contracts
const multicallReader = new MulticallReader({ contract: this._perp.contracts.multicall2 })
// NOTE: We cover those functions of the contract reader (getIndexPrice, getIndexTwapPrice, getMarketPrice, isMarketClosed, isMarketPaused, getMarketStatus, getMarketData)
// NOTE: The function getPriceFeedAggregator is called by LimitOrderBook, we can add it later if it is necessary.
const callsMap: { [key: string]: ContractCall[] } = {}
Object.entries(this._marketMap).forEach(([tickerSymbol, market]) => {
const contractBaseToken = contracts.baseToken.attach(market.baseAddress)
const contractPool = contracts.pool.attach(market.poolAddress)
const calls: ContractCall[] = [
// NOTE: get index price
{
contract: contractBaseToken,
contractName: ContractName.BASE_TOKEN,
funcName: "getIndexPrice",
funcParams: [0],
},
// NOTE: get index twap price
{
contract: contractBaseToken,
contractName: ContractName.BASE_TOKEN,
funcName: "getIndexPrice",
funcParams: [15 * 60],
},
// NOTE: get market price
{
contract: contractPool,
contractName: ContractName.POOL,
funcName: "slot0",
funcParams: [],
},
// NOTE: get if the base token paused
{
contract: contractBaseToken,
contractName: ContractName.BASE_TOKEN,
funcName: "isPaused",
funcParams: [],
},
// NOTE: get if the base token closed
{
contract: contractBaseToken,
contractName: ContractName.BASE_TOKEN,
funcName: "isClosed",
funcParams: [],
},
]
callsMap[`${tickerSymbol}`] = calls
})
// NOTE: grad data
const data = await multicallReader.execute(Object.values(callsMap).flat(), {
failFirstByContract: false,
failFirstByClient: false,
})

// NOTE: data analysis
// TODO: error handling
const marketDataAll: MarketDataAll = {}
Object.entries(callsMap).forEach(([key, value]) => {
const dataChunk = data.splice(0, value.length)
const indexPrice = bigNumber2BigAndScaleDown(dataChunk[0])
const indexTwapPrice = bigNumber2BigAndScaleDown(dataChunk[1])
const markPrice = fromSqrtX96(dataChunk[2].sqrtPriceX96)
const isPaused = dataChunk[3]
const isClosed = dataChunk[4]
marketDataAll[`${key}`] = {
status: isClosed ? MarketStatus.CLOSED : isPaused ? MarketStatus.PAUSED : MarketStatus.ACTIVE,
markPrice,
indexPrice,
indexTwapPrice,
}
})

// NOTE: emit market data all
this.emit("updated", marketDataAll)
}
}

export { Markets }
2 changes: 1 addition & 1 deletion src/core/market/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type { MarketMap, GetMarketParams } from "./Markets"
export type { MarketMap, GetMarketParams, MarketDataAll } from "./Markets"
export { Markets } from "./Markets"
export { Market, MarketStatus } from "./Market"
export { FundingUpdated } from "./FundingUpdated"

0 comments on commit 9793502

Please sign in to comment.