Skip to content

Commit

Permalink
clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
callmephilip committed Nov 27, 2023
1 parent 1b6da45 commit 6ee81c1
Show file tree
Hide file tree
Showing 102 changed files with 291 additions and 55 deletions.
3 changes: 2 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ SUGAR_TOKENS_CACHE_MINUTES=10
# caching for Sugar LPs
SUGAR_LPS_CACHE_MINUTES=10
# caching for oracle pricing
ORACLE_PRICES_CACHE_MINUTES=10
ORACLE_PRICES_CACHE_MINUTES=10
UI_POOL_STATS_THUMBNAIL=https://i.imgur.com/lGbVYac.png
41 changes: 35 additions & 6 deletions bots/commander.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .data import LiquidityPool
from .data import LiquidityPool, LiquidityPoolEpoch
from .helpers import is_address
from .ui import PoolsDropdown, PoolStats

Expand All @@ -7,6 +7,8 @@


class _CommanderBot(commands.Bot):
"""Commander bot instance to handle / commands"""

def __init__(self):
intents = discord.Intents.default()
intents.message_content = True
Expand All @@ -22,21 +24,29 @@ async def on_ready(self):


def CommanderBot() -> commands.Bot:
# keep our commander as a singleton
return bot


async def on_select_pool(
response: discord.InteractionResponse,
interaction: discord.Interaction,
address_or_pool: str | LiquidityPool,
):
"""Handle pool selection and reply with a pool stats embed
Args:
interaction (discord.Interaction): chat interaction
address_or_pool (str | LiquidityPool): pool address or instance
"""
pool = (
await LiquidityPool.by_address(address_or_pool)
if isinstance(address_or_pool, str)
else address_or_pool
)
tvl = await LiquidityPool.tvl([pool])
await response.send_message(
await PoolStats().render(pool, tvl), suppress_embeds=True
pool_epoch = await LiquidityPoolEpoch.fetch_for_pool(pool.lp)
await interaction.response.send_message(
embed=await PoolStats(interaction.client.emojis).render(pool, tvl, pool_epoch)
)


Expand All @@ -45,11 +55,21 @@ async def on_select_pool(
address_or_query="Pool address or search query",
)
async def pool(interaction: discord.Interaction, address_or_query: str):
"""Pool command handler: show specific pool or pool selector
Args:
interaction (discord.Interaction): chat interaction
address_or_query (str): command input
"""
if is_address(address_or_query):
# if /pool receives specific pool address,
# show the pool immediately or show in error
# message if it does not exist

pool = await LiquidityPool.by_address(address_or_query)

if pool is not None:
await on_select_pool(interaction.response, pool)
await on_select_pool(interaction, pool)
else:
await interaction.response.send_message(
f"No pool found with this address: {address_or_query}"
Expand All @@ -58,6 +78,15 @@ async def pool(interaction: discord.Interaction, address_or_query: str):

pools = await LiquidityPool.search(address_or_query)

if len(pools) == 1:
# got exact match, show the pool
await on_select_pool(interaction, pools[0])
return

# search returned several pools, show them in a dropdown
await interaction.response.send_message(
"Choose a pool:", view=PoolsDropdown(pools=pools, callback=on_select_pool)
"Choose a pool:",
view=PoolsDropdown(
interaction=interaction, pools=pools, callback=on_select_pool
),
)
17 changes: 17 additions & 0 deletions bots/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,18 @@ async def search(cls, query: str, limit: int = 10) -> List["LiquidityPool"]:
def match_score(query: str, symbol: str):
return fuzz.token_sort_ratio(query, symbol)

query_lowercase = query.lower()
pools = await cls.get_pools()
pools = list(
filter(lambda p: p.token0 is not None and p.token1 is not None, pools)
)

# look for exact match first, i.e. we get proper pool symbol in query (case insensitive)
exact_match = list(filter(lambda p: p.symbol.lower() == query_lowercase, pools))

if len(exact_match) == 1:
return exact_match

pools_with_ratio = list(map(lambda p: (p, match_score(query, p.symbol)), pools))
pools_with_ratio.sort(key=lambda p: p[1], reverse=True)

Expand Down Expand Up @@ -401,6 +409,15 @@ async def fetch_latest(cls):

return result

@classmethod
async def fetch_for_pool(cls, pool_address: str) -> "LiquidityPoolEpoch":
pool_epochs = await cls.fetch_latest()
try:
a = normalize_address(pool_address)
return next(pe for pe in pool_epochs if pe.pool_address == a)
except Exception:
return None

@property
def total_fees(self) -> float:
return sum(map(lambda fee: fee.amount_in_stable, self.fees))
Expand Down
2 changes: 2 additions & 0 deletions bots/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@
ORACLE_PRICES_CACHE_MINUTES = int(os.environ["ORACLE_PRICES_CACHE_MINUTES"])

GOOD_ENOUGH_PAGINATION_LIMIT = 2000

UI_POOL_STATS_THUMBNAIL = os.environ["UI_POOL_STATS_THUMBNAIL"]
1 change: 1 addition & 0 deletions bots/ui/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from .pools import PoolsDropdown # noqa
from .pool_stats import PoolStats # noqa
from .emojis import Emojis # noqa
30 changes: 30 additions & 0 deletions bots/ui/emojis.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
from typing import Sequence
from discord import Emoji


class Emojis:
"""Loads all custom emojis associated with current server and
makes them available via get method"""

def __init__(self, emojis: Sequence[Emoji]):
"""Load all custom emojis
Args:
emojis (Sequence[Emoji]): custom emojis attached to a server
"""
self.emojis = {}
for emoji in emojis:
# based on: https://github.com/Rapptz/discord.py/issues/390
self.emojis[emoji.name] = str(emoji)

def get(self, name: str, fallback: str = "*") -> str:
"""Get custom emoji by name or return fallback string
Args:
name (str): name of the custom emoji to get
fallback (str, optional): fallback value to return. Defaults to "*".
Returns:
str: _description_
"""
return self.emojis[name] if name in self.emojis else fallback
Loading

0 comments on commit 6ee81c1

Please sign in to comment.