nova2 / niva.py
chohj06ms's picture
Upload 22 files
d1e2e7a verified
import requests
import typing
from typing import Optional
from datetime import datetime, timezone, timedelta
import discord
from discord.ext import commands
from discord import app_commands
from PIL import Image, ImageDraw, ImageFont, ImageColor, ImageFilter, ImageSequence
import json
from web3 import Web3
from eth_utils import to_checksum_address
# PolygonScan API ํ‚ค
api_key = "4H655NPT5229MKFE2NNHIS2GNZ3U4UTGT2"
with open("token.txt", "r", encoding='utf-8') as f:
token = f.read()
def first_time(timestamp):
timestamp = int(timestamp)
dt_object = datetime.fromtimestamp(timestamp, timezone.utc)
# Convert UTC to Korea Standard Time (KST)
kst = timezone(timedelta(hours=9)) # KST is UTC+9
dt_kst = dt_object.astimezone(kst)
t = dt_kst.strftime('%Y-%m-%d')
return str(t)
def web3_find(token_id):
# Web3 ํ”„๋กœ๋ฐ”์ด๋” ์„ค์ • (์—ฌ๊ธฐ์„œ๋Š” Infura ์‚ฌ์šฉ, ์ž์‹ ์˜ ํ”„๋กœ์ ํŠธ ID๋กœ ๋Œ€์ฒด)
INFURA_URL = "https://polygon-mainnet.infura.io/v3/16185d569adf4d00a04f2d2a200cf231"
web3 = Web3(Web3.HTTPProvider(INFURA_URL))
# ํ† ํฐ ์ปจํŠธ๋ž™ํŠธ ์ฃผ์†Œ ๋ฐ ABI (์ตœ์†Œํ•œ tokenURI ํ•จ์ˆ˜๋ฅผ ํฌํ•จํ•ด์•ผ ํ•จ)
token_contract_address = "0xA4B37bE40F7b231Ee9574c4b16b7DDb7EAcDC99B"
token_id
# ์ปจํŠธ๋ž™ํŠธ ABI์˜ ์ผ๋ถ€ ์˜ˆ์‹œ (์‹ค์ œ ABI๋กœ ๋Œ€์ฒด ํ•„์š”)
contract_abi = [
{
"constant": True,
"inputs": [{"name": "_tokenId", "type": "uint256"}],
"name": "tokenURI",
"outputs": [{"name": "", "type": "string"}],
"payable": False,
"stateMutability": "view",
"type": "function"
},
]
# ์ปจํŠธ๋ž™ํŠธ ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ
contract = web3.eth.contract(address=token_contract_address, abi=contract_abi)
# tokenURI ํ˜ธ์ถœํ•˜์—ฌ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ URI ๊ฐ€์ ธ์˜ค๊ธฐ
token_uri = contract.functions.tokenURI(token_id).call()
# ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ URI์—์„œ JSON ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋‹ค์šด๋กœ๋“œ
metadata_response = requests.get(token_uri)
metadata = metadata_response.json()
# ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์—์„œ NFT ์ด๋ฆ„ ์ถ”์ถœ
nft_name = metadata.get("name", "Name not found")
print(f"NFT Name: {nft_name}")
return nft_name
def obj_srch(account_address):
# PolygonScan API URL ๊ตฌ์„ฑ
contract_address = "0xA4B37bE40F7b231Ee9574c4b16b7DDb7EAcDC99B"
url = f"https://api.polygonscan.com/api?module=account&action=tokenbalance&contractaddress={contract_address}&address={account_address}&tag=latest&apikey={api_key}"
# API ์š”์ฒญ
response = requests.get(url)
# ์‘๋‹ต ํ™•์ธ ๋ฐ ์ฒ˜๋ฆฌ
if response.status_code == 200:
data = response.json()
balance = data.get('result')
if balance is not None:
# ERC-721์€ ๋ณดํ†ต 1 NFT๋‹น 1์„ ๊ฐ€์ง€๋ฏ€๋กœ, balance๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜
real_balance = int(balance)
print(f"๊ณ„์ • ์ฃผ์†Œ {account_address}๋Š”(์€) ํ† ํฐ ์ปจํŠธ๋ž™ํŠธ {contract_address}์˜ NFT๋ฅผ {real_balance}๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.")
return real_balance
else:
print("NFT ์ž”์•ก ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
else:
print("API ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.")
def como_srch(account_address):
tok = "0x58AeABfE2D9780c1bFcB713Bf5598261b15dB6e5"
url = f"https://api.polygonscan.com/api?module=account&action=tokenbalance&contractaddress={tok}&address={account_address}&tag=latest&apikey={api_key}"
response = requests.get(url)
# ์‘๋‹ต ํ™•์ธ
if response.status_code == 200:
data = response.json()
# ํ† ํฐ ์ˆ˜๋Ÿ‰ ์ถœ๋ ฅ
balance = data.get('result')
if balance is not None:
real_balance = int(balance) / 10 ** 18
print(f"๊ณ„์ • ์ฃผ์†Œ {account_address}๋Š”(์€) ํ† ํฐ ์ฃผ์†Œ {tok}์˜ ํ† ํฐ์„ {int(real_balance)}๊ฐœ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.")
return int(real_balance)
else:
print("ํ† ํฐ ์ˆ˜๋Ÿ‰ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.")
else:
print("API ์š”์ฒญ์— ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.")
def ad2id(input_str):
input_str = str(input_str)
input_str = to_checksum_address(input_str)
print(input_str)
base_url = "https://cache.nova.gd/user/v1"
users = []
error_message = None
try:
if input_str.startswith("0x"):
url = f"{base_url}/by-address/{input_str}"
response = requests.get(url)
if response.status_code == 200:
users = response.json() # 'by-address' ๊ฐ€ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •
else:
error_message = f"Request failed with status code {response.status_code}"
except Exception as e:
error_message = str(e)
if error_message:
return "Error"
if not users:
return "Mint"
formatted_result = "".join(f"{user['nickname']}" for i, user in enumerate(users))
return formatted_result
def ad_srch(input_str):
if len(input_str) < 4:
return "4๊ธ€์ž ์ด์ƒ์œผ๋กœ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”."
base_url = "https://cache.nova.gd/user/v1"
url = f"{base_url}/search?query={input_str}"
response = requests.get(url)
data = response.json()
# 'address' ๊ฐ’ ์ถ”์ถœ
address = data['results'][0]['address']
print(address)
return address
def como_txt(text):
image_size = (180, 50)
image = Image.new('RGBA', image_size, (255, 255, 255, 0))
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("Helvetica_Neue_LT_Std_75_Bold.otf", 50)
text_color = (200, 200, 200)
# ํ…์ŠคํŠธ์˜ ๊ฒฝ๊ณ„ ์ƒ์ž ๊ณ„์‚ฐ
text_bbox = draw.textbbox((0, 0), text, font=font)
text_width = text_bbox[2] - text_bbox[0]
text_height = text_bbox[3] - text_bbox[1]
# ํ…์ŠคํŠธ๋ฅผ ์ด๋ฏธ์ง€ ์ค‘์•™์— ์ •๋ ฌ
text_x = (image_size[0] - text_width) / 2
text_y = (image_size[1] - text_height) / 2
draw.text((text_x, text_y), text, fill=text_color, font=font)
return image
def acom(input_str):
if len(input_str) < 4:
return ["4๊ธ€์ž ์ด์ƒ์œผ๋กœ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”."]
base_url = "https://cache.nova.gd/user/v1"
url = f"{base_url}/search?query={input_str}"
response = requests.get(url)
data = response.json()
users = data.get("results", []) # 'search' ๊ฐ€ {"results": [...]} ํ˜•์‹์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๊ฐ€์ •
if response.status_code != 200:
raise Exception(f"Request failed with status code {response.status_code}")
if not users:
return ["๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ ์—†์Œ"]
# ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์ŠคํŠธ ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ์ „์— ์ตœ๋Œ€ 25๊ฐœ์˜ ๊ฒฐ๊ณผ๋งŒ ํฌํ•จ๋˜๋„๋ก ์กฐ์ •
result_list = [user['nickname'] for user in users[:25]]
return result_list
def names(text, img, x = 124, y = 26):
text = str(text)
image = img
draw = ImageDraw.Draw(image)
font = ImageFont.truetype("Helvetica_Neue_LT_Std_75_Bold.otf", 42)
text_color = (208, 211, 214)
draw.text((x, y), text, fill=text_color, font=font)
return image
async def name_auto(interaction: discord.Interaction, current: str) -> typing.List[app_commands.Choice[str]]:
acs = acom(current)
matching_files = acs
return [app_commands.Choice(name=num, value=num) for num in matching_files]
def find_trans(account_address, number):
API_ENDPOINT = "https://api.polygonscan.com/api"
API_KEY = "4H655NPT5229MKFE2NNHIS2GNZ3U4UTGT2"
# ๊ฒ€์ƒ‰ํ•  ๊ณ„์ขŒ ์ฃผ์†Œ ๋ฐ ํ† ํฐ ์ปจํŠธ๋ž™ํŠธ ์ฃผ์†Œ
token_contract_address = "0xa4b37be40f7b231ee9574c4b16b7ddb7eacdc99b"
# Transfer ์ด๋ฒคํŠธ๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ
params = {
"module": "account",
"action": "tokennfttx",
"contractaddress": token_contract_address,
"address": account_address,
"page": 1,
"offset": number, # ์š”์ฒญํ•œ ์ด๋ฒคํŠธ ๊ฐœ์ˆ˜๋งŒํผ ์กฐํšŒ
"sort": "desc", # ์ตœ์‹ ์ˆœ์œผ๋กœ ์ •๋ ฌ
"apikey": API_KEY
}
response = requests.get(API_ENDPOINT, params=params)
data = response.json()
print(data)
# ๊ฒฐ๊ณผ์—์„œ ์š”์ฒญํ•œ ๊ฐœ์ˆ˜์˜ NFT ์ •๋ณด ์ถ”์ถœ
if data["status"] == "1" and data["result"]:
nft_list = data["result"][:number] # ์š”์ฒญํ•œ ๊ฐœ์ˆ˜๋งŒํผ์˜ ๊ฒฐ๊ณผ๋งŒ ์‚ฌ์šฉ
token_ids = [nft["tokenID"] for nft in nft_list] # ํ† ํฐ ID ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
token_from = [nft["from"] for nft in nft_list] # from ๊ฐ’์˜ ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
return token_ids, token_from # ํ† ํฐ ID ๋ฆฌ์ŠคํŠธ์™€ from ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
else:
print("No recent NFT transfers found.")
return [], [] # ๋‘ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
def find_first(account_address, number = 1):
API_ENDPOINT = "https://api.polygonscan.com/api"
API_KEY = "4H655NPT5229MKFE2NNHIS2GNZ3U4UTGT2"
# ๊ฒ€์ƒ‰ํ•  ๊ณ„์ขŒ ์ฃผ์†Œ ๋ฐ ํ† ํฐ ์ปจํŠธ๋ž™ํŠธ ์ฃผ์†Œ
token_contract_address = "0xa4b37be40f7b231ee9574c4b16b7ddb7eacdc99b"
# Transfer ์ด๋ฒคํŠธ๋ฅผ ์กฐํšŒํ•˜๊ธฐ ์œ„ํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ
params = {
"module": "account",
"action": "tokennfttx",
"contractaddress": token_contract_address,
"address": account_address,
"page": 1,
"offset": number, # ์š”์ฒญํ•œ ์ด๋ฒคํŠธ ๊ฐœ์ˆ˜๋งŒํผ ์กฐํšŒ
"sort": "asc", # ์ตœ์‹ ์ˆœ์œผ๋กœ ์ •๋ ฌ
"apikey": API_KEY
}
response = requests.get(API_ENDPOINT, params=params)
data = response.json()
print(data)
# ๊ฒฐ๊ณผ์—์„œ ์š”์ฒญํ•œ ๊ฐœ์ˆ˜์˜ NFT ์ •๋ณด ์ถ”์ถœ
if data["status"] == "1" and data["result"]:
nft_list = data["result"][:number] # ์š”์ฒญํ•œ ๊ฐœ์ˆ˜๋งŒํผ์˜ ๊ฒฐ๊ณผ๋งŒ ์‚ฌ์šฉ
timeStamp = [nft["timeStamp"] for nft in nft_list] # ํ† ํฐ ID ๋ฆฌ์ŠคํŠธ ์ƒ์„ฑ
return timeStamp # ํ† ํฐ ID ๋ฆฌ์ŠคํŠธ์™€ from ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
else:
print("No recent NFT transfers found.")
return [] # ๋‘ ๋นˆ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜ํ™˜
def run():
intents = discord.Intents.all()
bot = commands.Bot(command_prefix="!", intents=intents)
@bot.event
async def on_ready():
bot.tree.copy_global_to(guild=discord.Object(id=1192532796967751790))
await bot.tree.sync(guild=discord.Object(id=1192532796967751790))
print("ready")
@app_commands.autocomplete(name=name_auto)
@bot.tree.command()
async def me(interaction: discord.Interaction, name: str):
await interaction.response.send_message(f"https://cdn.discordapp.com/emojis/455204724786855938.gif?size=96&quality=lossless", ephemeral=False)
did = interaction.user.id
nid = ad_srch(name)
nid = str(nid)
print(nid)
como = como_srch(nid)
como_img = como_txt(str(como))
base_img = Image.open("base_img.png")
name_paste_position = (219, 295)
base_img.paste(como_img, name_paste_position, como_img)
obj = obj_srch(nid)
como_img = como_txt(str(obj))
name_paste_position = (219, 205)
base_img.paste(como_img, name_paste_position, como_img)
base_img = names(name, base_img)
token_ids, token_from = find_trans(nid, 3)
token_name = [None] * len(token_ids) # token_ids์˜ ๊ธธ์ด๋งŒํผ token_name ๋ฐฐ์—ด ์ดˆ๊ธฐํ™”
for i in range(len(token_ids)):
token_name[i] = web3_find(int(token_ids[i]))
token_from[0] = ad2id(token_from[0])
token_from[1] = ad2id(token_from[1])
token_from[2] = ad2id(token_from[2])
print(token_from[0])
print(token_from[1])
print(token_from[2])
base_img = names(token_from[0], base_img, 114, 459)
base_img = names(token_from[1], base_img, 114, 519)
base_img = names(token_from[2], base_img, 114, 580)
base_img = names(token_name[0], base_img, 361, 459)
base_img = names(token_name[1], base_img, 361, 519)
base_img = names(token_name[2], base_img, 361, 580)
timeStamp = find_first(nid)
timeStamp = first_time(timeStamp[0])
print(timeStamp)
base_img = names(timeStamp, base_img, 640, 66)
base_img.save("img.png")
#await interaction.response.send_message(f"", ephemeral=False, file=discord.File("img.png"))
await interaction.edit_original_response(content="Done!")
await interaction.followup.send(f"<@!{did}>", ephemeral=False, file=discord.File("img.png"))
bot.run(token)
if __name__ == "__main__":
run()