Skip to content

Commit fa2c6fb

Browse files
authored
Merge pull request ilyarolf#111 from ilyarolf/develop
Develop
2 parents d17146e + bc79efa commit fa2c6fb

File tree

26 files changed

+707
-281
lines changed

26 files changed

+707
-281
lines changed

.env

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ DB_NAME = ""
88
DB_ENCRYPTION = ""
99
DB_PASS = ""
1010
NGROK_TOKEN = ""
11-
PAGE_ENTRIES = ""
12-
BOT_LANGUAGE = ""
13-
MULTIBOT = ""
14-
ETHPLORER_API_KEY = ""
15-
CURRENCY = ""
11+
PAGE_ENTRIES = "8"
12+
BOT_LANGUAGE = "en"
13+
MULTIBOT = "false"
14+
CURRENCY = "USD"
1615
RUNTIME_ENVIRONMENT = "DEV"
1716
WEBHOOK_SECRET_TOKEN = ""
18-
REDIS_HOST = ""
19-
REDIS_PASSWORD = ""
17+
KRYPTO_EXPRESS_API_KEY = ""
18+
KRYPTO_EXPRESS_API_URL = "https://kryptoexpress.pro/api"
19+
KRYPTO_EXPRESS_API_SECRET = ""
20+
REDIS_PASSWORD = ""
21+
REDIS_HOST = ""

bot.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,14 @@
1212
from db import create_db_and_tables
1313
import uvicorn
1414
from fastapi.responses import JSONResponse
15+
from processing.processing import processing_router
1516
from services.notification import NotificationService
1617

1718
redis = Redis(host=config.REDIS_HOST, password=config.REDIS_PASSWORD)
1819
bot = Bot(config.TOKEN, default=DefaultBotProperties(parse_mode=ParseMode.HTML))
1920
dp = Dispatcher(storage=RedisStorage(redis))
2021
app = FastAPI()
22+
app.include_router(processing_router)
2123

2224

2325
@app.post(config.WEBHOOK_PATH)

callbacks.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from aiogram.filters.callback_data import CallbackData
55

66
from enums.bot_entity import BotEntity
7+
from enums.cryptocurrency import Cryptocurrency
78
from utils.localizator import Localizator
89

910

