File size: 9,049 Bytes
65dca5a 70624fc 65dca5a 63ef879 65dca5a e8b3130 65dca5a 49650a3 65dca5a 5daaff6 65dca5a 49650a3 65dca5a |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 |
"""
Extol Wallet & Payment Integration for DragMusic Bot
Commands:
/addapi <api_key> (private chat only)
/addextol <address>
/removeextol
/payextol <amount>
/checkextol
/extolbal
/sendextol <to_address> <amount>
"""
import os
import httpx
from pyrogram import filters
from DragMusic import app
from DragMusic.utils.database import mongodb
from pyrogram.types import Message
from datetime import datetime
from pyrogram.enums import ParseMode
API_BASE_URL = "https://marketapi.animerealms.org"
api_keys_collection = mongodb.iac_api_keys
addresses_collection = mongodb.iac_extol_addresses
payments_collection = mongodb.iac_payments
# Async helpers for MongoDB
async def set_user_api_key(user_id: int, api_key: str):
await api_keys_collection.update_one(
{"user_id": user_id},
{"$set": {"api_key": api_key}},
upsert=True
)
async def get_user_api_key(user_id: int):
doc = await api_keys_collection.find_one({"user_id": user_id})
return doc["api_key"] if doc and "api_key" in doc else None
async def set_user_address(user_id: int, address: str):
await addresses_collection.update_one(
{"user_id": user_id},
{"$set": {"address": address}},
upsert=True
)
async def get_user_address(user_id: int):
doc = await addresses_collection.find_one({"user_id": user_id})
return doc["address"] if doc and "address" in doc else None
async def remove_user_address(user_id: int):
await addresses_collection.delete_one({"user_id": user_id})
async def set_last_payment_id(user_id: int, payment_id: str):
await payments_collection.update_one(
{"user_id": user_id},
{"$set": {"last_payment_id": payment_id}},
upsert=True
)
async def get_last_payment_id(user_id: int):
doc = await payments_collection.find_one({"user_id": user_id})
return doc["last_payment_id"] if doc and "last_payment_id" in doc else None
async def save_payment(user_id: int, payment_id: str, address: str, amount: float, payment_url: str):
await payments_collection.insert_one({
"user_id": user_id,
"payment_id": payment_id,
"address": address,
"amount": amount,
"payment_url": payment_url,
"created_at": datetime.utcnow()
})
async def get_user_payments(user_id: int, limit: int = 10):
cursor = payments_collection.find({"user_id": user_id}).sort("created_at", -1).limit(limit)
return await cursor.to_list(length=limit)
# /addapi <api_key> (private chat only)
@app.on_message(filters.command("addapi") & filters.private)
async def set_api_key_handler(client, message: Message):
args = message.text.split()
if len(args) != 2:
await message.reply_text("Usage: /addapi <your_api_key>")
return
await set_user_api_key(message.from_user.id, args[1])
await message.reply_text("β
Extol API Key set successfully.")
# Helper to check API key
async def check_api_key(message: Message):
user_id = message.from_user.id
api_key = await get_user_api_key(user_id)
if not api_key:
await message.reply_text("[IAC Marketplace] API key not set. Use /addapi <your_api_key> in bot DM to set it.")
return None
return api_key
# /addextol <address>
@app.on_message(filters.command("addextol"))
async def add_extol_handler(client, message: Message):
args = message.text.split()
if len(args) != 2 or not args[1].startswith("EXT"):
await message.reply_text("β Provide a valid Extol address starting with EXT.\n Usage: /addextol <address>")
return
await set_user_address(message.from_user.id, args[1])
await message.reply_text(f"β
Extol address saved: `{args[1]}`.")
# /removeextol
@app.on_message(filters.command("removeextol"))
async def remove_extol_handler(client, message: Message):
await remove_user_address(message.from_user.id)
await message.reply_text("β
Extol address removed.")
# /payextol <amount>
@app.on_message(filters.command("payextol"))
async def pay_extol_handler(client, message: Message):
args = message.text.split()
if len(args) != 2 or not args[1].isdigit():
await message.reply_text("β Enter a valid numeric amount.\n Usage: /payextol <amount>")
return
address = await get_user_address(message.from_user.id)
if not address:
await message.reply_text("β Use /addextol <address> to set your address first.")
return
msg = await message.reply_text("π Generating payment link...")
data = {"address": address, "amount": int(args[1])}
resp = await extol_request(message.from_user.id, "/api/create-payment", method="POST", data=data)
if not resp.get("ok"):
return await msg.edit(f"β Error: `{resp.get('error')}`")
payment_id = resp["payment_id"]
await set_last_payment_id(message.from_user.id, payment_id)
# Save payment to history for /checkextol
await save_payment(message.from_user.id, payment_id, address, int(args[1]), resp["payment_url"])
await msg.edit(f"β
<a href='{resp['payment_url']}'>Click here to pay</a>", disable_web_page_preview=True, parse_mode=ParseMode.HTML)
# /checkextol
@app.on_message(filters.command("checkextol"))
async def check_extol_handler(client, message: Message):
payments = await get_user_payments(message.from_user.id, limit=10)
if not payments:
await message.reply_text("β No recent payments found.")
return
msg = await message.reply_text("π Checking last 10 payment statuses...")
status_lines = []
for p in payments:
payment_id = p["payment_id"]
amount = p["amount"]
pay_url = p["payment_url"]
resp = await extol_request(message.from_user.id, "/api/payment-status", params={"payment_id": payment_id})
if not resp.get("ok"):
status_str = f"β Error: {resp.get('error') or 'Unknown'}"
else:
status = resp["status"]
if status == "paid":
status_str = f"β
<b>Paid</b><br>From: <code>{resp.get('from_address', '-')}</code>, At: <code>{resp.get('paid_at', '-')}</code>"
elif status == "timeout":
status_str = f"β <b>Timeout</b><br>Expired: <code>{resp.get('expired_at', '-')}</code>"
else:
status_str = "β³ <b>Pending</b>"
status_lines.append(f"Amount: <code>{amount}</code><br>"
f'<a href="{pay_url}">Click here to pay</a><br>'
f"ID: <code>{payment_id}</code><br>{status_str}")
await msg.edit("\n\n".join(status_lines), disable_web_page_preview=True, parse_mode=ParseMode.HTML)
# /extolbal
@app.on_message(filters.command("extolbal"))
async def extol_balance_handler(client, message: Message):
msg = await message.reply_text("π Fetching Extol balance...")
resp = await extol_request(message.from_user.id, "/api/balance")
if not resp.get("ok"):
return await msg.edit(f"β Error: `{resp.get('error')}`")
balance = resp.get("balance", 0)
address = resp.get("address", "Unknown")
await msg.edit(f"π° Balance: {balance} EXT\nπ·οΈ Address: {address}")
# /sendextol <to_address> <amount>
@app.on_message(filters.command("sendextol"))
async def send_extol_handler(client, message: Message):
args = message.text.split()
if len(args) != 3 or not args[2].isdigit() or not args[1].startswith("EXT"):
await message.reply_text("Usage: /sendextol <to_address> <amount>")
return
to_address, amt = args[1], int(args[2])
if amt <= 0:
await message.reply_text("β Amount must be positive.")
return
msg = await message.reply_text("π Sending Extol...")
resp = await extol_request(
message.from_user.id,
"/api/withdraw",
method="GET",
params={"amount": amt, "address": to_address},
)
if not resp.get("ok"):
error_msg = resp.get('error') or 'Unknown error (no message from API)'
code = resp.get('code')
if code is not None:
error_msg = f"(code {code}) {error_msg}"
return await msg.edit(f"β Error: {error_msg}")
link = resp.get("link", "No explorer link.")
await msg.edit(f"β
Sent {amt} EXT to {to_address} \n<a href='{link}'>View Transaction</a>", disable_web_page_preview=True, parse_mode=ParseMode.HTML)
# --- HTTPX helper ---
async def extol_request(user_id, path, method="GET", data=None, params=None):
api_key = await get_user_api_key(user_id)
if not api_key:
return {"ok": False, "error": "API key not set. Use /addapi <key> in DM."}
async with httpx.AsyncClient() as client:
headers = {"api-key": api_key}
try:
if method == "GET":
r = await client.get(f"{API_BASE_URL}{path}", headers=headers, params=params, timeout=10)
else:
r = await client.post(f"{API_BASE_URL}{path}", headers=headers, json=data, timeout=10)
return r.json()
except Exception as e:
return {"ok": False, "error": str(e)} |