From f2ec21c4e0baf71b13e0c5de94d5a93e3c5e29ff Mon Sep 17 00:00:00 2001 From: 0xgnek <0xgnek@gmail.com> Date: Sat, 2 Mar 2024 16:49:45 +0000 Subject: [PATCH] add sushi-aptos --- dexs/sushi-aptos/index.ts | 96 +++++++++++++++++++++++++++++++++++++++ helpers/aptops.ts | 22 +++++++++ 2 files changed, 118 insertions(+) create mode 100644 dexs/sushi-aptos/index.ts create mode 100644 helpers/aptops.ts diff --git a/dexs/sushi-aptos/index.ts b/dexs/sushi-aptos/index.ts new file mode 100644 index 0000000000..d50c49fa76 --- /dev/null +++ b/dexs/sushi-aptos/index.ts @@ -0,0 +1,96 @@ +import { FetchOptions, FetchResultV2, FetchV2, SimpleAdapter } from "../../adapters/types"; +import { CHAIN } from "../../helpers/chains"; +import { APTOS_PRC, getResources } from '../../helpers/aptops'; +import { httpGet } from "../../utils/fetchURL"; +const plimit = require('p-limit'); +const limits = plimit(1); + +interface ISwapEventData { + type: string; + amount_x_in: string; + amount_x_out: string; + amount_y_in: string; + amount_y_out: string; + user: string; +} +const getToken = (i: string) => i.split('<')[1].replace('>', '').split(', '); +const account = '0x31a6675cbe84365bf2b0cbce617ece6c47023ef70826533bde5203d32171dc3c'; + +const fetchVolume: FetchV2 = async (options: FetchOptions): Promise => { + const fromTimestamp = options.fromTimestamp + const toTimestamp = options.toTimestamp; + const resources = await getResources(account); + const pools = resources.filter(e => e.type?.includes('swap::PairEventHolder')) + .map((e: any) => { + const [token0, token1] = getToken(e.type); + return { + type: e.type, + token0, + token1, + swap_events: { + counter: e.data.swap.counter, + creation_num: e.data.swap.guid.id.creation_num, + }, + timestamp: e.data.timestamp, + counter: Number(e.data.swap.counter), + } + }).sort((a, b) => b.counter - a.counter) + const logs_swap: ISwapEventData[] = (await Promise.all(pools.map(async pool => limits(() => getSwapEvent(pool, fromTimestamp, toTimestamp))))).flat() + const dailyVolume = options.createBalances(); + logs_swap.map((e: ISwapEventData) => { + const [token0, token1] = getToken(e.type); + dailyVolume.add(token0, e.amount_x_out) + dailyVolume.add(token1, e.amount_y_out) + }) + return { dailyVolume: dailyVolume } +} + +const getSwapEvent = async (pool: any, fromTimestamp: number, toTimestamp: number): Promise => { + const limit = 100; + const swap_events: ISwapEventData[] = []; + let start = Math.max(pool.swap_events.counter - limit, 0); + while (true) { + if (start < 0) break; + const getEventByCreation = `${APTOS_PRC}/v1/accounts/${account}/events/${pool.swap_events.creation_num}?start=${start}&limit=${limit}`; + try { + const event: any[] = await httpGet(getEventByCreation); + const listSequence: number[] = event.map(e => Number(e.sequence_number)); + const lastMin = Math.min(...listSequence); + if (!isFinite(lastMin)) break; + const lastVision = event.find(e => Number(e.sequence_number) === lastMin)?.version; + const urlBlock = `${APTOS_PRC}/v1/blocks/by_version/${lastVision}`; + const block = await httpGet(urlBlock); + const lastTimestamp = toUnixTime(block.block_timestamp); + const lastTimestampNumber = lastTimestamp; + if (lastTimestampNumber >= fromTimestamp && lastTimestampNumber <= toTimestamp) { + swap_events.push(...event); + } + if (lastTimestampNumber < fromTimestamp) { + break; + } + if (start === 0) break; + start = Math.max(lastMin - (limit + 1), 0); + } catch (e: any) { + break; + } + } + return swap_events.map((e: any) => ({ + ...e, + type: e.type, + ...e.data, + })); +} + +const toUnixTime = (timestamp: string) => Number((Number(timestamp) / 1e6).toString().split('.')[0]) + +const adapter: SimpleAdapter = { + adapter: { + [CHAIN.APTOS]: { + fetch: fetchVolume, + start: 1708992000, + } + }, + version: 2, +} + +export default adapter; diff --git a/helpers/aptops.ts b/helpers/aptops.ts new file mode 100644 index 0000000000..657ea9a5b3 --- /dev/null +++ b/helpers/aptops.ts @@ -0,0 +1,22 @@ +import { httpGet } from "../utils/fetchURL"; + +export const APTOS_PRC = 'https://aptos-mainnet.pontem.network'; + +const getResources = async (account: string): Promise => { + const data: any = [] + let lastData: any; + let cursor + do { + let url = `${APTOS_PRC}/v1/accounts/${account}/resources?limit=9999` + if (cursor) url += '&start=' + cursor + const res = await httpGet(url, undefined, { withMetadata: true }) + lastData = res.data + data.push(...lastData) + cursor = res.headers['x-aptos-cursor'] + } while (lastData.length === 9999) + return data +} + +export { + getResources +}