From c9f8e66904060af8893cd5143cde43a1c3ff1138 Mon Sep 17 00:00:00 2001 From: robcxyz Date: Wed, 7 Feb 2024 21:54:11 -0800 Subject: [PATCH] fix: add dex swaps endpoint --- .../ef669e9ed598_v0_2_3_add_swap_index.py | 29 +++++++++ balanced_backend/api/v1/endpoints/dex.py | 64 +++++++++++++++++++ balanced_backend/api/v1/router.py | 2 + balanced_backend/tables/dex.py | 2 +- 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 balanced_backend/alembic/versions/ef669e9ed598_v0_2_3_add_swap_index.py create mode 100644 balanced_backend/api/v1/endpoints/dex.py diff --git a/balanced_backend/alembic/versions/ef669e9ed598_v0_2_3_add_swap_index.py b/balanced_backend/alembic/versions/ef669e9ed598_v0_2_3_add_swap_index.py new file mode 100644 index 0000000..76f43fd --- /dev/null +++ b/balanced_backend/alembic/versions/ef669e9ed598_v0_2_3_add_swap_index.py @@ -0,0 +1,29 @@ +"""v0.2.3-add-swap-index + +Revision ID: ef669e9ed598 +Revises: c0be6c7b7b02 +Create Date: 2024-02-07 21:53:12.854330 + +""" +from alembic import op +import sqlalchemy as sa +import sqlmodel + + +# revision identifiers, used by Alembic. +revision = 'ef669e9ed598' +down_revision = 'c0be6c7b7b02' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.create_index(op.f('ix_dex_swaps_pool_id'), 'dex_swaps', ['pool_id'], unique=False) + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f('ix_dex_swaps_pool_id'), table_name='dex_swaps') + # ### end Alembic commands ### diff --git a/balanced_backend/api/v1/endpoints/dex.py b/balanced_backend/api/v1/endpoints/dex.py new file mode 100644 index 0000000..4db6286 --- /dev/null +++ b/balanced_backend/api/v1/endpoints/dex.py @@ -0,0 +1,64 @@ +from fastapi import APIRouter, Depends, Response, Query +from sqlalchemy.ext.asyncio import AsyncSession +from sqlmodel import select, func + +from balanced_backend.config import settings +from balanced_backend.db import get_session +from balanced_backend.tables.dex import DexSwap + +router = APIRouter() + + +@router.get("/dex/swaps") +async def swaps( + response: Response, + session: AsyncSession = Depends(get_session), + skip: int = Query(0), + limit: int = Query(100, gt=0, lt=101), + chain_id: int = Query(None), + transaction_hash: str = Query(None), + log_index: int = Query(None), + start_timestamp: int = Query(None), + end_timestamp: int = Query(None), + start_block_number: int = Query(None), + end_block_number: int = Query(None), + +) -> list[DexSwap]: + query = select(DexSwap).offset(skip).limit(limit).where( + DexSwap.chain_id == settings.CHAIN_ID) + query_count = select([func.count(DexSwap.chain_id)]).where( + DexSwap.chain_id == settings.CHAIN_ID) + + if transaction_hash: + query = query.where(DexSwap.transaction_hash == transaction_hash) + query_count = query_count.where(DexSwap.transaction_hash == transaction_hash) + if log_index: + query = query.where(DexSwap.log_index == log_index) + query_count = query.where(DexSwap.log_index == log_index) + if chain_id: + query = query.where(DexSwap.chain_id == chain_id) + query_count = query.where(DexSwap.chain_id == chain_id) + if start_timestamp: + query = query.where(DexSwap.timestamp >= start_timestamp) + query_count = query.where(DexSwap.timestamp >= start_timestamp) + if end_timestamp: + query = query.where(DexSwap.timestamp <= end_timestamp) + query_count = query.where(DexSwap.timestamp <= end_timestamp) + if start_block_number: + query = query.where(DexSwap.block_number >= start_block_number) + query_count = query.where(DexSwap.block_number >= start_block_number) + if end_block_number: + query = query.where(DexSwap.block_number <= end_block_number) + query_count = query.where(DexSwap.block_number <= end_block_number) + + result = await session.execute(query) + swaps = result.scalars().all() + + # # Return the count in header + # # TODO: Can't be cached and very expensive... 2M records + # result_count = await session.execute(query_count) + # total_count = str(result_count.scalars().all()[0]) + # response.headers["x-total-count"] = total_count + + response.headers["x-total-count"] = str(len(swaps)) + return swaps diff --git a/balanced_backend/api/v1/router.py b/balanced_backend/api/v1/router.py index 2f0025b..e57f0c8 100644 --- a/balanced_backend/api/v1/router.py +++ b/balanced_backend/api/v1/router.py @@ -10,6 +10,7 @@ coingecko, stats, contract_methods, + dex, ) api_router = APIRouter() @@ -23,3 +24,4 @@ api_router.include_router(coingecko.router, prefix='/coingecko', tags=["coingecko"]) api_router.include_router(stats.router) api_router.include_router(supply.router) +api_router.include_router(dex.router) diff --git a/balanced_backend/tables/dex.py b/balanced_backend/tables/dex.py index 549f01e..5cd8603 100644 --- a/balanced_backend/tables/dex.py +++ b/balanced_backend/tables/dex.py @@ -8,7 +8,7 @@ class DexSwap(SQLModel, table=True): log_index: int = Field(None, primary_key=True) timestamp: int = Field(None, index=True) block_number: int = Field(None, index=True) - pool_id: int = Field(None) + pool_id: int = Field(None, index=True) from_token: str = Field(None) to_token: str = Field(None)