mango-stats-v3/src/collectStats.ts

112 lines
3.4 KiB
TypeScript

import { Connection } from "@solana/web3.js"
import {
Config,
getMultipleAccounts,
GroupConfig,
I80F48,
IDS,
MangoClient,
PerpMarket,
PerpMarketLayout,
} from "@blockworks-foundation/mango-client"
import PerpMarketStats from "../models/perp_market_stats"
import SpotMarketStats from "../models/spot_market_stats"
const CLUSTER_URLS = [
{
name: "mainnet-beta",
url: "https://mango.rpcpool.com/",
websocket: "https://mango.rpcpool.com/",
},
{
name: "devnet",
url: "https://mango.devnet.rpcpool.com",
websocket: "https://api.devnet.solana.com",
},
]
type CLUSTER_TYPE = "devnet" | "mainnet-beta"
const cluster = (process.env.CLUSTER || "devnet") as CLUSTER_TYPE
const SECONDS = 1000
const statsInterval = 10 * SECONDS
const loadPerpMarkets = async (connection, groupConfig: GroupConfig) => {
const perpMarketPks = groupConfig.perpMarkets.map((p) => p.publicKey)
const allMarketAccountInfos = await getMultipleAccounts(connection, perpMarketPks)
return groupConfig.perpMarkets.map((config, i) => {
const decoded = PerpMarketLayout.decode(allMarketAccountInfos[i].accountInfo.data)
return new PerpMarket(config.publicKey, config.baseDecimals, config.quoteDecimals, decoded)
})
}
async function main() {
const clusterUrl = CLUSTER_URLS.find((c) => c.name === cluster)
if (!clusterUrl) return
const connection = new Connection(clusterUrl.url, "singleGossip")
const config = new Config(IDS)
const groupConfig = config.getGroup(cluster, "mango_test_v3.8")
console.log("1")
const client = new MangoClient(connection, groupConfig.mangoProgramId)
console.log("2")
const mangoGroup = await client.getMangoGroup(groupConfig.publicKey)
console.log("3")
await mangoGroup.loadRootBanks(connection)
console.log("4")
const spotMarketStats = groupConfig.spotMarkets.map((spotMarket, index) => {
const totalDeposits = mangoGroup.getUiTotalDeposit(index)
const totalBorrows = mangoGroup.getUiTotalBorrow(index)
return {
time: new Date(),
name: groupConfig.spotMarkets[index].name,
publicKey: spotMarket.publicKey.toString(),
mangoGroup: groupConfig.name,
totalDeposits: totalDeposits.toNumber(),
totalBorrows: totalBorrows.toNumber(),
depositRate: mangoGroup.getDepositRate(index).toNumber(),
borrowRate: mangoGroup.getBorrowRate(index).toNumber(),
utilization: totalDeposits.gt(I80F48.fromNumber(0)) ? totalBorrows.div(totalDeposits).toNumber() : 0,
baseOraclePrice: 0,
}
})
try {
await SpotMarketStats.bulkCreate(spotMarketStats)
console.log("spot stats inserted")
} catch (err) {
console.log("failed to insert spot stats", `${err}`)
}
const perpMarkets = await loadPerpMarkets(connection, groupConfig)
console.log("6")
const perpMarketStats = perpMarkets.map((perpMarket, index) => {
return {
time: new Date(),
name: groupConfig.perpMarkets[index].name,
publicKey: perpMarket.publicKey.toString(),
mangoGroup: groupConfig.name,
longFunding: perpMarket.longFunding.toNumber(),
shortFunding: perpMarket.shortFunding.toNumber(),
openInterest: perpMarket.openInterest.toNumber(),
baseOraclePrice: 0,
}
})
try {
await PerpMarketStats.bulkCreate(perpMarketStats)
console.log("perp stats inserted")
} catch (err) {
console.log("failed to insert spot stats", `${err}`)
}
setTimeout(main, statsInterval)
}
main()