-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
5,993 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
DISCORD_APP_NAME= | ||
DISCORD_APP_ID= | ||
DISCORD_PUBLIC_KEY= | ||
DISCORD_SECRET= | ||
DISCORD_BOT_TOKEN= |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import os | ||
import pprint | ||
import requests | ||
from dotenv import load_dotenv | ||
load_dotenv("../../.env", verbose=True) | ||
|
||
|
||
def register_discord_slash_command(): | ||
# This is an example CHAT_INPUT or Slash Command, with a type of 1 | ||
url = f"https://discord.com/api/v8/applications/{os.getenv('DISCORD_APP_ID')}/commands" | ||
|
||
json = { | ||
"name": "sol", | ||
"type": 1, | ||
"description": "Get Solana ecosystem DeFi token updates", | ||
"options": [] | ||
} | ||
|
||
# For authorization, you can use either your bot token | ||
headers = { | ||
"Authorization": f"Bot {os.getenv('DISCORD_BOT_TOKEN')}" | ||
} | ||
|
||
r = requests.post(url, headers=headers, json=json) | ||
|
||
pprint.pprint(vars(r)) | ||
|
||
|
||
if __name__ == '__main__': | ||
register_discord_slash_command() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import json | ||
import os | ||
from utils.environment import init_env | ||
from nacl.signing import VerifyKey | ||
from nacl.exceptions import BadSignatureError | ||
|
||
PING_PONG = {"type": 1} | ||
RESPONSE_TYPES = { | ||
"PONG": 1, | ||
"ACK_NO_SOURCE": 2, | ||
"MESSAGE_NO_SOURCE": 3, | ||
"MESSAGE_WITH_SOURCE": 4, | ||
"ACK_WITH_SOURCE": 5 | ||
} | ||
|
||
|
||
def handler(event, context): | ||
""" | ||
Query the Pyth price feed | ||
""" | ||
logger = init_env() | ||
logger.info('RUNNING LAMBDA FUNCTION... inputs: ') | ||
# verify the signature | ||
try: | ||
verify_signature(event) | ||
except BadSignatureError as e: | ||
raise Exception(f"[UNAUTHORIZED] Invalid request signature: {e}") | ||
|
||
# check if message is a ping | ||
body = event.get('body-json') | ||
if ping_pong(body): | ||
return PING_PONG | ||
|
||
# dummy return | ||
return { | ||
"type": RESPONSE_TYPES['MESSAGE_NO_SOURCE'], | ||
"data": { | ||
"tts": False, | ||
"content": "BEEP BOOP", | ||
"embeds": [], | ||
"allowed_mentions": [] | ||
} | ||
} | ||
|
||
# return { | ||
# "isBase64Encoded": "false", | ||
# "statusCode": "200", | ||
# "body": json.dumps({"data": "bleep boop"}) | ||
# } | ||
|
||
|
||
def verify_signature(event): | ||
raw_body = event.get("rawBody") | ||
auth_sig = event['params']['header'].get('x-signature-ed25519') | ||
auth_ts = event['params']['header'].get('x-signature-timestamp') | ||
|
||
message = auth_ts.encode() + raw_body.encode() | ||
verify_key = VerifyKey(bytes.fromhex(os.getenv('DISCORD_PUBLIC_KEY'))) | ||
verify_key.verify(message, bytes.fromhex(auth_sig)) # raises an error if unequal | ||
|
||
|
||
def ping_pong(body): | ||
if body.get("type") == 1: | ||
return True | ||
return False | ||
|
||
|
||
if os.getenv('AWS_EXECUTION_ENV') is None: | ||
handler({'params': {'header': {"Authorization": f"Bot {os.getenv('DISCORD_BOT_TOKEN')}"}}}, {}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
aiodns==3.0.0 | ||
aiohttp==3.8.1 | ||
aiosignal==1.2.0 | ||
async-timeout==4.0.2 | ||
attrs==21.4.0 | ||
backoff==1.11.1 | ||
base58==2.1.1 | ||
certifi==2021.10.8 | ||
cffi==1.15.0 | ||
charset-normalizer==2.0.10 | ||
dnspython==2.1.0 | ||
flake8==4.0.1 | ||
frozenlist==1.2.0 | ||
idna==3.3 | ||
loguru==0.5.3 | ||
lxml==4.7.1 | ||
mccabe==0.6.1 | ||
multidict==5.2.0 | ||
numpy==1.22.0 | ||
pandas==1.3.4 | ||
pycares==4.1.2 | ||
pycodestyle==2.8.0 | ||
pycoingecko==2.2.0 | ||
pycparser==2.21 | ||
pyflakes==2.4.0 | ||
pythclient==0.0.2 | ||
python-dateutil==2.8.2 | ||
python-dotenv==0.19.2 | ||
pytrends==4.7.3 | ||
pytz==2021.3 | ||
requests==2.27.1 | ||
six==1.16.0 | ||
typing_extensions==4.0.1 | ||
urllib3==1.26.8 | ||
yarl==1.7.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import asyncio | ||
import pandas as pd | ||
from pythclient.pythclient import PythClient | ||
from pythclient.utils import get_key | ||
from helpers import \ | ||
derive_index, \ | ||
get_unix_timestamps, \ | ||
limit_to_solana_tokens, \ | ||
validate_price_status | ||
pd.set_option('display.max_columns', 500) | ||
|
||
|
||
async def main(): | ||
v2_first_mapping_account_key = get_key('devnet', 'mapping') | ||
v2_program_key = get_key('devnet', 'program') | ||
async with PythClient( | ||
first_mapping_account_key=v2_first_mapping_account_key, | ||
program_key=v2_program_key or None, | ||
) as c: | ||
await c.refresh_all_prices() | ||
solana_products = limit_to_solana_tokens(await c.get_products()) | ||
solana_products_prices = list() | ||
for sp in solana_products: | ||
valid_prices = validate_price_status(await sp.get_prices()) | ||
if valid_prices is not None: | ||
solana_products_prices.append(valid_prices) | ||
|
||
idx = derive_index(solana_products_prices) | ||
# | ||
# token_names: list = list(idx.keys()) | ||
# trends_df = get_trends_df(token_names) | ||
# print(trends_df) | ||
get_unix_timestamps() | ||
|
||
if __name__ == '__main__': | ||
asyncio.run(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
certifi==2021.10.8 | ||
cffi==1.15.0 | ||
charset-normalizer==2.0.10 | ||
idna==3.3 | ||
pycparser==2.21 | ||
PyNaCl==1.5.0 | ||
python-dotenv==0.19.2 | ||
requests==2.27.1 | ||
urllib3==1.26.8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
class SolanaTokens: | ||
with open('../../../scripts/solana_tokens.txt', 'r') as txt: | ||
tokens = list() | ||
for token in txt.read().splitlines(): | ||
tokens.append(token.replace('\"', '').rstrip(',')) | ||
BASE = tokens | ||
TOP = { | ||
'SOL', | ||
'RAY', | ||
'SRM', | ||
'MNGO', | ||
'ATLAS', | ||
'AURY', | ||
'FIDA', | ||
'SAMO', | ||
'OXY', | ||
'SLRS', | ||
'STEP', | ||
} | ||
EXTENDED = { | ||
'SOL', 'SRM', 'MSOL', 'RAY', 'MNGO', 'ATLAS', 'FIDA', 'AURY', 'IN', 'OXY', 'KIN', 'SAMO', 'SLIM', | ||
'JET', 'ORCA', 'STEP', 'TULIP', 'SLRS', 'LIKE', 'DXL', 'MAPS', 'RIN', 'PRISM', 'SNY', 'PORT', 'COPE', 'MER', | ||
'CYS', 'MEDIA', 'LIQ', 'FAB', 'IVN', 'CRP', 'SUNNY', 'SWARM', 'MOLA', 'SAIL', 'HOLY', 'KURO', 'CATO', 'GST', | ||
'GSAIL', 'ROPE', 'SLX', 'SOLAB', 'SOLA', 'NAXAR', 'ASH', 'FRIES', 'DATE', 'SOLAPE', 'STR', 'APEX', 'SOLUM', | ||
'SWOLE', 'GOFX', 'SOLPAD', 'INU', 'UPS', 'UXP', 'KITTY', 'NEKI', 'BASIS', 'SECO', 'RACEFI', 'BOP', 'ISOLA', | ||
'FTR', 'GRAPE', 'SHILL', 'WOOF', 'OXS', 'NINJA', 'PRT', 'SCNSOL', 'POLIS', 'DFL' | ||
} | ||
TOP_20 = { | ||
'SOL', 'LINK', 'GRT', 'REN', | ||
'RAY', 'INJ', 'MNGO', 'BAND', | ||
'FIDA', 'DFL', 'DIA', 'RAMP', | ||
'PRQ', 'FRONT', 'OOE', 'SLRS', | ||
'SNY', 'SLND', 'UPS', 'CYS', | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import logging | ||
import os | ||
import sys | ||
import threading | ||
from dotenv import load_dotenv | ||
|
||
thread_local = threading.local() | ||
|
||
|
||
class PathTruncatingFormatter(logging.Formatter): | ||
def format(self, record): | ||
"""Logging Formatter subclass to truncate the pathname to the two innermost directories.""" | ||
if 'pathname' in record.__dict__.keys(): | ||
fullpath = record.pathname | ||
pathparts = fullpath.split('/') | ||
if len(pathparts) >= 2: | ||
trunc_path = './{}/{}'.format(pathparts[-2], pathparts[-1]) | ||
else: | ||
trunc_path = fullpath | ||
record.pathname = trunc_path | ||
|
||
return super(PathTruncatingFormatter, self).format(record) | ||
|
||
|
||
def init_env(): | ||
if os.getenv('AWS_EXECUTION_ENV') is None: | ||
print('Operating in local context, loading .env file...') | ||
load_dotenv("../../../.env", verbose=True) | ||
else: | ||
print('Operating in Lambda context...') | ||
|
||
logger = init_logger() | ||
|
||
return logger | ||
|
||
|
||
def init_logger(): | ||
logger = getattr(thread_local, 'logger', None) | ||
if logger is not None: | ||
return logger | ||
|
||
if os.getenv('LOCAL_LOG_FORMAT') is None: | ||
local_log_format = \ | ||
'%(asctime)-26s [%(levelname)-5s] %(name)-25s %(pathname)s:%(lineno)s %(message)s' | ||
else: | ||
local_log_format = os.getenv('LOCAL_LOG_FORMAT') | ||
aws_log_format = '[%(levelname)s] %(name)-25s %(pathname)s:%(lineno)s %(message)s' | ||
|
||
log_level = logging.INFO | ||
|
||
if os.getenv('AWS_EXECUTION_ENV') is None: | ||
# NOTE: Local Dev, this formatter will be respected | ||
new_format = local_log_format | ||
logging.basicConfig(stream=sys.stdout, | ||
format=new_format, | ||
level=log_level) | ||
else: | ||
# NOTE: AWS has already mutated the logger, so we might want to adjust it. | ||
new_format = aws_log_format | ||
logging.basicConfig(format=aws_log_format, | ||
level=log_level) | ||
|
||
for h in logging.root.handlers: | ||
h.setFormatter(PathTruncatingFormatter(new_format)) | ||
|
||
# Our default level is WARN... | ||
logging.root.setLevel(logging.WARN) | ||
|
||
# | ||
# This will adjust all logging to DEBUG. It's very loud. | ||
# However, you can see all subsystems and then selectively enable the | ||
# various subsystems you really want verbose logging out of. | ||
# | ||
# logging.root.setLevel(logging.DEBUG) | ||
# | ||
|
||
logger = logging.getLogger('') | ||
logger.setLevel(log_level) | ||
logger.info('Initialized Logger...') | ||
|
||
# These are some common loggers that can be enabled. | ||
# urllib3.connectionpool | ||
# boto3.resources.factory | ||
# botocore.hooks | ||
# botocore.utils | ||
# botocore.parsers | ||
# botocore.endpoint | ||
# botocore.auth | ||
# botocore.retryHandler | ||
# botocore.retries.standard | ||
|
||
# | ||
# Enable the retry handler, because we should not really have any. | ||
# | ||
logging.getLogger('botocore.retries.standard').setLevel(logging.INFO) | ||
logging.getLogger('botocore.retryHandler').setLevel(logging.INFO) | ||
|
||
# | ||
# This will enable the aws client debug level to be louder. | ||
# | ||
# logging.getLogger('boto3').setLevel(logging.DEBUG) | ||
return logger |
Oops, something went wrong.