Really-amin commited on
Commit
f2cbe2d
·
verified ·
1 Parent(s): c6a3e2b

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +24 -12
  2. app.py +134 -0
  3. requirements.txt +3 -0
README.md CHANGED
@@ -1,12 +1,24 @@
1
- ---
2
- title: Asset
3
- emoji: 🚀
4
- colorFrom: red
5
- colorTo: yellow
6
- sdk: gradio
7
- sdk_version: 5.49.1
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # BSC Address Checker + Optional BEP20 Transfer (Gradio Space)
2
+
3
+ این پروژه یک اپ ساده Gradio است که:
4
+ - موجودی BNB (BSC) و ETH (Ethereum) را برای یک آدرس نمایش می‌دهد.
5
+ - جستجوی ساده برای دو توکن رایج (BUSD و WETH_BEP20) انجام می‌دهد.
6
+ - **اختیاری**: انتقال BEP20 را در شبکه BSC با وارد کردن کلید خصوصی انجام می‌دهد.
7
+
8
+ ## هشدارهای امنیتی
9
+ - هرگز کلید خصوصی خود را در یک Space عمومی قرار ندهید.
10
+ - اگر می‌خواهید عملیات ارسال را فعال کنید، Space را خصوصی نگه دارید یا اپ را محلی اجرا کنید.
11
+ - توصیه می‌شود از Wallet-based signing یا پل‌های امن استفاده کنید.
12
+
13
+ ## Deploy در Hugging Face Spaces
14
+ 1. ساخت یک Space جدید (Gradio).
15
+ 2. آپلود فایل‌های `app.py` و `requirements.txt`.
16
+ 3. تنظیم متغیرهای محیطی (در Settings -> Secrets):
17
+ - `BSC_RPC` (اختیاری; پیش‌فرض: https://bsc-dataseed.binance.org/)
18
+ - `ETH_RPC` (اختیاری)
19
+ 4. اگر خواستی قابلیت ارسال را ایمن کنی، از Secrets برای قرار دادن `PRIVATE_KEY` استفاده کن، یا بهتر: اجازه نده کاربران کی‌ها را وارد کنند.
20
+
21
+ ## اجرا محلی
22
+ 1. pip install -r requirements.txt
23
+ 2. export BSC_RPC=...
24
+ 3. python app.py
app.py ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ # Hugging Face Space (Gradio) for checking BSC/Ethereum balances and optional BEP20 transfers.
3
+ # WARNING: Never paste your private key into public/shared Spaces. This UI allows optional local signing
4
+ # but you must understand the security risks. Prefer using WalletConnect / local signing or set
5
+ # PRIVATE_KEY as a secret in a private Space only if you know what you're doing.
6
+
7
+ from web3 import Web3
8
+ import gradio as gr
9
+ import os
10
+ from dotenv import load_dotenv
11
+ load_dotenv()
12
+
13
+ BSC_RPC = os.environ.get('BSC_RPC','https://bsc-dataseed.binance.org/')
14
+ ETH_RPC = os.environ.get('ETH_RPC','https://mainnet.infura.io/v3/YOUR_INFURA_KEY')
15
+ w3_bsc = Web3(Web3.HTTPProvider(BSC_RPC))
16
+ w3_eth = Web3(Web3.HTTPProvider(ETH_RPC))
17
+
18
+ COMMON_TOKENS = {
19
+ 'BUSD': '0xe9e7cea3dedca5984780bafc599bd69add087d56',
20
+ 'WETH_BEP20': '0x2170ed0880ac9a755fd29b2688956bd959f933f8'
21
+ }
22
+
23
+ ERC20_ABI = [
24
+ {"constant":True,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"balance","type":"uint256"}],"type":"function"},
25
+ {"constant":True,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"type":"function"},
26
+ {"constant":True,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"type":"function"},
27
+ {"constant":False,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"type":"function"}
28
+ ]
29
+
30
+ def checksum(addr):
31
+ try:
32
+ return w3_bsc.toChecksumAddress(addr)
33
+ except Exception:
34
+ return None
35
+
36
+ def check_address(addr):
37
+ addr = addr.strip()
38
+ c = checksum(addr)
39
+ if not c:
40
+ return ("آدرس نامعتبر است. لطفاً آدرس را با 0x شروع وارد کنید.", "")
41
+ out_lines = []
42
+ try:
43
+ bnb = w3_bsc.fromWei(w3_bsc.eth.get_balance(c), 'ether')
44
+ out_lines.append(f"BNB (BSC) balance: {bnb} BNB")
45
+ except Exception as e:
46
+ out_lines.append(f"خطا در خواندن موجودی BSC: {e}")
47
+ try:
48
+ eth = w3_eth.fromWei(w3_eth.eth.get_balance(c), 'ether')
49
+ out_lines.append(f"ETH (Ethereum) balance: {eth} ETH")
50
+ except Exception:
51
+ out_lines.append("Ethereum RPC not configured or error reading.")
52
+ token_lines = []
53
+ for sym, taddr in COMMON_TOKENS.items():
54
+ try:
55
+ token = w3_bsc.eth.contract(address=w3_bsc.toChecksumAddress(taddr), abi=ERC20_ABI)
56
+ bal = token.functions.balanceOf(c).call()
57
+ dec = token.functions.decimals().call()
58
+ if bal > 0:
59
+ token_lines.append(f"{sym}: {bal / (10**dec)} ({taddr})")
60
+ except Exception:
61
+ pass
62
+ if token_lines:
63
+ out_lines.append("\nTokens on BSC found:")
64
+ out_lines += token_lines
65
+ else:
66
+ out_lines.append("\nNo common tokens (BUSD/WETH_BEP20) found with nonzero balance.")
67
+ bscscan = f"https://bscscan.com/address/{c}"
68
+ out_lines.append(f"\nView on BscScan: {bscscan}")
69
+ return ("\n".join(out_lines), bscscan)
70
+
71
+ def send_bep20(token_addr, to_addr, amount_str, private_key):
72
+ # Security: This function will perform a real on-chain transfer if called.
73
+ # Use only in a private Space or run locally. The app warns the user strongly.
74
+ try:
75
+ token_addr = w3_bsc.toChecksumAddress(token_addr)
76
+ to_addr = w3_bsc.toChecksumAddress(to_addr)
77
+ except Exception as e:
78
+ return f"آدرس‌ها نامعتبر هستند: {e}"
79
+ try:
80
+ token = w3_bsc.eth.contract(address=token_addr, abi=ERC20_ABI)
81
+ decimals = token.functions.decimals().call()
82
+ amt = int(float(amount_str) * (10 ** decimals))
83
+ except Exception as e:
84
+ return f"خطا در آماده‌سازی مقدار یا ABI توکن: {e}"
85
+ try:
86
+ acct = w3_bsc.eth.account.from_key(private_key)
87
+ except Exception as e:
88
+ return f"خطا در private key: {e}"
89
+ from_addr = acct.address
90
+ # Check balance
91
+ try:
92
+ bal = token.functions.balanceOf(from_addr).call()
93
+ if bal < amt:
94
+ return f"موجودی توکن کافی نیست. موجودی: {bal / (10**decimals)}"
95
+ except Exception as e:
96
+ return f"خطا در خواندن موجودی: {e}"
97
+ # Build tx
98
+ nonce = w3_bsc.eth.get_transaction_count(from_addr)
99
+ tx = token.functions.transfer(to_addr, amt).buildTransaction({
100
+ 'chainId': 56,
101
+ 'gas': 200000,
102
+ 'gasPrice': w3_bsc.eth.gas_price,
103
+ 'nonce': nonce
104
+ })
105
+ try:
106
+ signed = w3_bsc.eth.account.sign_transaction(tx, private_key=private_key)
107
+ tx_hash = w3_bsc.eth.send_raw_transaction(signed.rawTransaction)
108
+ return f"Transaction submitted: {tx_hash.hex()} — View: https://bscscan.com/tx/{tx_hash.hex()}"
109
+ except Exception as e:
110
+ return f"خطا در ارسال تراکنش: {e}"
111
+
112
+ with gr.Blocks() as demo:
113
+ gr.Markdown("# BSC Address Checker & (optional) BEP20 Transfer")
114
+ 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.")
115
+ with gr.Tab("Check Address"):
116
+ addr_in = gr.Textbox(label="Address (0x...)", placeholder="0x...")
117
+ out_text = gr.Textbox(label="Result", lines=12)
118
+ bscscan_link = gr.Textbox(label="BscScan link")
119
+ check_btn = gr.Button("Check")
120
+ check_btn.click(fn=check_address, inputs=addr_in, outputs=[out_text, bscscan_link])
121
+ with gr.Tab("Send BEP20 (DANGEROUS)"):
122
+ gr.Markdown("Use only in a private environment. This will perform a live on-chain transfer if you provide a valid private key.")
123
+ token_addr = gr.Textbox(label="Token contract address (BSC)", placeholder="0x...")
124
+ to_addr = gr.Textbox(label="Destination address (0x...)")
125
+ amount = gr.Textbox(label="Amount (decimal string, e.g. 1.23)")
126
+ pk = gr.Textbox(label="Private key (hex) — optional (DANGEROUS)", placeholder="0x...", type="password")
127
+ send_out = gr.Textbox(label="Send result", lines=4)
128
+ send_btn = gr.Button("Send")
129
+ send_btn.click(fn=send_bep20, inputs=[token_addr, to_addr, amount, pk], outputs=send_out)
130
+
131
+ gr.Markdown("⚠️ This Space is a convenience tool. The authors are not responsible for funds lost. Always test with tiny amounts first.")
132
+
133
+ if __name__ == "__main__":
134
+ demo.launch()
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ web3
3
+ python-dotenv