-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
200 lines (172 loc) · 9.63 KB
/
main.py
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
import discord, requests, json, time, os.path
from discord import app_commands
def get_config():
config = []
with open('config.json', 'r', encoding='utf-8') as file_object:
config = json.load(file_object)
return config
def checkAuth(id):
if(id == OWNER_ID):
return True
return False
# Check if config.json exists in the directory
if(os.path.exists('config.json') == False):
print("[ERROR] Config.json not found.")
exit()
# Get our Config (APIs/Tokens)
config = get_config()
# Currently supported Crypto list
crypto_list = {"BTC", "ETH", "BCH", "LTC", "XRP", "SOL", "XMR", "DOGE"}
# Ask for Token on start
# Another way of using this would be a config file or env variables
DISCORD_TOKEN = config['discord_token']
API_KEY = config['api_key']
OWNER_ID = config['ownerID']
# Let's confirm Discord Token is -probably- valid from default config.json
if(DISCORD_TOKEN == "discord_bot_token_here" or DISCORD_TOKEN == None or DISCORD_TOKEN == ""):
print("[ERROR] Please add a valid Discord Bot Token!")
exit()
# Let's confirm API is -probably- valid from default config.json
if(API_KEY == "api_key_here" or API_KEY == None or API_KEY == ""):
print("[ERROR] Please add a valid CoinMarketCap API Key!")
exit()
if(OWNER_ID == None or OWNER_ID == "your_discord_id_here" or OWNER_ID == ""):
print("[ERROR] Please add a valid Owner ID!")
exit()
class client(discord.Client):
def __init__(self):
super().__init__(intents=discord.Intents.default())
self.synced = False
async def on_ready(self):
await self.wait_until_ready()
if not self.synced:
await tree.sync()
self.synced = True
await self.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name="BTC Transactions ❤"))
# print(f"Logged in as {self.user}")
client = client()
tree = app_commands.CommandTree(client)
# Grabbing Confirmations count using method mentioned here
# https://stackoverflow.com/questions/14989481/blockchain-api-to-determine-transaction-confirmations
@tree.command(name = "check", description = "Used to check transaction confirmation status")
async def check(interaction, txid:str):
# check if owner is running the commands
if(checkAuth(interaction.user.id)):
await interaction.response.send_message(f"~ Unauthorized Access ~")
return
res = requests.get(f'https://mempool.space/api/tx/{txid}/status')
if(res.status_code != 200):
await interaction.response.send_message(f"is {txid} a valid TXID? :'(")
else:
res = res.json()
if(res['confirmed'] == False):
embed=discord.Embed(title="Transaction Status", url=f"https://mempool.space/tx/{txid}", description="Transaction has not been confirmed yet", color=0xFF0000)
embed.add_field(name="Not Confirmed Yet", value=f"{txid}", inline=False)
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
else:
txheight = int(res['block_height'])
res3 = requests.get(f'https://mempool.space/api/blocks/tip/height')
curheight = int(res3.json())
confirmations = curheight - txheight + 1
embed=discord.Embed(title="Transaction Status", url=f"https://mempool.space/tx/{txid}", description="Transaction has been confirmed", color=0x04ff00)
embed.add_field(name=f"Confirmed [{confirmations}]", value=f"{txid}", inline=False)
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
@tree.command(name = "fees", description = "Used to get optimal BTC fees")
async def fees(interaction):
# check if owner is running the commands
if(checkAuth(interaction.user.id)):
await interaction.response.send_message(f"~ Unauthorized Access ~")
return
res = requests.get('https://mempool.space/api/v1/fees/recommended')
res2 = requests.get("https://mempool.space/api/mempool")
if(res.status_code != 200 or res2.status_code != 200):
await interaction.response.send_message(f"Is mempool down? :'(")
else:
resp = res.json()
resp2 = res2.json()
embed=discord.Embed(title="Optimal Fees", url=f"https://mempool.space/", description="Below you can see all the suggested fees.\n Remember that mining blocks might take longer if the network is congested.", color=0x04ff00)
embed.add_field(name=f"Within 10 mins (next block): {resp['fastestFee']} sat/vB", value=f"", inline=False)
embed.add_field(name=f"Within 30 mins: {resp['halfHourFee']} sat/vB", value=f"", inline=False)
embed.add_field(name=f"Within 60 mins: {resp['hourFee']} sat/vB", value=f"", inline=False)
embed.add_field(name=f"Don't hold your breath: {resp['economyFee']} sat/vB", value=f"", inline=False)
embed.add_field(name=f"Won't be purged: {resp['minimumFee']} sat/vB", value=f"", inline=False)
embed.add_field(name=f"\u200b", value=f"Currently Unconfirmed Transactions: {resp2['count']:,} TXs", inline=False)
embed.add_field(name=f"Fetched at", value=f"<t:{int(time.time())}:R>")
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
@tree.command(name = "unconfirmed", description = "gets total unconfirmed transactions on the BTC network")
async def unconfirmed(interaction):
# check if owner is running the commands
if(checkAuth(interaction.user.id)):
await interaction.response.send_message(f"~ Unauthorized Access ~")
return
res2 = requests.get("https://mempool.space/api/mempool")
if(res2.status_code != 200):
await interaction.response.send_message(f"Is mempool down? :'(")
else:
resp2 = res2.json()
embed=discord.Embed(title="Total Unconfirmed Transactions", url=f"https://mempool.space/", description="", color=0x04ff00)
embed.add_field(name=f"Currently Unconfirmed Transactions", value=f"{resp2['count']:,} TXs", inline=False)
embed.add_field(name=f"Fetched at", value=f"<t:{int(time.time())}:R>")
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
@tree.command(name = "cryptos", description = "Used to get currently supported Crypto-currencies list.")
async def cryptos(interaction):
# check if owner is running the commands
if(checkAuth(interaction.user.id)):
await interaction.response.send_message(f"~ Unauthorized Access ~")
return
res = ""
for i in crypto_list:
res += i + " "
embed=discord.Embed(title="Currently Supported Cryptos", description="Below you can see all the currently supported Crpyots for /price", color=0x04ff00)
embed.add_field(name=f"", value=f"{res}", inline=False)
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
@tree.command(name="price", description = "Used to get current BTC price")
async def price(interaction, crypto:str):
# check if owner is running the commands
if(checkAuth(interaction.user.id)):
await interaction.response.send_message(f"~ Unauthorized Access ~")
return
headers = {
'Accepts': 'application/json',
"X-CMC_PRO_API_KEY": API_KEY
}
session = requests.Session()
session.headers.update(headers)
if(crypto in crypto_list):
pass
else:
await interaction.response.send_message("Invalid/Unsupport Crypto | Check /cryptos to check currently supported currencies.")
return
res = session.get("https://pro-api.coinmarketcap.com/v1/tools/price-conversion", params={"amount": 1, "symbol": crypto})
if(res.status_code != 200):
await interaction.response.send_message("Can't reach Coinmarket API?")
else:
resp = res.json()
price = resp['data']['quote']['USD']['price']
price = f"{price:,.2f}"
embed=discord.Embed(title=f"Current {crypto} Price", description=f"Below you can see current {crypto}'s Price", color=0x04ff00)
embed.add_field(name=f"{crypto} Price", value=f"${price} USD", inline=False)
embed.add_field(name=f"Fetched at", value=f"<t:{int(time.time())}:R>")
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
@tree.command(name = "help", description = "Bot help & Commands List")
async def help(interaction):
# check if owner is running the commands
if(checkAuth(interaction.user.id)):
await interaction.response.send_message(f"~ Unauthorized Access ~")
return
embed=discord.Embed(title="Help & Commands List", description="Thank you for using this crappy bot, hope you liked it so far.", color=0x04ff00)
embed.add_field(name=f"/help", value=f"Displays this message and currently supported commands", inline=False)
embed.add_field(name=f"/fees", value=f"Shows BTC fees depending on how fast you need it confirmed", inline=False)
embed.add_field(name=f"/price", value=f"used as /price <crypto currency> (ex BTC/ETH)", inline=False)
embed.add_field(name=f"/cryptos", value=f"used to get currently supported list of crypto-currencies for /price", inline=False)
embed.add_field(name=f"/unconfirmed", value=f"gets total unconfirmed transactions on the BTC network", inline=False)
embed.add_field(name=f"/check", value=f"used to check a BTC transaction for confirmations and list how many confirmations transaction has if confirmed.", inline=False)
embed.set_footer(text="Made with ❤ by banonkiel#0001")
await interaction.response.send_message(embed=embed)
client.run(DISCORD_TOKEN)