SAGAN User Manual
The LBC Client
Get Work
If you are familiar with the theory behind the pool search effort, you know about the big search space the pool has to cope with. You can decide if you want to fly SAGAN in "autopilot" mode, or if you'd like to perform some manual stunts. The most important parameters for controlling work are:
-t, --time <TIME>
Work duration in minutes. SAGAN will keep requesting work from
the server until the time limit is reached.
-L, --loops <LOOPS>
Number of work request loops. Default: infinite
-N, --block-num <BLOCK_NUM>
Number of blocks per work unit. Default: 1
--cpu-only [<N>]
CPU-only mode (no GPU). Optionally specify number of threads.
--delay <DELAY>
Sleep time between work loops (in seconds).
Auto Mode
If you want to simply throw your client's searching capacity on whatever the pool deems fit and let it work, just run SAGAN without arguments:
saganOn first run, SAGAN will auto-detect your hardware, create a configuration file (lbc.toml), and download the bloom filter file if needed. After that, it continuously requests work from the server and processes it.
The output looks like this:
$ sagan Requesting work from server... Got work: blocks 2780358184..2780360200 (2017 blocks) Start: 00000000000000000000000000000000000000000000000000a5b8e628000000 | 2017 blocks (135359M keys) Block 2017/2017: 135358.58M keys @ 402.08 Mkeys/s Work unit complete: 2017 blocks, 336.65s, 402.08 Mkeys/s Reported work to server Requesting work from server... Got work: blocks 2780360201..2780362210 (2010 blocks)
SAGAN shows the block range it received, the starting private key in hexadecimal, and real-time progress with the current speed in Mkeys/s. When a work unit completes, it reports the results to the server and requests more work.
Terminology
blocks
A block contains 224 (16,777,216) private keys. The server assigns work in blocks,
and SAGAN processes them sequentially, checking each key against the bloom filter of funded addresses.
key/private key
The smallest unit of account. There are almost 2256 possible private keys —
a number so large it defies comprehension. Each key, when processed through elliptic curve multiplication and
hashing, produces a Bitcoin address.
Manual Mode
If you want to search a specific range of blocks, use the --block-start and --block-end options:
$ sagan --block-start 1000 --block-end 2000This will search blocks 1000 through 2000, ignoring server-assigned work.
You can also specify a starting private key directly with the -I, --start-key option:
$ sagan --start-key 0x1000000000000
Standalone Mode
For searching without connecting to the server (e.g., for private searches or testing), use standalone mode:
$ sagan --standalone --block-start 1000 --block-end 2000In standalone mode, SAGAN doesn't report work to the server — you're on your own.
Pulsed Operation
If you can't run SAGAN continuously, use the --delay parameter to specify sleep periods between work loops. Combined with -t (time limit), you can create scheduled operation patterns:
$ sagan -t 10 --delay 5400This runs for 10 minutes, then sleeps for 5400 seconds (90 minutes), then repeats. Useful for:
- Cloud instances with CPU credits (like AWS t2.micro)
- Running only during off-hours on shared machines
- Thermal management on laptops
Continuous Operation
For "fire and forget" operation, SAGAN is designed to run indefinitely by default. It handles:
- Auto-updates — SAGAN checks for updates and can upgrade itself (disable with --no-update)
- Bloom filter updates — automatically downloads new bloom filter files when available
- Network interruptions — gracefully handles temporary connectivity issues
Client Identity and Security
Identity
You can set your own client ID with the --id command line parameter or in the config file. The ID must be between 8 and 32 characters, using only word characters (a-zA-Z0-9_). Valid ID examples:
__rico666__ Colliders_Inc Elliptic_EpilepsyInvalid ID examples:
hello (too short) .-=1337=-. (invalid characters) something_really_long_more_than32 (too long)With a custom ID, you can run SAGAN on multiple machines and have all contributions aggregated under the same identity in the stats.
If you don't set a custom ID, SAGAN will generate one automatically based on your machine's fingerprint.
Security
To protect your identity from being impersonated, you should set a secret (password). This is done in the config file lbc.toml:
id = "YourChosenId" secret = "your-secret-password"
To change an existing secret, use the --chgsecret command line option:
$ sagan --chgsecret old-password new-password Server message: secret set.
Once a secret is set, all operations require the correct secret. Without it:
$ sagan --id YourChosenId -Q
Server answer to 'query' is:
{
"nil" : "wrong secret"
}
The secret is stored salted and SHA256-hashed on the server. If you forget it, the pool administrator can reset it for you, but cannot recover the original value.
BTC Rewards
You can set a BTC address for your client ID either in the config file or via command line. The address is used for any rewards the pool may distribute. Set it in lbc.toml:
id = "YourClientId" secret = "your-secret" address = "1YourBitcoinAddressHere..."Or via command line:
$ sagan --address 1YourBitcoinAddressHere...
You can check your current settings with the query option:
$ sagan -Q
{
"done": 18075470,
"btcadr": "1YourBitcoinAddressHere...",
"lastsee": ...
}
The done field shows the total blocks you have delivered to the pool.
You can change your BTC address at any time. Only the most recent address is active for future payouts.
Wait — what reward?!
When the pool started, some small bounties were planted in the search space for clients to find. While this is fun, it's a "winner takes all" approach that's not what pools are about. With a BTC address attached to your client ID, the pool can reward participants proportionately based on their contributions.
Possible reward scenarios:
- Periodic distributions among top contributors
- If the pool finds an unclaimed address, proportional distribution of the find
- Finder's fees for successful discoveries
GPU
SAGAN supports GPU acceleration via OpenCL, which can dramatically increase your key generation rate compared to CPU-only operation. The GPU performs the computationally intensive hash160 calculations while the CPU handles key generation and bloom filter lookups.
Auto-Detection
On first run, SAGAN automatically detects your GPU and configures optimal settings. If you have a single GPU, everything works out of the box — no configuration needed. The auto-generated lbc.toml will contain:
# GPU device index (use 'sagan --list-devices' to see all) device = 0 # CPU producer threads (from calibration or oracle estimate) threads = 5
Listing Devices
To see all available OpenCL devices on your system:
$ sagan --list-devicesThis shows device indices, names, and capabilities. Use the device index when configuring multiple GPUs.
GPU Configuration
For advanced control, use the --gpu command line option with the format:
--gpu DEVICE[:k=KERNEL][:gt=GPU_THREADS][:ct=CPU_THREADS][:w=WORKSIZE]Parameters:
- DEVICE — OpenCL device index (from --list-devices)
- k=KERNEL — Kernel type (e.g., ecc)
- gt=N — Number of GPU threads
- ct=N — Number of CPU threads (for hybrid kernels)
- w=N — Workgroup size
Example: Use device 0 with the ECC kernel and 2560 GPU threads:
$ sagan --gpu 0:k=ecc:gt=2560
Multiple GPUs
The --gpu option is repeatable. To use multiple GPUs:
$ sagan --gpu 0:gt=2560 --gpu 1:gt=2560This distributes work across both devices.
CPU-Only Mode
To disable GPU acceleration and use only CPU:
$ sagan --cpu-onlyOr specify the number of CPU threads:
$ sagan --cpu-only 8
Benchmarking
To benchmark your GPU kernels:
$ sagan --benchmarkThis helps identify optimal settings for your hardware.
Configuration File
SAGAN uses a TOML configuration file called lbc.toml in the working directory. On first run, SAGAN auto-generates this file with optimal settings for your hardware. You can then customize it as needed.
Example Configuration
# SAGAN Configuration # GPU device index (use 'sagan --list-devices' to see all) device = 0 # CPU producer threads threads = 5 # Bloom filter path bloom = "260118-BTC_90d9f66c.blf" # LBC Server server = "https://lbc.cryptoguru.org" # Client identity id = "YourClientId" secret = "your-secret-password" address = "1YourBitcoinAddress..." # Hook commands (run on events) [hooks] on_start = "./hooks/on_start.sh" on_end = "./hooks/on_end.sh" on_find = "./hooks/on_find.sh" on_error = "./hooks/on_error.sh"
Configuration Options
Hardware Settings
- device — GPU device index (0-based)
- threads — Number of CPU threads for key generation
File Paths
- bloom — Path to the bloom filter file
Server Settings
- server — LBC server URL
Identity Settings
- id — Your client ID (8-32 word characters)
- secret — Password protecting your ID
- address — BTC address for rewards
Command Line Override
Command line options take precedence over config file settings. For example, to temporarily use a different server while keeping all other settings from the config:
$ sagan -s https://other-server.example.com
To use a different config file:
$ sagan -f /path/to/other-config.toml
Found!
Finding a private key is a rare event. Your machine could run for months (or more) without hitting anything, but when it does find something, it happens instantly. What does a find look like?
1768462554 0000000000000000000000000000000000000000000000000000000000000066 c 1768462554 00000000000000000000000000000000000000000000000000000000000f9f8d u 1768462554 00000000000000000000000000000000000000000000000000000000000f9f8d c 1768462554 000000000000000000000000000000000000000000000000000000000340326e c
The format is:
- Timestamp — Unix epoch seconds when the key was found
- Private key — 64-character hexadecimal (256-bit key)
- Type — c for compressed, u for uncompressed public key
This output appears on screen and is also written to FOUND.txt in the SAGAN directory. You don't need to watch the screen constantly — the file will contain all found keys. SAGAN appends to this file, so multiple finds won't overwrite each other.
Converting to Wallet Format
Once you have a private key, you can convert it to WIF (Wallet Import Format) using tools like bitcoin-tool:
./bitcoin-tool \ --input-type private-key \ --input-format hex \ --input <your-hex-key> \ --output-type private-key-wif \ --output-format base58check \ --public-key-compression compressed \ --network bitcoin
Use --public-key-compression uncompressed if the find was marked with u.
What To Do With A Find
This documentation covers the technical aspects of handling a found private key. For what you should do when your client finds something (moving funds to a custodial address, announcing your find publicly, etc.), please see the FAQ.
Hooks
SAGAN supports hooks — shell commands that execute on specific events. Hooks are configured in the [hooks] section of lbc.toml and receive data via environment variables.
Available Hooks
| Hook | Triggered When |
|---|---|
| on_start | SAGAN starts up |
| on_end | SAGAN exits normally |
| on_find | A matching private key is found |
| on_error | An error condition occurs |
Configuration
Add hooks to your lbc.toml:
[hooks] on_start = "./hooks/on_start.sh" on_end = "./hooks/on_end.sh" on_find = "./hooks/on_find.sh" on_error = "./hooks/on_error.sh"Hook scripts can have any name and location — just make sure they're executable.
Environment Variables
Common to all hooks:
- SAGAN_VERSION — SAGAN version string
- SAGAN_CLIENT_ID — Client identifier
on_end (additional):
- SAGAN_UPTIME_SECS — Seconds since SAGAN started
- SAGAN_WORK_UNITS — Number of work units completed
- SAGAN_KEYS_TOTAL — Total keys processed (approximate)
- SAGAN_MKEYS_SEC — Measured speed in Mkeys/s
on_find (additional):
- SAGAN_PRIVKEY — The found private key (hex) — this is the critical data!
- SAGAN_HASH160 — The hash160 that matched
on_error (additional):
- SAGAN_ERROR — Error message
Example: on_find Hook
#!/bin/sh
# on_find.sh - notify when a key is found
echo "[on_find] KEY FOUND!"
echo " Privkey: ${SAGAN_PRIVKEY}"
echo " Client ID: ${SAGAN_CLIENT_ID}"
# Desktop notification (Linux)
notify-send "SAGAN: Key Found!" "$SAGAN_PRIVKEY"
# Secure backup
echo "$(date +%s) $SAGAN_PRIVKEY" >> ~/secure/found_keys.log
# HTTP notification
curl -X POST https://your-endpoint/found -d "key=$SAGAN_PRIVKEY"
Example: on_error Hook
#!/bin/sh # on_error.sh - log errors to syslog logger -t sagan "Error: $SAGAN_ERROR (client: $SAGAN_CLIENT_ID)" # Or send email echo "SAGAN error: $SAGAN_ERROR" | mail -s "SAGAN Alert" you@example.com
Notification Methods
Email — If your system can send mail:
#!/bin/sh echo "Key found: $SAGAN_PRIVKEY" | mail -s "SAGAN FIND" you@example.com
Pushbullet — Using the Pushbullet CLI:
#!/bin/sh pb push "SAGAN found a key: $SAGAN_PRIVKEY"Setup: pip install pushbullet-cli && pb set-key YOUR_API_KEY
HTTP/Webhook — Send to any HTTP endpoint:
#!/bin/sh
curl -X POST https://your-server/webhook \
-H "Content-Type: application/json" \
-d "{\"key\":\"$SAGAN_PRIVKEY\",\"client\":\"$SAGAN_CLIENT_ID\"}"