Spaces:
Sleeping
Sleeping
File size: 6,408 Bytes
f2cbe2d |
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 |
# app.py
# Hugging Face Space (Gradio) for checking BSC/Ethereum balances and optional BEP20 transfers.
# WARNING: Never paste your private key into public/shared Spaces. This UI allows optional local signing
# but you must understand the security risks. Prefer using WalletConnect / local signing or set
# PRIVATE_KEY as a secret in a private Space only if you know what you're doing.
from web3 import Web3
import gradio as gr
import os
from dotenv import load_dotenv
load_dotenv()
BSC_RPC = os.environ.get('BSC_RPC','https://bsc-dataseed.binance.org/')
ETH_RPC = os.environ.get('ETH_RPC','https://mainnet.infura.io/v3/YOUR_INFURA_KEY')
w3_bsc = Web3(Web3.HTTPProvider(BSC_RPC))
w3_eth = Web3(Web3.HTTPProvider(ETH_RPC))
COMMON_TOKENS = {
'BUSD': '0xe9e7cea3dedca5984780bafc599bd69add087d56',
'WETH_BEP20': '0x2170ed0880ac9a755fd29b2688956bd959f933f8'
}
ERC20_ABI = [
{"constant":True,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},
{"constant":True,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},
{"constant":True,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},
{"constant":False,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"type":"function"}
]
def checksum(addr):
try:
return w3_bsc.toChecksumAddress(addr)
except Exception:
return None
def check_address(addr):
addr = addr.strip()
c = checksum(addr)
if not c:
return ("آدرس نامعتبر است. لطفاً آدرس را با 0x شروع وارد کنید.", "")
out_lines = []
try:
bnb = w3_bsc.fromWei(w3_bsc.eth.get_balance(c), 'ether')
out_lines.append(f"BNB (BSC) balance: {bnb} BNB")
except Exception as e:
out_lines.append(f"خطا در خواندن موجودی BSC: {e}")
try:
eth = w3_eth.fromWei(w3_eth.eth.get_balance(c), 'ether')
out_lines.append(f"ETH (Ethereum) balance: {eth} ETH")
except Exception:
out_lines.append("Ethereum RPC not configured or error reading.")
token_lines = []
for sym, taddr in COMMON_TOKENS.items():
try:
token = w3_bsc.eth.contract(address=w3_bsc.toChecksumAddress(taddr), abi=ERC20_ABI)
bal = token.functions.balanceOf(c).call()
dec = token.functions.decimals().call()
if bal > 0:
token_lines.append(f"{sym}: {bal / (10**dec)} ({taddr})")
except Exception:
pass
if token_lines:
out_lines.append("\nTokens on BSC found:")
out_lines += token_lines
else:
out_lines.append("\nNo common tokens (BUSD/WETH_BEP20) found with nonzero balance.")
bscscan = f"https://bscscan.com/address/{c}"
out_lines.append(f"\nView on BscScan: {bscscan}")
return ("\n".join(out_lines), bscscan)
def send_bep20(token_addr, to_addr, amount_str, private_key):
# Security: This function will perform a real on-chain transfer if called.
# Use only in a private Space or run locally. The app warns the user strongly.
try:
token_addr = w3_bsc.toChecksumAddress(token_addr)
to_addr = w3_bsc.toChecksumAddress(to_addr)
except Exception as e:
return f"آدرسها نامعتبر هستند: {e}"
try:
token = w3_bsc.eth.contract(address=token_addr, abi=ERC20_ABI)
decimals = token.functions.decimals().call()
amt = int(float(amount_str) * (10 ** decimals))
except Exception as e:
return f"خطا در آمادهسازی مقدار یا ABI توکن: {e}"
try:
acct = w3_bsc.eth.account.from_key(private_key)
except Exception as e:
return f"خطا در private key: {e}"
from_addr = acct.address
# Check balance
try:
bal = token.functions.balanceOf(from_addr).call()
if bal < amt:
return f"موجودی توکن کافی نیست. موجودی: {bal / (10**decimals)}"
except Exception as e:
return f"خطا در خواندن موجودی: {e}"
# Build tx
nonce = w3_bsc.eth.get_transaction_count(from_addr)
tx = token.functions.transfer(to_addr, amt).buildTransaction({
'chainId': 56,
'gas': 200000,
'gasPrice': w3_bsc.eth.gas_price,
'nonce': nonce
})
try:
signed = w3_bsc.eth.account.sign_transaction(tx, private_key=private_key)
tx_hash = w3_bsc.eth.send_raw_transaction(signed.rawTransaction)
return f"Transaction submitted: {tx_hash.hex()} — View: https://bscscan.com/tx/{tx_hash.hex()}"
except Exception as e:
return f"خطا در ارسال تراکنش: {e}"
with gr.Blocks() as demo:
gr.Markdown("# BSC Address Checker & (optional) BEP20 Transfer")
gr.Markdown("**Warnings:** Do not paste private keys into public/shared spaces. Use this tool **locally** or in a private Hugging Face Space. Prefer wallet-based signing (WalletConnect) or using environment secrets.")
with gr.Tab("Check Address"):
addr_in = gr.Textbox(label="Address (0x...)", placeholder="0x...")
out_text = gr.Textbox(label="Result", lines=12)
bscscan_link = gr.Textbox(label="BscScan link")
check_btn = gr.Button("Check")
check_btn.click(fn=check_address, inputs=addr_in, outputs=[out_text, bscscan_link])
with gr.Tab("Send BEP20 (DANGEROUS)"):
gr.Markdown("Use only in a private environment. This will perform a live on-chain transfer if you provide a valid private key.")
token_addr = gr.Textbox(label="Token contract address (BSC)", placeholder="0x...")
to_addr = gr.Textbox(label="Destination address (0x...)")
amount = gr.Textbox(label="Amount (decimal string, e.g. 1.23)")
pk = gr.Textbox(label="Private key (hex) — optional (DANGEROUS)", placeholder="0x...", type="password")
send_out = gr.Textbox(label="Send result", lines=4)
send_btn = gr.Button("Send")
send_btn.click(fn=send_bep20, inputs=[token_addr, to_addr, amount, pk], outputs=send_out)
gr.Markdown("⚠️ This Space is a convenience tool. The authors are not responsible for funds lost. Always test with tiny amounts first.")
if __name__ == "__main__":
demo.launch() |