Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ Options:
iteration. [default: 24]
--is-case-sensitive BOOLEAN Whether the search should be case sensitive
or not. [default: True]
--notify BOOLEAN Notify flag when found pubkey.
--telegram-bot-token TEXT Telegram bot token.
--telegram-chat-id TEXT Telegram chat ID.
--help Show this message and exit.
```

Expand All @@ -72,12 +75,10 @@ $ python3 main.py search-pubkey --starts-with SoL # run
$ solana-keygen pubkey SoLxxxxxxxxxxx.json # you should install solana cli to verify it
```


## FAQs

See [FAQs.md](./FAQs.md).


## Donations

If you find this project helpful, please consider making a donation:
Expand Down
61 changes: 53 additions & 8 deletions core/cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import logging
import multiprocessing
import platform as plf
import sys
from multiprocessing.pool import Pool
from typing import List, Optional, Tuple
Expand All @@ -8,12 +9,14 @@
import pyopencl as cl

from core.config import DEFAULT_ITERATION_BITS, HostSetting
from core.opencl.manager import (
get_all_gpu_devices,
get_chosen_devices,
from core.opencl.manager import get_all_gpu_devices, get_chosen_devices
from core.searcher import multi_gpu_init, parse_result
from core.utils.crypto import save_keypair
from core.utils.helpers import (
check_character,
load_kernel_source,
send_telegram_message,
)
from core.searcher import multi_gpu_init, save_result
from core.utils.helpers import check_character, load_kernel_source

logging.basicConfig(level="INFO", format="[%(levelname)s %(asctime)s] %(message)s")

Expand Down Expand Up @@ -58,6 +61,13 @@ def cli():
@click.option(
"--is-case-sensitive", type=bool, default=True, help="Case sensitive search flag."
)
@click.option(
"--notify/--no-notify",
default=False,
help="Notify flag when found pubkey.",
)
@click.option("--telegram-bot-token", type=str, help="Telegram bot token.")
@click.option("--telegram-chat-id", type=str, help="Telegram chat ID.")
def search_pubkey(
starts_with,
ends_with,
Expand All @@ -66,10 +76,21 @@ def search_pubkey(
select_device,
iteration_bits,
is_case_sensitive,
notify,
telegram_bot_token,
telegram_chat_id,
):
"""Search for Solana vanity pubkeys."""
if not starts_with and not ends_with:
click.echo("Please provide at least one of --starts-with or --ends-with.")
logging.error("Please provide at least one of --starts-with or --ends-with.\n")
ctx = click.get_current_context()
click.echo(ctx.get_help())
sys.exit(1)

if notify and (not telegram_bot_token or not telegram_chat_id):
logging.error(
"Please provide both telegram bot token and chat id when using --notify.\n"
)
ctx = click.get_current_context()
click.echo(ctx.get_help())
sys.exit(1)
Expand All @@ -86,13 +107,26 @@ def search_pubkey(
gpu_counts = len(get_all_gpu_devices())

logging.info(
"Searching Solana pubkey with starts_with=(%s), ends_with=%s, is_case_sensitive=%s",
"Searching Solana pubkey with starts_with=(%s), ends_with=%s, is_case_sensitive=%s, notify=%s",
", ".join(repr(s) for s in starts_with),
repr(ends_with),
is_case_sensitive,
notify,
)
logging.info(f"Using {gpu_counts} OpenCL device(s)")

host_name = plf.node()
if notify:
send_telegram_message(
telegram_bot_token,
telegram_chat_id,
"Starting to search: starts with \\({}\\), ends with {} at __{}__".format(
", ".join(repr(s) for s in starts_with),
repr(ends_with),
host_name,
),
)

result_count = 0
with multiprocessing.Manager() as manager:
with Pool(processes=gpu_counts) as pool:
Expand All @@ -116,7 +150,18 @@ def search_pubkey(
for x in range(gpu_counts)
],
)
result_count += save_result(results, output_dir)
keypairs = parse_result(results)
result_count += len(keypairs)

for keypair in keypairs:
pubkey = save_keypair(keypair, output_dir)

if notify:
send_telegram_message(
telegram_bot_token,
telegram_chat_id,
f"Found pubkey: `{pubkey}` at __{host_name}__",
)


@cli.command(context_settings={"show_default": True})
Expand Down
23 changes: 10 additions & 13 deletions core/searcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
import pyopencl as cl

from core.config import HostSetting
from core.opencl.manager import (
get_all_gpu_devices,
get_selected_gpu_devices,
)
from core.opencl.manager import get_all_gpu_devices, get_selected_gpu_devices


class Searcher:
Expand Down Expand Up @@ -123,14 +120,14 @@ def multi_gpu_init(
return [0]


def save_result(outputs: List, output_dir: str) -> int:
from core.utils.crypto import save_keypair
def parse_result(results: List) -> List[bytes]:
keypairs: List[bytes] = []

result_count = 0
for output in outputs:
if not output[0]:
for result in results:
if not result[0]:
continue
result_count += 1
pv_bytes = bytes(output[1:])
save_keypair(pv_bytes, output_dir)
return result_count

pv_bytes = bytes(result[1:])
keypairs.append(pv_bytes)

return keypairs
14 changes: 14 additions & 0 deletions core/utils/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import Tuple

import pyopencl as cl
import requests
from base58 import b58decode


Expand Down Expand Up @@ -68,3 +69,16 @@ def load_kernel_source(
if cl.get_cl_header_version()[0] != 1 and platform.system() != "Windows":
source_str = source_str.replace("#define __generic\n", "")
return source_str


def send_telegram_message(bot_token: str, chat_id: str, message: str) -> None:
"""
Send a message to a Telegram chat.
"""
try:
requests.post(
f"https://api.telegram.org/bot{bot_token}/sendMessage",
data={"chat_id": chat_id, "text": message, "parse_mode": "MarkdownV2"},
)
except Exception:
pass
3 changes: 2 additions & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ click>=8.1.0
pyopencl
base58
PyNaCl
numpy==1.26.4
numpy==1.26.4
requests