DILSHAD737 commited on
Commit
4d5d278
·
1 Parent(s): 927abf6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -247
app.py CHANGED
@@ -1,256 +1,33 @@
1
- import asyncio
2
- import warnings
3
- warnings.filterwarnings("ignore", category=UserWarning)
4
- warnings.filterwarnings("ignore", category=RuntimeWarning)
5
-
6
- try:
7
- asyncio.set_event_loop(asyncio.new_event_loop())
8
- except Exception:
9
- pass
10
-
11
- import gradio as gr
12
- import hashlib, hmac, os, time, math, random
13
- from itertools import permutations, combinations
14
- from mnemonic import Mnemonic
15
- import coincurve
16
- from eth_utils import keccak, to_checksum_address
17
- import spaces
18
-
19
- @spaces.GPU
20
- def _noop():
21
- return "ok"
22
-
23
- # ============================================================
24
- _MNEMONIC = None
25
- def _get_mnemonic():
26
- global _MNEMONIC
27
- if _MNEMONIC is None:
28
- _MNEMONIC = Mnemonic("english")
29
- return _MNEMONIC
30
-
31
- # ---------- BIP32 manual ----------
32
- _SECP256K1_N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
33
- _HARDENED = 0x80000000
34
-
35
- def _bip32_derive_child_priv(parent_priv, parent_chain, index):
36
- if index >= _HARDENED:
37
- data = b'\x00' + parent_priv + index.to_bytes(4, 'big')
38
- else:
39
- pub = coincurve.PrivateKey(parent_priv).public_key.format(compressed=True)
40
- data = pub + index.to_bytes(4, 'big')
41
- I = hmac.new(parent_chain, data, hashlib.sha512).digest()
42
- child_int = (int.from_bytes(I[:32], 'big') + int.from_bytes(parent_priv, 'big')) % _SECP256K1_N
43
- if child_int == 0:
44
- raise ValueError("Invalid child key")
45
- return child_int.to_bytes(32, 'big'), I[32:]
46
-
47
- def seed_to_privkey_hd(seed, address_index=0):
48
- I = hmac.new(b"Bitcoin seed", seed, hashlib.sha512).digest()
49
- key, chain = I[:32], I[32:]
50
- for idx in [44 + _HARDENED, 60 + _HARDENED, _HARDENED, 0, address_index]:
51
- key, chain = _bip32_derive_child_priv(key, chain, idx)
52
- return key
53
-
54
- # ---------- BIP39 ----------
55
- try:
56
- import bip39 as _bip39_rust
57
- _USE_RUST_BIP39 = True
58
- if hasattr(_bip39_rust, 'phrase_to_seed'):
59
- _seed_fn = _bip39_rust.phrase_to_seed
60
- _check_fn = getattr(_bip39_rust, 'check_phrase', None)
61
- elif hasattr(_bip39_rust, 'bip39_to_seed'):
62
- _seed_fn = _bip39_rust.bip39_to_seed
63
- _check_fn = getattr(_bip39_rust, 'bip39_validate', None)
64
- else:
65
- _seed_fn = None; _check_fn = None; _USE_RUST_BIP39 = False
66
- except ImportError:
67
- _bip39_rust = None; _USE_RUST_BIP39 = False; _seed_fn = None; _check_fn = None
68
-
69
- def is_valid_bip39(phrase):
70
- if _USE_RUST_BIP39 and _check_fn:
71
- return _check_fn(phrase)
72
- return _get_mnemonic().check(phrase)
73
-
74
- def phrase_to_seed(phrase, passphrase=""):
75
- if _USE_RUST_BIP39 and _seed_fn:
76
- return _seed_fn(phrase, passphrase)
77
- return _get_mnemonic().to_seed(phrase, passphrase=passphrase)
78
-
79
- # ---------- Address Cache ----------
80
- _ADDRESS_CACHE = {}
81
-
82
- def load_addresses_cached(path):
83
- if path in _ADDRESS_CACHE:
84
- cached_mtime, cached_set = _ADDRESS_CACHE[path]
85
- try:
86
- current_mtime = os.path.getmtime(path)
87
- if current_mtime == cached_mtime:
88
- return cached_set
89
- except OSError:
90
- pass
91
-
92
- s = set()
93
- with open(path, "r", encoding="utf-8") as f:
94
- for line in f:
95
- a = line.strip().strip('"').strip("'").lstrip("\ufeff").lower()
96
- if a.startswith("0x"):
97
- a = a[2:]
98
- if a and len(a) == 40:
99
- s.add(a)
100
-
101
- try:
102
- mtime = os.path.getmtime(path)
103
- except OSError:
104
- mtime = 0
105
- _ADDRESS_CACHE[path] = (mtime, s)
106
- return s
107
-
108
- def normalize(addr):
109
- a = addr.strip().lower()
110
- if a.startswith("0x"):
111
- a = a[2:]
112
- return a
113
-
114
- # ---------- Generator ----------
115
- def generate_phrases_for_words(wordlist, mode):
116
- n = len(wordlist)
117
- if mode == "order":
118
- for perm in permutations(wordlist):
119
- yield " ".join(perm)
120
- elif mode == "replace":
121
- for i in range(n):
122
- for w in wordlist:
123
- new = wordlist.copy()
124
- new[i] = w
125
- yield " ".join(new)
126
- elif mode == "subset":
127
- for r in range(1, n + 1):
128
- for combo in combinations(wordlist, r):
129
- yield " ".join(combo)
130
-
131
- # ============================================================
132
- # Scan Function (Returns all at once, NO yield)
133
- # ============================================================
134
-
135
- def run_scan(my_phrase, num_phrases, addresses_file, phrase_mode,
136
- start_index, end_index, passphrase):
137
-
138
- if not os.path.exists(addresses_file):
139
- return f"❌ File nahi mili: {addresses_file}", ""
140
-
141
- num_phrases = int(num_phrases)
142
- start_index = int(start_index)
143
- end_index = int(end_index)
144
-
145
- try:
146
- known = load_addresses_cached(addresses_file)
147
- except Exception as e:
148
- return f"❌ Addresses load fail: {e}", ""
149
-
150
- if not known:
151
- return "❌ Koi valid address file mein nahi mila", ""
152
-
153
- mnemo = _get_mnemonic()
154
- phrases = []
155
-
156
- my_words = my_phrase.strip().split()
157
- if len(my_words) == 12:
158
- phrases.append(" ".join(my_words))
159
-
160
- for _ in range(num_phrases):
161
- phrases.append(mnemo.generate(strength=128))
162
-
163
- log_text = f"✅ Loaded {len(known):,} addresses\n"
164
- log_text += f"🔧 Mode: {phrase_mode} | 🔑 Index: {start_index}-{end_index}\n"
165
- log_text += f"📝 Total phrases: {len(phrases)}\n\n"
166
-
167
- log_text += "Phrases:\n"
168
- for i, p in enumerate(phrases, 1):
169
- tag = " (AAPKI)" if i == 1 and len(my_words) == 12 else ""
170
- log_text += f" {i}. {p}{tag}\n"
171
- log_text += "\n--- Scanning ---\n"
172
-
173
- matches = []
174
- start = time.time()
175
- total_phrases = len(phrases)
176
-
177
- for p_idx, phrase in enumerate(phrases, 1):
178
- log_text += f"\n🔍 [{p_idx}/{total_phrases}] Checking: {phrase}\n"
179
- words = phrase.strip().split()
180
-
181
- if len(words) != 12:
182
- log_text += " ⚠️ Skipped (not 12 words)\n"
183
- continue
184
-
185
- for idx in range(start_index, end_index + 1):
186
- for phrase_str in generate_phrases_for_words(words, phrase_mode):
187
- if not is_valid_bip39(phrase_str):
188
- continue
189
- try:
190
- seed = phrase_to_seed(phrase_str, passphrase)
191
- priv = seed_to_privkey_hd(seed, idx)
192
- pub = coincurve.PrivateKey(priv).public_key.format(compressed=False)[1:]
193
- addr = to_checksum_address(keccak(pub)[-20:])
194
- except Exception:
195
- continue
196
-
197
- if normalize(addr) in known:
198
- match_line = f"🎉 MATCH!\nPhrase: {phrase_str}\nIndex: {idx}\nKey: {priv.hex()}\nAddr: {addr}\n"
199
- log_text += match_line
200
- matches.append(match_line)
201
-
202
- elapsed = time.time() - start
203
- log_text += f"\n=== DONE ===\nTotal time: {elapsed:.1f}s\nTotal matches: {len(matches)}\n"
204
-
205
- matches_text = "\n".join(matches) if matches else "Koi match nahi mila"
206
-
207
- # Returns everything at the very end
208
- return log_text, matches_text
209
-
210
- # ============================================================
211
- # Clean UI (Standard Gradio, no blank screens)
212
- # ============================================================
213
- with gr.Blocks() as demo:
214
- gr.Markdown("# 🔍 Phrase Scanner")
215
-
216
  my_phrase = gr.Textbox(
217
- label="🔑 Apni Phrase (optional)",
218
  value="lesson cushion crane affair federal decline limb spend reunion chief cart zebra",
219
- lines=2,
220
  )
