Bot Configurations
The complete SolanaMevBot 2.0.0 configuration reference
Version 2.0.0 uses [bot], one or both settlement profiles under [auto], and a repeated [[senders]] entry for each sending service. [auto_rebalance] and [log] are optional.
Unknown config fields are rejected. Start from a 2.0.0 example instead of carrying forward a 1.x config.
Bot
[bot]
rpc_url = "https://YOUR_READ_RPC"
encrypted_key_path = "~/keys/ENCRYPTED_PRIVATE_KEY"
flashloan = true| Field | Default | Meaning |
|---|---|---|
rpc_url | Required | Solana RPC for account reads and blockhashes. Must support reads, not just transaction submission. |
flashloan | false | Enable borrowing from the executor's settlement loan vault. The wallet still pays fees, tips, and account creation. |
encrypted_key_path | Automatic search | Path to an existing bot key file. Supports ~/, absolute paths, and paths relative to the working directory. Without it, the bot searches for ENCRYPTED_PRIVATE_KEY in the working directory and its parents. |
private_key | Unset | First-run key import: a base58 string or a JSON byte array encoded as a string. The bot writes ENCRYPTED_PRIVATE_KEY and exits. Remove this field before restarting. Do not combine it with an existing key file. |
See Getting Started for first-run key setup.
Automatic market selection
Configure [auto.sol], [auto.usdc], or both. Each profile selects routes that start and end in its settlement token. The SOL profile settles in wrapped SOL (WSOL).
[auto.sol]
min_total_profit = 5_000_000
min_tx_count = 2
lookback_secs = 3_600
max_routes = 50
process_delay = 50
[auto.usdc]
min_total_profit = 750_000
min_tx_count = 2
lookback_secs = 3_600
max_routes = 25
process_delay = 50| Field | Default | Meaning |
|---|---|---|
min_total_profit | Required per profile | Combined profit the feed observed through a route during lookback_secs. Integer lamports for SOL; integer millionths of USDC for USDC. |
min_tx_count | 1 | Minimum observed transaction count. Integer from 1 to 9_007_199_254_740_991. |
lookback_secs | 300 | Observation window in seconds, from 1 to 3600. |
max_routes | 50 | Maximum selected routes for this settlement, from 1 to 100. |
process_delay | 0 | Milliseconds each route waits between send passes. 0 adds no timed delay. |
For example, 5_000_000 is 0.005 SOL in [auto.sol], while 750_000 is 0.75 USDC in [auto.usdc]. These are historical selection thresholds, not per-trade profit requirements. The program checks current pool state when a transaction executes.
Each route runs independently. process_delay is not a global requests-per-second limit; use each sender's rate_limit_per_second to cap submissions across all routes and both settlements.
Senders
Add at least one enabled sender to submit transactions. Each sender builds transactions using its own prices and tips.
[[senders]]
name = "rpc"
type = "json_rpc"
urls = ["https://YOUR_SENDING_RPC"]
rate_limit_per_second = 20
compute_unit_price = { strategy = "Random", from = 1000, to = 2000, count = 1 }
request_params = { maxRetries = 10 }Sender types and defaults
type | Request format | Default submissions/second | Default timeout | Default strategy |
|---|---|---|---|---|
json_rpc | JSON-RPC sendTransaction | 20 | 1500 ms | AllAtOnce |
jito | JSON-RPC sendBundle; appends /bundles to each URL | 1 | 5000 ms | OneByOne |
send_bundle | JSON-RPC sendBundle to the exact URL | No configured cap | 5000 ms | AllAtOnce |
submit_batch | A transactions array of base64 transactions | No configured cap | 5000 ms | AllAtOnce |
next_block | A transaction object with base64 content | No configured cap | 5000 ms | AllAtOnce |
harmonic | Harmonic bundles over gRPC (2.0.2 or later) | No configured cap | 5000 ms | OneByOne |
type is required. For jito, supply a block-engine URL ending in /api/v1, not /api/v1/bundles. For harmonic, supply a regional URL such as https://fra.be.harmonic.gg; see Harmonic.
Sender fields
| Field | Default | Meaning |
|---|---|---|
name | Required | Nonempty, unique name used in logs, including for disabled senders. |
type | Required | One of the six types above. |
enabled | true | Whether this sender submits transactions. |
urls | Empty | Endpoint URLs. Required for an enabled sender unless using keys. |
auth_header, auth_value | Unset | HTTP authentication header and value. Set both together. Not accepted by harmonic. |
keys | Empty | Endpoint groups with separate credentials; see below. Not accepted by harmonic. |
request_params | Unset | Table merged into JSON-RPC request options. Supported by json_rpc, jito, and send_bundle only. |
sending_strategy | By type | AllAtOnce sends to every endpoint. OneByOne rotates the starting endpoint and tries another on connection failures, timeouts, HTTP server errors (5xx), or gRPC errors other than a rejection or rate limit. Acceptance, application-level rejection, and rate-limit responses end that submission. |
compute_unit_price | Unset | Priority price strategy in micro-lamports per CU. Unset means no added priority fee. Required for harmonic, at least 10000. |
tip_amount | Unset | Tip strategy in lamports. Required for jito. Not accepted by harmonic, which is paid through compute_unit_price. |
tip_accounts | Empty | Tip destination public keys. Required with a tip for non-Jito senders. Jito uses its built-in accounts when omitted. |
rate_limit_per_second | By type | Integer from 1 to 1000. Shared across all routes, settlement profiles, keys, and source IPs for this sender. |
timeout_ms | By type | Positive request timeout in milliseconds. |
no_failure_mode | false | Allow the executor to return without a trade when no profitable route is found. Does not suppress every possible transaction error. |
uuid | Unset | Jito-only uuid query parameter. |
auth_keypair | Unset | Harmonic-only: path to the keypair file of a public key Harmonic whitelisted. Without it, bundles go to Harmonic's public service. |
ip_addresses | Empty | Local source IPs or CIDR ranges. Submissions rotate through them. These addresses must be configured on your machine. Not accepted by harmonic. |
use_separate_tip_account | On for Jito with ip_addresses; otherwise off | Jito-only: use a temporary tip account and a second transaction in the bundle to forward the tip. Requires tip_amount. |
A sender's rate limit counts submissions. With AllAtOnce, one submission contacts every configured endpoint, so the number of HTTP requests can be higher.
JSON-RPC transaction options default to encoding = "base64", skipPreflight = true, preflightCommitment = "confirmed", and maxRetries = 10. Bundle options default to encoding = "base64". request_params overrides matching options. Keep base64 encoding, since that is how the bot serializes transactions.
Multiple credentials
Use [[senders.keys]] when one sender has multiple endpoint groups with different credentials. Each group supports urls, auth_header, auth_value, and request_params.
[[senders]]
name = "rpc-keys"
type = "json_rpc"
rate_limit_per_second = 10
sending_strategy = "OneByOne"
request_params = { maxRetries = 0 }
[[senders.keys]]
urls = ["https://YOUR_FIRST_RPC"]
auth_header = "authorization"
auth_value = "YOUR_FIRST_API_KEY"
[[senders.keys]]
urls = ["https://YOUR_SECOND_RPC"]
auth_header = "authorization"
auth_value = "YOUR_SECOND_API_KEY"When using keys, omit sender-level urls, auth_header, and auth_value. A key's request_params replaces the sender-level table for that key; the chosen table is then merged into the request defaults.
Tips and no-failure mode
With no_failure_mode = false, a tipped transaction requires profit to cover at least its tip. For USDC settlement, the bot converts the SOL tip into USDC with a 20% margin. This floor does not cover every cost, such as transaction fees.
With no_failure_mode = true, the bot removes that tip-based profit floor. A transaction may succeed without a trade and still pay its tip and network fees. This setting does not make submissions free or guarantee a profit.
Astralane endpoints without a supplied API key use the bot's shared default key and require no_failure_mode = true. Use an api_key header or an api-key/api_key URL query parameter to supply your own key.
See Sending Vendor Examples for service-specific setups.
Price and tip strategies
compute_unit_price and tip_amount use the same strategy structure, except Helius is supported only for compute unit prices. Strategy names are case-sensitive.
| Strategy | Fields | Behavior |
|---|---|---|
Random | from, to, count | Uniform random integers in the inclusive range. Set from equal to to for a fixed value. |
ExponentialRandom | from, to, count | Random values distributed on a logarithmic scale. Use positive from below to. |
Linear | from, to, count | Values spaced with an integer step across the range. One value uses from. |
Exponential | from, to, count | Values spaced geometrically across the range. from must be at least 1. |
File | file_path | Read integer values, one per line. Blank lines and # or // comments are ignored. The file is reread each send pass. |
Helius | api_key; optional fields below | Scale the Helius priority fee estimate for the transaction's accounts. |
For the four range strategies, provide count of at least 1 and from no greater than to (ExponentialRandom requires a strict increase). An optional min sets a lower bound on generated values for non-Helius strategies. max applies only to Helius.
Each send pass tries the combinations of generated tip amounts and compute unit prices, subject to the sender's shared rate limit. For example, two tips and three prices produce six candidate submissions per basket.
Helius priority prices
[[senders]]
name = "rpc-helius-prices"
type = "json_rpc"
urls = ["https://YOUR_SENDING_RPC"]
compute_unit_price = { strategy = "Helius", api_key = "YOUR_HELIUS_API_KEY", from = 90, to = 130, count = 3, max = 20000, fetch_interval = 5 }Here from and to are percentages of the estimate, not micro-lamport amounts. This example generates three prices from 90% to 130% of the estimate, capped at 20,000 micro-lamports per CU.
| Helius field | Default | Meaning |
|---|---|---|
api_key | Required | Helius API key used for priority fee estimates. |
from | 100 | Starting percentage of the estimate. |
to | Same as from | Ending percentage. |
count | 1 | Number of generated prices; values below 1 are treated as 1. |
max | Unset | Upper bound in micro-lamports per CU. |
fetch_interval | 5 | Cache interval in seconds, with a minimum of 1. |
account_keys | Empty | Additional account addresses to include with the transaction's accounts when requesting an estimate. |
Auto-rebalance
This optional section checks the wallet every minute. When native SOL falls below min_sol_balance, the bot unwraps WSOL and wraps min_wsol_balance again. It skips rebalancing if the combined SOL and WSOL balance is below the two configured amounts added together.
[auto_rebalance]
min_sol_balance = 500_000_000
min_wsol_balance = 200_000_000
compute_unit_price = 10_000All three fields are required when this section is present. Balances are in lamports; compute_unit_price is in micro-lamports per CU. Rebalancing does not sell USDC, and it is not an initial funding mechanism for the WSOL account.
Logging
[log]
enable_sending_log_summary = true
summary_interval_seconds = 60enable_sending_log_summary defaults to false. When enabled, periodic summaries replace per-transaction sending logs. summary_interval_seconds defaults to 60.
Applying config changes
The bot checks the config file every second. Sender settings and filters for the existing settlement profiles can update while it runs. Invalid edits keep the previous config active.
Restart after adding or removing a settlement profile, changing the RPC or wallet, or changing auto-rebalance settings. These changes take effect on the next start.
Removed 1.x settings
| Previous setting | 2.0.0 replacement |
|---|---|
[rpc] | bot.rpc_url |
[wallet] | bot.private_key for first import, then bot.encrypted_key_path |
[flashloan].enabled | bot.flashloan |
[spam], [jito], [[sending_venders.sending_vender]] | [[senders]] with an explicit type |
request_format, enable_submit_batch | Sender type = "send_bundle" or "submit_batch" |
| Manual mint/pool lists and bundle groups | [auto.sol] and/or [auto.usdc] |
| Manual compute limits, transaction-version selection, and lookup table configuration | Managed by the bot |
Remove old fields rather than leaving them alongside the new ones: unknown fields prevent the config from loading.