diff --git a/dexs/ethereal-dex/index.ts b/dexs/ethereal-dex/index.ts new file mode 100644 index 0000000000..cc6d5b574d --- /dev/null +++ b/dexs/ethereal-dex/index.ts @@ -0,0 +1,55 @@ +import { SimpleAdapter, FetchOptions, FetchResult } from "../../adapters/types"; +import { CHAIN } from "../../helpers/chains"; + +const FEE_ACCURED_EVENT = "event FeeAccrued(address indexed account, bytes32 indexed subaccount, address token, uint256 feeAmount, uint256 balance, uint64 messageIdx)"; + +const ORDER_MATCHED_EVENT = "event PerpOrderMatched(uint32 indexed productId, address indexed maker, address indexed taker, bytes32 makerSubaccount, bytes32 takerSubaccount, uint8 makerSide, uint8 takerSide, uint128 fillQuantity, uint128 price, uint64 messageIdx)"; + +const EXCHANGE_GATEWAY = "0xB3cDC82035C495c484C9fF11eD5f3Ff6d342e3cc"; + +async function fetch(options: FetchOptions): Promise { + const dailyFees = options.createBalances(); + const dailyVolume = options.createBalances(); + + const feeAccuredLogs = await options.getLogs({ + target: EXCHANGE_GATEWAY, + eventAbi: FEE_ACCURED_EVENT + }); + + const orderMatchedLogs = await options.getLogs({ + target: EXCHANGE_GATEWAY, + eventAbi: ORDER_MATCHED_EVENT + }); + + feeAccuredLogs.forEach((fee: any) => { + dailyFees.addCGToken("ethena-usde", Number(fee.feeAmount) / 1e9); + }); + + orderMatchedLogs.forEach((order:any)=>{ + dailyVolume.addCGToken("ethena-usde",(Number(order.fillQuantity)/1e9)*(Number(order.price)/1e9)); + }); + + return { + dailyVolume, + dailyFees, + dailyRevenue: dailyFees, + dailyProtocolRevenue: dailyFees, + } +} + +const methodology = { + Volume: "Ethereal perp trade volume", + Fees: "All trading fees paid by users", + Revenue: "All the fees is revenue", + ProtocolRevenue: "All the revenue goes to protocol", +} + +const adapter: SimpleAdapter = { + version: 2, + fetch, + chains: [CHAIN.ETHEREAL], + methodology, + start: '2025-10-21' +} + +export default adapter; \ No newline at end of file diff --git a/helpers/chains.ts b/helpers/chains.ts index bcca12d3d7..840aecc315 100644 --- a/helpers/chains.ts +++ b/helpers/chains.ts @@ -272,4 +272,5 @@ export enum CHAIN { HIBACHI = "hibachi", SATORI = "satori", SHIBARIUM = "shibarium", + ETHEREAL = "ethereal", } diff --git a/open-interest/ethereal-oi.ts b/open-interest/ethereal-oi.ts new file mode 100644 index 0000000000..ce24fa2079 --- /dev/null +++ b/open-interest/ethereal-oi.ts @@ -0,0 +1,28 @@ +import { SimpleAdapter, FetchResult, FetchOptions } from "../adapters/types"; +import { CHAIN } from "../helpers/chains"; +import fetchUrl from "../utils/fetchURL"; + +async function fetch(_a: any, _b: any, _c: FetchOptions): Promise { + + const tradeData = (await fetchUrl("https://api.ethereal.trade/v1/product")).data; + + const marketPrice = (await fetchUrl(`https://api.ethereal.trade/v1/product/market-price?productIds=${tradeData.map((market: any) => market.id).join('&productIds=')}`)).data; + + const openInterestAtEnd = tradeData.reduce((acc: number, market: any) => { + const price = + ((marketPrice.find((priceEntry: any) => market.id === priceEntry.productId))?.oraclePrice || 0); + acc+= price * +(market.openInterest || 0); + return acc; + }, 0); + + return { + openInterestAtEnd, + } +} + +const adapter: SimpleAdapter = { + chains: [CHAIN.ETHEREAL], + fetch, + runAtCurrTime: true +} + +export default adapter; \ No newline at end of file