221
- num_phrases = gr.Number(label="Kitni Random Phrases Check Karein?", value=10, precision=0, minimum=0)
 
 
222
  addresses_file = gr.Textbox(label="Addresses File", value="12730802_addresses.csv")
223
- phrase_mode = gr.Radio(choices=["replace", "order", "subset"], value="replace", label="Phrase Mode")
224
- start_index = gr.Number(label="Start Index", value=0, precision=0, minimum=0)
225
- end_index = gr.Number(label="End Index", value=20, precision=0, minimum=0)
226
- passphrase = gr.Textbox(label="BIP39 Passphrase (khali chhod dein)", value="", type="password")
227
-
228
- run_btn = gr.Button("🚀 Scan Shuru Karein", variant="primary")
229
 
230
- gr.Markdown("### Output")
231
- log_output = gr.Textbox(lines=15, interactive=False, show_label=False)
 
 
232
 
233
- gr.Markdown("### Matches")
234
- matches_output = gr.Textbox(lines=8, interactive=False, show_label=False)
235
-
236
- run_btn.click(
237
- fn=run_scan,
238
- inputs=[my_phrase, num_phrases, addresses_file, phrase_mode,
239
- start_index, end_index, passphrase],
240
- outputs=[log_output, matches_output],
241
- )
242
 
