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()