@@ -160,8 +161,8 @@ def create(level: int, statistics_entity: StatisticsEntity | None = None,
160161

161162

162163
class WalletCallback(BaseCallback, prefix="wallet"):
163-
pass
164+
cryptocurrency: Cryptocurrency | None
164165

165166
@staticmethod
166-
def create(level: int):
167-
return WalletCallback(level=level)
167+
def create(level: int, cryptocurrency: Cryptocurrency | None = None):
168+
return WalletCallback(level=level, cryptocurrency=cryptocurrency)

config.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
PAGE_ENTRIES = int(os.environ.get("PAGE_ENTRIES"))
2828
BOT_LANGUAGE = os.environ.get("BOT_LANGUAGE")
2929
MULTIBOT = os.environ.get("MULTIBOT", False) == 'true'
30-
ETHPLORER_API_KEY = os.environ.get("ETHPLORER_API_KEY")
3130
CURRENCY = Currency(os.environ.get("CURRENCY"))
31+
KRYPTO_EXPRESS_API_KEY = os.environ.get("KRYPTO_EXPRESS_API_KEY")
32+
KRYPTO_EXPRESS_API_URL = os.environ.get("KRYPTO_EXPRESS_API_URL")
33+
KRYPTO_EXPRESS_API_SECRET = os.environ.get("KRYPTO_EXPRESS_API_SECRET")
3234
WEBHOOK_SECRET_TOKEN = os.environ.get("WEBHOOK_SECRET_TOKEN")
3335
REDIS_HOST = os.environ.get("REDIS_HOST")
3436
REDIS_PASSWORD = os.environ.get("REDIS_PASSWORD")

crypto_api/CryptoApiWrapper.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import aiohttp
2+
import config
3+
from enums.cryptocurrency import Cryptocurrency
4+
from enums.withdraw_type import WithdrawType
5+
from models.withdrawal import WithdrawalDTO
6+
7+
8+
class CryptoApiWrapper:
9+
LTC_API_BASENAME_TX = "https://litecoinspace.org/tx/"
10+
BTC_API_BASENAME_TX = "https://mempool.space/tx/"
11+
SOL_API_BASENAME_TX = "https://solscan.io/tx/"
12+
ETH_API_BASENAME_TX = "https://etherscan.io/tx/"
13+
BNB_API_BASENAME_TX = "https://bscscan.com/tx/"
14+
15+
@staticmethod
16+
async def fetch_api_request(url: str, params: dict | None = None, method: str = "GET", data: str | None = None,
17+
headers: dict | None = None) -> dict:
18+
async with aiohttp.ClientSession() as session:
19+
async with session.request(method, url, params=params, data=data, headers=headers) as response:
20+
if response.status == 200:
21+
data = await response.json()
22+
return data
23+
24+
@staticmethod
25+
async def get_crypto_prices() -> dict:
26+
url = f"https://api.coingecko.com/api/v3/simple/price"
27+
params = {
28+
"ids": "bitcoin,litecoin,solana,ethereum,binancecoin",
29+
"vs_currencies": "usd,eur,gbp,jpy,cad"
30+
}
31+
return await CryptoApiWrapper.fetch_api_request(url, params)
32+
33+
@staticmethod
34+
async def get_wallet_balance() -> dict:
35+
url = f"{config.KRYPTO_EXPRESS_API_URL}/wallet"
36+
headers = {
37+
"X-Api-Key": config.KRYPTO_EXPRESS_API_KEY
38+
}
39+
response = await CryptoApiWrapper.fetch_api_request(
40+
url,
41+
headers=headers
42+
)
43+
return {k: v for k, v in response.items() if v > 0}
44+
45+
@staticmethod
46+
async def withdrawal(cryptocurrency: Cryptocurrency, to_address: str, only_calculate: bool) -> WithdrawalDTO:
47+
url = f"{config.KRYPTO_EXPRESS_API_URL}/wallet/withdrawal"
48+
headers = {
49+
"X-Api-Key": config.KRYPTO_EXPRESS_API_KEY,
50+
"Content-Type": "application/json"
51+
}
52+
body = WithdrawalDTO(
53+
withdrawType=WithdrawType.ALL,
54+
cryptoCurrency=cryptocurrency.name,
55+
toAddress=to_address,
56+
onlyCalculate=only_calculate
57+
)
58+
response = await CryptoApiWrapper.fetch_api_request(
59+
url,
60+
method="POST",
61+
data=body.model_dump_json(),
62+
headers=headers
63+
)
64+
return WithdrawalDTO.model_validate(response)

docker-compose.yml

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,26 +19,8 @@ services:
1919
build:
2020
context: .
2121
container_name: 'AiogramShopBot'
22-
environment:
23-
WEBHOOK_PATH: "/"
24-
WEBAPP_HOST: "0.0.0.0" # Don't touch this
25-
WEBAPP_PORT: 5000 # Here your port
26-
TOKEN: "1234567890:QWER.....TYI" # Here your bot token from botfather
27-
NGROK_TOKEN: 'NGROK_TOKEN_HERE' # Here your ngrok token from ngrok.com
28-
ADMIN_ID_LIST: "12345678,87654321" # Telegram ID's for admins;
29-
SUPPORT_LINK: "https://t.me/YourUsername"
30-
DB_NAME: "database.db" # Here your database name
31-
DB_ENCRYPTION: "false" # DB encryption option
32-
DB_PASS: "1234567890" # Here your database password (Required only if DB_ENCRYPTION-"true”)
33-
PAGE_ENTRIES: 8 # Items per page
34-
BOT_LANGUAGE: "en" # The name of your file from the l10n folder without the .json suffix
35-
MULTIBOT: "false" # Allows the use of a multibot
36-
ETHPLORER_API_KEY: "" # API key from Ethplorer
37-
CURRENCY: "USD" # fiat currency
38-
RUNTIME_ENVIRONMENT: "PROD"
39-
WEBHOOK_SECRET_TOKEN: "1234567890" # Any string you want
40-
REDIS_HOST: "redis"
41-
REDIS_PASSWORD: "1234567890" # Any string you want
22+
env_file:
23+
- .env
4224
labels:
4325
caddy: YOUR-DOMAIN-GOES-HERE
4426
caddy.reverse_proxy: "bot:5000"

enums/cryptocurrency.py

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,37 @@
11
from enum import Enum
22

3+
import config
4+
35

46
class Cryptocurrency(str, Enum):
7+
BNB = "BNB"
58
BTC = "BTC"
69
LTC = "LTC"
10+
ETH = "ETH"
711
SOL = "SOL"
8-
USDT_TRC20 = "USDT_TRC20"
9-
USDT_ERC20 = "USDT_ERC20"
10-
USDC_ERC20 = "USDC_ERC20"
1112

12-
def get_balance_field(self) -> str:
13+
def get_divider(self):
1314
match self:
1415
case Cryptocurrency.BTC:
15-
return "btc_balance"
16+
return 8
1617
case Cryptocurrency.LTC:
17-
return "ltc_balance"
18+
return 8
19+
case Cryptocurrency.ETH:
20+
return 18
1821
case Cryptocurrency.SOL:
19-
return "sol_balance"
20-
case Cryptocurrency.USDT_TRC20:
21-
return "usdt_trc20_balance"
22-
case Cryptocurrency.USDT_ERC20:
23-
return "usdt_erc20_balance"
24-
case Cryptocurrency.USDC_ERC20:
25-
return "usdc_erc20_balance"
22+
return 9
23+
case Cryptocurrency.BNB:
24+
return 18
2625

27-
def get_address_field(self) -> str:
26+
def get_coingecko_name(self) -> str:
2827
match self:
2928
case Cryptocurrency.BTC:
30-
return "btc_address"
29+
return "bitcoin"
3130
case Cryptocurrency.LTC:
32-
return "ltc_address"
31+
return "litecoin"
32+
case Cryptocurrency.ETH:
33+
return "ethereum"
34+
case Cryptocurrency.BNB:
35+
return "binancecoin"
3336
case Cryptocurrency.SOL:
34-
return "sol_address"
35-
case Cryptocurrency.USDT_TRC20:
36-
return "trx_address"
37-
case _:
38-
return "eth_address"
37+
return "solana"

enums/payment.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from enum import Enum
2+
3+
4+
class PaymentType(Enum):
5+
DEPOSIT = "DEPOSIT"
6+
PAYMENT = "PAYMENT"

enums/withdraw_type.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from enum import Enum
2+
3+
4+
class WithdrawType(Enum):
5+
ALL = "ALL"
6+
SINGLE = "SINGLE"

handlers/admin/constants.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ class AdminAnnouncementStates(StatesGroup):
3535
class UserManagementStates(StatesGroup):
3636
balance_amount = State()
3737
user_entity = State()
38+
39+
40+
class WalletStates(StatesGroup):
41+
crypto_address = State()

0 commit comments

Comments
 (0)