243
- # ZeroGPU requirement
244
- _noop()
245
 
246
- _original_launch = demo.launch
247
- def _patched_launch(**kwargs):
248
- kwargs.setdefault("ssr_mode", False)
249
- kwargs.setdefault("share", True)
250
- kwargs.setdefault("server_name", "0.0.0.0")
251
- kwargs.setdefault("server_port", 7860)
252
- return _original_launch(**kwargs)
253
- demo.launch = _patched_launch
254
 
255
- if __name__ == "__main__":
256
- demo.launch(theme=gr.themes.Soft())
 
 
 
 
 
1
+ with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
  my_phrase = gr.Textbox(
3
+ label="Your Phrase (optional)",
4
  value="lesson cushion crane affair federal decline limb spend reunion chief cart zebra",
5
+ lines=2
6
  )
7
+
8
+ with gr.Row():
9
+ num_phrases = gr.Number(label="Random Phrases to Check", value=10, minimum=0)
10
  addresses_file = gr.Textbox(label="Addresses File", value="12730802_addresses.csv")
 
 
 
 
 
 
11
 
12
+ with gr.Row():
13
+ phrase_mode = gr.Radio(choices=["replace", "order", "subset"], value="replace", label="Phrase Mode")
14
+ start_index = gr.Number(label="Start Index", value=0, minimum=0)
15
+ end_index = gr.Number(label="End Index", value=20, minimum=0)
16
 
17
+ with gr.Row():
18
+ passphrase = gr.Textbox(label="BIP39 Passphrase", value="", type="password")
19
+
20
+ run_btn = gr.Button("🚀 Start Scan", variant="primary")
 
 
 
 
 
21
 
22
+ gr.Markdown("### Output")
23
+ log_output = gr.Textbox(lines=15, interactive=False, show_label=False)
24
 
25
+ gr.Markdown("### Matches")
26
+ matches_output = gr.Textbox(lines=8, interactive=False, show_label=False)
 
 
 
 
 
 
27
 
28
+ run_btn.click(
29
+ fn=run_scan,
30
+ inputs=[my_phrase, num_phrases, addresses_file, phrase_mode,
31
+ start_index, end_index, passphrase],
32
+ outputs=[log_output, matches_output]
33
+ )