NotArb - Solana Arbitrage Bot
  • Getting Started
    • Welcome
    • Changelog
    • The Basics
  • Setup
    • Start Here!
    • Prerequisites
      • Recommended Apps
      • RPC Providers
      • Linux Machines
    • Logging in Using SSH
    • Securing Your Machine
      • User Management
      • SSH Key-Based Authentication
      • Setting up UFW
      • Setting up fail2ban
      • Securing Wallet Private Key
    • Setting up for FTP
    • Initial Setup of NotArb
    • Using Screens
    • Making a Solana Wallet
  • Configurations
    • Using Nano
    • Config Basics
    • bot-config.toml
      • General Bot Settings
      • WSOL Unwrapper
      • JITO Strategy Settings
      • Spam Strategy Settings
      • Token Lists Settings
      • Swap Settings
    • jupiter-config.toml
      • Manager Settings
      • Env Settings
      • Mint Filters
    • Shell Scripts
      • run-bot.sh
      • run-jupiter.sh
      • run-screens.sh
  • Usage
    • Strategies
      • Jito Strategy
      • Spam Strategy
    • Updating
  • EXPERIMENTAL FEATURES
    • Overview & Caution
    • New Setup Configurations
  • New Mint Configurations
  • Default Strategy Fields
  • Jito Example
  • Spam Example
  • Extra Features
  • Support
    • FAQ
    • Common Issues
    • Troubleshooting
    • NotArb Docs Tracker
    • Contact
Powered by GitBook
On this page
  • v0.9-Alpha
  • v0.9.50 (EXPERIMENTAL RELEASE)
  • v0.9.10 (EXPERIMENTAL RELEASE)
  • v0.1-Alpha
  • v0.1.91-alpha
  • v0.1.90-alpha
  • v0.1.89-alpha
  • v0.1.88-alpha
  • v0.1.87-alpha
  • v0.1.85/86-alpha
  • v0.1.84-alpha
  • v0.1.83-alpha
  • v0.1.82-alpha
  • v0.1.81-alpha
  • v0.1.80-alpha
  • v0.1.79-alpha
  • v0.1.78-alpha
  • v0.1.77-alpha
  • v0.1.76-alpha
  • v0.1.75-alpha
  • v0.1.74-alpha
  • v0.1.73-alpha
  • v0.1.72-alpha
  • v0.1.71-alpha
  • v0.1.70-alpha
  • v0.1.69-alpha
  1. Getting Started

Changelog

NotArb Changelogs

PreviousWelcomeNextThe Basics

Last updated 2 months ago

v0.9-Alpha

We'll break these update notes into several parts:

  1. New Setup Configurations

  2. New Mint Configurations

  3. Default Strategy Fields

  4. Jito Example Configuration

  5. Spam Example Configuration

  6. Extra Features & Notes

New Setup Configurations

[blockhash_fetcher] # required
rpc_url="http://111.222.333.69:8899/"
[token_accounts_fetcher] # not required but encouraged
rpc_url="http://111.222.333.69:8899/"
[plugin] # required
class="" # default values below

You'll notice some of these configurations changed from rpc to rpc_url as we will now only be defining "rpc" configurations for spam sending. It's also important to note the following configurations have been removed:

  • [[static_mints]]

  • [dynamic_mints]

New Mint Configurations

As mentioned above, [[static_mints]] and [dynamic_mints] have been removed. The two remaining mint configurations are:

[[file_mints]]
enabled=true
update_seconds=10 # optional field - when set, this file will be loaded every X amount of seconds (default 0)
max_per_cycle=10 # optional - the maximum amount of mints that can be processed from this mint supplier per bot cycle (default unlimited)
random_order=false # optional field - use this to randomize the order of the list every cycle (default false)
path="/path/to/mints.txt" # supports raw text (1 mint per line) and json
[[url_mints]]
enabled=false
update_seconds=10 # optional field - when set, this url will be loaded every X amount of seconds (default 0)
max_per_cycle=10 # optional - the maximum amount of mints that can be processed from this mint supplier per bot cycle (default unlimited)
random_order=false # optional field - use this to randomize the order of the list every cycle (default false)
url="http://youminturl.com/" # the actual extension here doesn't matter, as long as the output is either a json list of strings or raw text of 1 mint per line (raw text supports # comments)

You can now optionally pass %TIMESTAMP% in your url field to add a milliseconds timestamp to your url for caching purposes, for example:

url="https://notarb.org/mints?t=%TIMESTAMP%"

Mint Tags You can now tag mints like so:

So11111111111111111111111111111111111111112,perps # wsol
EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v,perps # usdc
Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB,perps # usdt
USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA,perps # usds
6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN,meme # trump

Multiple tags are allowed, use commas as separators. Mint tags can be used as part of strategies to either accept specific mints or skip them, here's an include example: mint_include_tags=[ ["perps"] ] Notice this is an array of tag groups, where in order for the mint to be accepted it has to match at least one group. In this example "perps" is its own group. If any mints have tag "perps" it'll be accepted by the strategy. However, if you were to do: mint_include_tags=[ ["perps", "something"] ] The strategy would only accept mints that have both tags "perps" and "something" Now, onto a multiple group example: mint_include_tags=[ ["perps", "something"], ["meme"] ] A mint will be accepted by the strategy if any of the groups match, so the mint will either have to have both tags "perps" and "something" OR just have "meme" Remember, only one group needs to match! Now, that brings us to skipping mints per strategy: mint_exclude_tags=[ ["someTag"] ] The same logic applies, only one tag group must match for a mint to be skipped by the strategy.

Default Strategy Fields

The following fields can be set per all strategies:

  • mint_include_tags string[][]

  • mint_exclude_tags string[][]

  • entry_quote_error_print bool

  • exit_quote_error_print bool

  • same_pool_error_print bool

  • kamino_borrow_amount num

  • max_lookup_tables num (default 4)

  • min_spend num

  • max_spend num

  • min_priority_fee_lamports num

  • max_priority_fee_lamports num

  • min_swap_routes num

  • max_swap_routes num

  • cu_limit num (if not set, automatically set for jito only)

  • cooldown_ms num OR cooldown string (ex: "1ms")

  • entry_only_direct_routes OR entry_direct bool

  • entry_legacy bool

  • entry_restrict_intermediate_tokens bool

  • entry_max_accounts num

  • entry_include_dexes string[]

  • entry_exclude_dexes string[]

  • exit_only_direct_routes OR exit_direct bool

  • exit_legacy bool

  • exit_restrict_intermediate_tokens bool

  • exit_max_accounts num

  • exit_include_dexes string[]

  • exit_exclude_dexes string[]

  • min_gain_bps num

  • min_gain_percent num

  • min_gain_lamports num (yes, this works with any base)

  • min_gain_sol num

Jito Example Configuration

At the moment, only static proxy tip transactions are supported. Because of this, you must keep in mind your min gain should be able to cover the following:

  • 5000 lamports network fee for swap tx.

  • 5000 lamports network fee for tip tx.

  • At minimum 1000 lamports for tip.

  • Priority fee, if set.

Min gains are purely gains between the Jupiter exit and entry quotes. They do not factor in fees for you. Nor should they be looked at as what you'll net. They're simply an estimation of what you'll gross before network fees. The following fields can be set per Jito strategies:

  • static_tip_percent num

  • static_tip_lamports num

  • static_tip_sol num

[bot_misc]
keypair_path="/path/to/keypair.json" # required for signing transactions
protect_keypair=true
acknowledge_terms_of_service=false
acknowledge_external_price_risk=false
acknowledge_experimental_release=false

[jupiter]
url="http://127.0.0.1:8080"
workers=6 # the amount of connections and threads used to make jupiter requests
connect_timeout_ms=1000
request_timeout_ms=1000

[blockhash_fetcher]
rpc_url="http://111.222.333.69:8899/"

[token_accounts_fetcher] # not required but encouraged
rpc_url="http://111.222.333.69:8899/"

[[file_mints]]
enabled=true
update_seconds=10
path="/path/to/mints.txt"

[plugin]
class="org.notarb.DefaultJito"

[[jito_unbound_rpc]] # if you prefer, you can use [[jito_unbound_grpc]] here instead for grpc sending vs http sending
url="https://slc.mainnet.block-engine.jito.wtf"
bind_ips=[
    #"123.456.789.10/25", # cidr ranges supported
    "127.0.0.1", # this will use your default ip instead of binding
]
proxy_keypairs_path="" # optionally pass an absolute path to a file of raw keypairs (1 per line) of wallets to be used for tips (these wallets must have enough balance to cover rent)

# A worker is a thread that manages a queued http connection and dispatches http requests on that connection.
# (At least 1 worker of any type required)
busy_workers = 2    # Continuously checks for work (100% CPU, lowest latency)
spin_workers = 0    # Uses CPU hint instructions (high CPU, very low latency)
yield_workers = 0   # Yields to other threads when idle (medium CPU, moderate latency)

# Misc http options
connect_timeout_ms = 5000
request_timeout_ms = 5000
idle_timeout_ms = 10_000

## SOL (Jito)
[[swap]]
enabled=true
mint="SOL"

[swap.strategy_defaults]
cooldown_ms=10

[[swap.strategy]]
min_spend=0.5
max_spend=1
min_gain_lamports=20_000
static_tip_lamports=6900

[[swap.strategy]]
min_spend=0.5
max_spend=1
min_gain_lamports=20_000
static_tip_percent=5

Spam Example Configuration

The following fields can be set per Spam strategies:

  • max_opportunity_age_ms num OR max_opportunity_age string (ex: "100ms")

  • spam_senders array

[bot_misc]
keypair_path="/path/to/keypair.json" # required for signing transactions
protect_keypair=true
acknowledge_terms_of_service=false
acknowledge_external_price_risk=false
acknowledge_experimental_release=false

[jupiter]
url="http://127.0.0.1:8080"
workers=6 # the amount of connections and threads used to make jupiter requests
connect_timeout_ms=1000
request_timeout_ms=1000

[blockhash_fetcher]
rpc_url="http://111.222.333.69:8899/"

[token_accounts_fetcher] # not required but encouraged
rpc_url="http://111.222.333.69:8899/"

[[file_mints]]
enabled=true
update_seconds=10
path="/path/to/mints.txt"

[plugin]
class="org.notarb.DefaultSpam"

[[spam_rpc]]
enabled=true
id = "test"
url = "http://123.45.67.89:8899"

# A worker is a thread that manages a persistent http connection and dispatches http requests on that connection.
# (At least 1 worker of any type required)
busy_workers = 2    # Continuously checks for work (100% CPU, lowest latency)
spin_workers = 0    # Uses CPU hint instructions (high CPU, very low latency)
yield_workers = 0   # Yields to other threads when idle (medium CPU, moderate latency)

# Misc http options
connect_timeout_ms = 5000
request_timeout_ms = 5000
idle_timeout_ms = 10_000 # how long a connection can go without sending before timing out (important to have for http since most servers will end the connection on their end after so much time)

## SOL (Spam)
[[swap]]
enabled=true
mint="SOL"

[swap.strategy_defaults]
cooldown_ms=10
max_opportunity_age_ms=100

[[swap.strategy]]
min_spend=0.0001
max_spend=0.1
cu_limit=369_369
min_priority_fee_lamports=187
max_priority_fee_lamports=369
min_gain_lamports=5000
spam_senders=[
    { rpc="test", skip_preflight=true, max_retries=0 },
    { rpc="test", skip_preflight=true, max_retries=0 },
]

Extra Features and Notes

Extra Features & Notes

  • All swaps will now be done on our own swap program instead of Jupiter's.

  • As seen above, a new strategy field kamino_borrow_amount is now available for Kamino flash loans.

  • A new plugin system has been implemented, but still in the works.

  • Additional encryption has been added to protected keypairs. (Reminder: this encryption will simply buy you time if your server is compromised.)

In order to run the new jar, the following vm arg must be added: "--add-exports=java.base/jdk.internal.util=ALL-UNNAMED" You can either add this to vm_args inside of the run-bot.sh file, or to the notarb_java.sh file after --enable-preview. If you run multiple bots on the same server and you're trading anything other than WSOL, you'll want to add the following configuration and either use a bind ip or proxy.

[price_fetcher] # not required to be defined unless you want to use a bind ip or proxy (only needed when using non-wsol base tokens)
#bind_ip=""
#proxy_host=""
#proxy_port=123
#proxy_user=""
#proxy_pass=""

Edit: The optional [wsol_unwrapper] configuration slightly changed, here's an example:

[wsol_unwrapper]
enabled=true
rpc_url="http://123.45.67.89:7399/" # the rpc used for the balance check & rebalance transaction
check_minutes=1 # interval in minutes to check if an unwrap is required
min_sol=0.5 # triggers an unwrap when your sol balance is less than this number
unwrap_sol=1 # aims to leave at least this amount of sol unwrapped
priority_fee_lamports=190 # optional, but can help tx land

Edit: The following mints support Kamino flash loans:

SOL, USDC, USDT, USDS, PYUSD, JLP, JUPSOL

  • Several changes to increase overall performance and speed.

  • Jupiter configurations should now set DISABLE_SWAP_CACHE_LOADING="true" as NotArb will be responsible for providing important swap data.

  • Because NotArb no longer uses Jupiter to build transactions, the bot now requires a field called blockhash_rpc_url="http://rpc.url:1234" inside of [bot_misc]- this field is temporary and will most likely be moved.

  • A new Strategy field max_lookup_tables has been added, and for testing purposes currently defaults to 10.

About Lookup Tables

Lookup tables allow transactions to include more accounts while bringing the size of the transaction down. Smaller transaction sizes can technically send over the network faster, but you have to keep in mind the time it takes for the validator processing the transaction to lookup said table on chain. With that being said, the maximum number of lookup tables to include per strategy will be something you have to feel out and decide what you prefer.

What Does Not Work

  • Simulation mode has not yet been converted.

  • "Unique" spam transactions have not yet been converted.

  • "Unique" jito transactions when sending the same transaction to multiple zones has not yet been converted.

What's New

Unbound static jito tip transactions are now smarter than ever and will cover the amount required to open a proxy wallet account, returning said amount at the end of the transaction

v0.1-Alpha

  • Added the TRUMP (6p6xgHyF7AeE6TZkSmFsko444wqoP15icUSqi2jfGiPN) token as a base token

  • Added support for unbound grpc static tips. (Unbound depends on multiple IPs. Static txs will only send if the static tip can cover the cost of the proxy wallet rent...)

  • Updated outdated libs

  • Added several new base tokens, thanks to @Spif. A full list can be found here: https://github.com/NotArb/Jupiter/blob/main/BASE_TOKENS.txt

  • Introduced a new strategy field: skip_user_accounts_rpc_calls. Set this to true only if you are absolutely certain all trades will involve tokens with pre-opened accounts. Alternatively, use the new [account_tokens_fetcher] feature to let the bot smartly skip unnecessary RPC calls.

  • Updated GitHub docs.

One of my commits from last night was overwritten before this update that causes the [token_accounts_fetcher] to not work... fixed in .89

  • Added a new optional [token_accounts_fetcher] feature, more on this below.

  • Fixed an issue that would cause extra data to be added to JSON encoded strings.

  • Other miscellaneous under the hood changes.

The token accounts fetcher is a new optional feature that can be used to help speed up Jupiter /swap requests. How does it work?

When the token accounts fetcher is enabled, a background task will run every 5 seconds monitoring your open token accounts. The bot will then be able to determine if RPC calls can be skipped when making /swap requests to Jupiter. In the case that they can, swap time is significantly improved.

How to enable it:

[[rpc]]
id="lava"
url=""

[token_accounts_fetcher]
enabled=true
rpc="lava"

Keep in mind this feature is optional and will not stop token accounts from being opened.

  • Changed default Jito Bundle encoding to Base64

  • Jupiter price fetches will now skip responses marked as "low" confidence.

  • The [url_mints] fetches will no longer append ?notArbMs to the url. (We will attempt to bypass cache on our end, you should ensure your webhost does the same for your url)

  • Fixed some mislabled bot output & config docs.

  • [bot_misc] You can now optionally set jito_threads=-1 and/or spam_threads=-1 to use dynamic thread pooling. (This will not work with swap_threads!) [bot_misc]

  • Added a new optional debug field debug_executors=true which will print executor information every 10 seconds. (Only use for debugging, this will slightly slow down cycles)

Warning: Versions below v0.1.85 will be discontinued in the near future. Two new [bot_misc] fields have been added:

acknowledge_terms_of_service

acknowledge_external_price_risk

I don't want this to scare anyone, but from a legal standpoint I have to lookout for myself. With that being said, this new mandatory configuration field must be set to true to use NotArb.

What you'll see when the bot doesn't have this set to true:

Error: Terms of Service Not Acknowledged

In order to use this bot, you must first acknowledge that you have read and accepted our Terms of Service. This is required to ensure a clear understanding of the terms and any potential risks associated with using the bot.
You can review our full Terms of Service here: https://tos.notarb.org/
To proceed, please set the following in your configuration file under [bot_misc]:
acknowledge_terms_of_service=true

acknowledge_external_price_risk

Similar to above, this field is required to arb with non-wsol bases.

What you'll see when the bot doesn't have this set to true:

Error: External Price Risk Not Acknowledged

Trading using non-WSOL base tokens detected:
...

This bot relies on external price feeds to calculate profits for non-WSOL base swaps. While every effort is made to ensure the accuracy and reliability of price data, these external feeds may potentially provide incorrect information. This could result in inaccurate profit calculations and unintended overpayment of fees or tips (e.g., to Jito).
Although such occurrences are highly unlikely, they remain possible due to reliance on third-party data.

To proceed, please set the following in your configuration file under [bot_misc]:
acknowledge_external_price_risk=true

By enabling this field, you acknowledge and accept all risks associated with external price data and waive any liability for issues arising from it.

v0.1.85 Notes

  • Added a secondary layer of price validation for non-wsol tokens.

  • Added a secondary layer of price validation for usd pegged tokens. (USDC, USDT, PYUSD, etc...)

  • The Jupiter Management server will now default to Jupiter v6.0.29 instead of the latest versions. The latest versions are only advised if you manually adjust new Jupiter thread envs.

v0.1.86 Notes

  • Transaction prints will now include the baseMint and targetMint

This update will require update configurations. Previous configs will not work.

Basic

  • Overhauled mint configuration for both the bot and Jupiter management server. More on this below.

  • You can now make multiple [[swap]] configs with the same mint values. Why? This can help keep configs tidy!

  • Removed deprecated strategy field jito_tip_percent which was replaced with jito_dynamic_tip_percent

  • Removed deprecated strategy field spam_cooldown which was replaced with cooldown

Mints

All mint loading for both the bot and Jupiter management server have been changed, please change your configs accordingly.

[dynamic_mints] # this is the only mint configuration where only one is allowed, hence the single brackets
enabled=true
limit=100 # optional - limits the number of mints obtained from this supplier, ordered by highest daily volume first
export_path="dynamic-mints.txt" # optional - useful for debugging

untradable_cooldown="1m" # if the bot detects an untradable token, that token will be put on a cooldown for the given duration (default 1m)
max_per_cycle=10 # optional - used to limit how many mints can be processed from this mint supplier per bot cycle (default unlimited)
update_seconds=10 # this pulls from Jupiter's public endpoint, keep that in mind if running multiple bots for rate limiting (default 10, min 5)

exclude=[ # optional
    "So11111111111111111111111111111111111111112",  # sol
    "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", # usdt
    "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", # usdc
]

## NOTE: Filter configurations must be placed at the end, after other settings like exclude and enabled. ##

[[dynamic_mints.filter]] # example filter to pick up all mints with either a birdeye-trending tag OR pump and verified tags
include_tags=[ # an array of tag groups, only one group match required to be included
    ["birdeye-trending"],
    ["pump", "verified"]
]

[[dynamic_mints.filter]] # example filter to pick up new mints
max_age="3d" # d=days, h=hours, m=minutes
min_daily_volume=10_000
exclude_tags=[ # an array of tag groups, only one group match is required to be excluded
    ["strict"],
    ["community"]
]

Jupiter Example:

[dynamic_mints] # this is the only mint configuration where only one is allowed, hence the single brackets
enabled=true
limit=100 # optional - limits the number of mints obtained from this supplier, sorted by daily volume (higher volume first)
export_path="dynamic-mints-jup.txt" # optional - useful for debugging

exclude=[ # optional
    "So11111111111111111111111111111111111111112",  # sol
    "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", # usdt
    "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", # usdc
]

## NOTE: Filter configurations must be placed at the end, after other settings like exclude and enabled. ##

[[dynamic_mints.filter]] # example filter to pick up all mints with either a birdeye-trending tag OR pump and verified tags
include_tags=[ # an array of tag groups, only one group match required to be included
    ["birdeye-trending"],
    ["pump", "verified"]
]

[[dynamic_mints.filter]] # example filter to pick up new mints
max_age="3d" # d=days, h=hours, m=minutes
min_daily_volume=10_000
exclude_tags=[ # an array of tag groups, only one group match is required to be excluded
    ["strict"],
    ["community"]
]

Static Mints Static mints are a fixed list of mints loaded straight from your configuration file that will never change except for on restarts. Bot Example:

[[static_mints]] # double brackets since we allow multiple
enabled=true
untradable_cooldown="1m" # if the bot detects an untradable token, that token will be put on a cooldown for the given duration (default 1m)
max_per_cycle=10 # optional field - use this to limit how many mints can be processed from this mint supplier per bot cycle (default unlimited)
random_order=false # optional field - use this to randomize the order of the list every cycle (default false)
list=[
    "So11111111111111111111111111111111111111112",  # sol
    "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", # usdt
    "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", # usdc
]

Jupiter Example:

[[static_mints]] # double brackets since we allow multiple
enabled=true
list=[
    "So11111111111111111111111111111111111111112",  # sol
    "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB", # usdt
    "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", # usdc
]

File Mints File mints are loaded from a local file either in json or raw text format. Bot Example:

[[file_mints]]
enabled=true
untradable_cooldown="1m" # if the bot detects an untradable token, that token will be put on a cooldown for the given duration (default 1m)
max_per_cycle=10 # optional field - use this to limit how many mints can be processed from this mint supplier per bot cycle (default unlimited)
random_order=false # optional field - use this to randomize the order of the list every cycle (default false)
update_seconds=10 # optional field - when set, this file will be loaded every X amount of seconds (default 0)
path="/absolute/path/to/mints.json OR /absolute/path/to/mints.txt" # the actual extension here doesn't matter, as long as the output is either a json list of strings or raw text of 1 mint per line (raw text supports # comments)

Jupiter Example:

[[file_mints]] # only loaded on start/restart
enabled=true
path="/absolute/path/to/mints.json OR /absolute/path/to/mints.txt"

URL Mints URL mints are loaded from a web url which supports json or raw text format. Bot Example:

[[url_mints]]
enabled=true
untradable_cooldown="1m" # if the bot detects an untradable token, that token will be put on a cooldown for the given duration (default 1m)
max_per_cycle=10 # optional field - use this to limit how many mints can be processed from this mint supplier per bot cycle (default unlimited)
random_order=false # optional field - use this to randomize the order of the list every cycle (default false)
update_seconds=10 # optional field - when set, this url will be loaded every X amount of seconds (default 0)
url="http://yoururl.com/mints.txt OR http://yoururl.com/mints.json" # the actual extension here doesn't matter, as long as the output is either a json list of strings or raw text of 1 mint per line (raw text supports # comments)

Jupiter Example:

[[url_mints]] # only loaded on start/restart
enabled=true
url="http://yoururl.com/mints.txt OR http://yoururl.com/mints.json" # the actual extension here doesn't matter, as long as the output is either a json list of strings or raw text of 1 mint per line (raw text supports # comments)
  • The Jupiter Management Server config [dynamic_mint_filter] field skip_no_volume has been replaced with min_daily_volume and max_daily_volume - Volume is measured in USDC by Jupiter. To include any token even if there's no volume, set min_daily_volume=-1 (The same changes apply to the bot config [jupiter_token_fetcher])

  • Slightly optimized PublicKey hashing.

  • Jito HTTP UUIDs are now set differently. More on this below.

  • You can now optionally use two separate Jupiter servers, one for making quotes and one for making swaps. (More below)

  • Restructured NotArb release packaging and added several new tool scripts. (More below)

Repackaging & Tool Scripts NotArb's release packaging has been restructured to support newly added tool scripts:

  • protect-keypair.sh

  • wsol-unwrapper.sh

  • update-jar.sh

We'll be adding more useful tool scripts in the future like one for closing token accounts. Jito HTTP UUIDs Along with the package restructuring, the way Jito HTTP UUIDs are set have also been changed. Before, Jito HTTP UUIDs were set with a VM arg, which didn't make much sense. However, now they're set with program args as shown in the example run script below: This script is available in the latest download of NotArb

#!/bin/bash

# The path to the bot config file (required)
BOT_CONFIG_PATH="./bot-config.toml"

# Move to the correct workdir to prevent path issues
cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# We highly recommend you increase the -Xmx value to better fit your system. Refer to other VM args here:
# https://docs.oracle.com/en/java/javase/22/docs/specs/man/java.html#standard-options-for-java
vm_args=( # no separating commas, each argument on a new line
  "-server"
  "-Xms256m"
  "-Xmx2048m"
  "-XX:+UseSerialGC"
)

# Args specific to running NotArb Jupiter bot
notarb_args=( # no separating commas, each argument on a new line
  "--jupiter-arb-config-path=$BOT_CONFIG_PATH"
  "--jito-uuid-example=abc" # replace "example" with something unique to identify from config file... ex: uuid="jito-uuid-example"
)

# Source the notarb_java.sh script
. "./libs/notarb_java.sh"

Jito UUIDs will no longer be assigned to [[jito]] configs by default. Please assign a UUID by putting either uuid="jito-uuid-example" OR uuid="actual-uuid" inside of your desired [[jito]] configs. If no uuid is set, HTTP requests will not be sent with UUIDs. Jupiter Servers You can now optionally use two separate Jupiter servers, here's an example:

[jupiter_quote]
url="http://127.0.0.1:8080/"
http_timeout_ms=3000
http_pool_max_size=50

[jupiter_swap]
url="http://127.0.0.1:9090/"
http_timeout_ms=3000
http_pool_max_size=50

This feature is for those who'd like to experiment with load balancing requests between two servers. This feature is optional, and you can continue to use the normal [jupiter] config.

v0.1.82 released with some quick (minor) fixes to how grpc is built, and to allow proxy jito senders to send alongside normal instead of either or.

  • Fixed an issue that caused an error "Missing ATA in map" to print.

  • Reworked some quote logic along with the "Missing ATA..." fix, the Jupiter 500 error should be resolved now too.

  • The strategy field jito_min_dynamic_proxy_tip_lamports introduced in the last version has been removed. Proxy wallet transactions will now require 0.01 SOL balance to use. You will fund the wallet with 0.01, process the transaction, and then receive your 0.01 back. This allows us to use proxy wallets for smaller profits.

  • Jito static transactions will no longer send with proxy wallets. Proxy wallets must exclusively use dynamic tipping.

Please keep in mind, your first NotArb transaction on our new program account will open a PDA account which requires 0.001 SOL rent.

  • A new strategy field jito_min_dynamic_proxy_tip_lamports has been added for when using [[jito]] field proxy_wallet=true (More info on this below)

  • Optimized the proxy tip transaction building for [[jito]] field proxy_wallet=true

  • Completely reworked how public keys are decoded/encoded by NotArb, increasing overall bot performance.

  • Made Jito static tip transactions send when [[jito]] field proxy_wallet=true (before only dynamic tips would send proxy wallet transactions)

  • When strategy field cooldown="0ms" is set, cooldown logic will be skipped for that strategy to increase performance.

When using proxy_wallet=true tips must be at least greater than or equal to 890,880 (minimum account rent) + 5000 (solana network fee) lamports. By default, NotArb will not send dynamic tip proxy transactions if the estimated tip is less than 895,880 lamports. However, you can adjust this value by using strategy field jito_min_dynamic_proxy_tip_lamports, which defaults to 895,880. Adjusting this field lower may help transactions get through that could potentially slip up causing the acutal dynamic tip to be greater than what the bot initially sees. Similar to dynamic tip proxy transactions, static tip proxy transactions also require a minimum tip of 895,880 lamports. Although, since this tip is set staticially from the bot by jito_static_tip_lamports or jito_static_tip_percent the minimum tip cannot be adjusted.

Priority fees set using SOL values greater than or equal to 1 SOL are no longer allowed. If you would like to set a priority fee of 1 SOL or more, please set the fee by lamports instead, as this value is not capped. Places this change has been applied to:

  • Strategy fields min_priority_fee_sol and max_priority_fee_sol

  • Wsol unwrapper field priority_fee_sol

  • Grpc transactions will now have unique prints.

Quick update guys, the logic for protect_keypair=true has been reworked to address an issue that caused the file to be loaded wrong. This update will require you to re-enter your keypair in whichever file you want to protect. The bot should throw an error on startup for older versions of the protected keypair file. To be more specific on what changed, we added another layer of encryption and added slightly more advanced machine detection. Keep in mind, protected keypairs are tied to the machine.

This update includes a critical improvement to the Jito queue system, so it’s highly recommended to update for that alone. Apologies for the tag, but this one felt important. The previous version will still function, though not quite as optimally. Take care!

  • Identified and resolved an issue causing Jito queues to process much slower than intended.

  • The Jupiter Management server will now do a sanity check on manually provided mint addresses to ensure they're proper on startup.

  • Added proper debugs for Jupiter Price API lookup fails.

  • Strategy min gains now factor in network fee + priority fee (if any)

  • Added several new Jito features, more on them below.

Jito Changes

The following fields have been added to [[jito]] configs:

http_enabled - enables http sending (default true)

grpc_enabled - enables grpc sending (default false)

UUID's do not apply to grpc sending.

priority_queue - enables priority queuing by estimated opportunity profit (default true)

bind_ip - binds outgoing connections to a system ip address (default none)

proxy_wallet - tips with a "proxy" wallet (default false)

If you use proxy_wallet=true you should keep in mind these wallets are temporary, used exclusively for tipping, and fully managed by the bot—including creation and minimum balance requirements—so you don’t need to handle these aspects yourself. Each arbitrage transaction must generate enough profit to cover around 890,880 lamports for account rent and an additional 5,000 lamports for network fees. As a result, these transactions will only occur for larger-profit trades, but there’s no need to adjust your minimum gains; the bot performs an exclusive check to meet these requirements.

  • Deprecated Strategy field jito_tip_percent and replaced it with jito_dynamic_tip_percent and jito_static_tip_percent, more info on how these work below.

  • Added a new Stratey field jito_unwrap_tip and when set to true your Jito tip will come directly from your WSOL profit rather than your SOL balance. This makes transactions more complex and will technically be worse in comparison to not using it. However, it's good if you want Jito transactions to never tip directly from your SOL balance. This also allows much larger tips even if your balance can't cover it.

  • Once again reworked how swap workers process to increase overall performance. One day I may be happy with how it performs...

  • Reworked the [wsol_unwrapper] code to be more effecient. It'll no longer require your whole WSOL balance to be unwrapped. For example, if you set unwrap_sol to 1 and min_sol to 0.5, as soon as your balance goes below 0.5 the bot will attempt to unwrap exactly 1 Solana.

  • Other under the hood performance improvements and optimizations.

Jito Tip Percents

Although the jito_tip_percent field has been deprecated, it will still register as jito_dynamic_tip_percent to replicate it's previous usage. The new field jito_static_tip_percent will add a static tip to your Jito transaction before sending it to chain based off of the opporunity profit seen by the bot at the time of the quote. Although "static" Jito transactions should technically be faster, there's a greater chance they slip too far to ensure profit. Use static tipping cautiously. When using jito_static_tip_percent, fields jito_static_tip_lamports and jito_static_tip_sol will be ignored. Both jito_static_tip_percent and jito_dynamic_tip_percent will respect jito_max_tip_lamports and jito_max_tip_sol

Jito Unwrap Tip

The new field jito_unwrap_tip will only work when your base mint is WSOL. This new feature is optional, but is useful at times where a large transaction may require a tip that your balance doesn't cover. For example, say you send a transaction that has 100 SOL profit and you have your tip percent set to 50. In order for this transaction to succeed, you need to have a SOL balance of 50 SOL normally, but if using jito_unwrap_tip the tip will come straight from the profit.

  • Use Strong Passwords: Change default root/admin passwords and use strong, unique passwords.

  • Restrict SSH Access: Disable root login and limit access to specific IPs

v0.1.73-alpha

Further optimized process speed for swap workers.

  • Reworked Jito queue logic to enhance process speed & to prioritize higher gain transactions.

  • Added new prints to Jito transaction messages such as the bundle explorer link & estimated gain in lamports.

  • Added an experimental option when setting jito_static_tip_lamports=-1 which will "static" tip 50% of the estimated gain. (This will be added as a feature in the future if it works well)

Fixed an issue from ⁠v0.1.68-alpha patch notes cooldowns causing txs to be skipped. For example, if you had dynamic + static tipping enabled, only dynamic would send in the same strategy. This is now fixed.

Quick update!, Updated the Jupiter Management Server to use the latest version of Jupiter: (v6.0.29)

Updated the default Jupiter version to 6.0.33:

Dynamic Mints Dynamic mint loading pulls from Jupiter's official Token List API and filters tokens with your desired settings. Bot Example:

Added several new base tokens, thanks to @spif. A full list can be found here:

Made several changes to the on-chain program which is now: (Other program accounts will continue to work until everyone is off of them)

Updated the Jupiter Management Server to the latest Jupiter version:

Updated the Jupiter Management Server to latest Jup Version 6.0.31:

Made proxy wallet transactions execute the tip on a separate program:

Updated the Jupiter Management Server to download the latest version of Jupiter, v6.0.30. Read more here:

Fully overhauled and optimized NotArb's on-chain program. We're back on FAM:

You can now enable protect_keypair=true in the [bot_misc] section to add an extra layer of security to your keypair file. Note: This will overwrite your existing keypair_path file, and the new file will only be usable on the current machine. While this feature offers additional protection, it’s not a foolproof solution. It can, however, provide extra time and defense if your machine is ever compromised. Remember to keep your host(s) secure, here are some things you can do:

v0.9.10 (EXPERIMENTAL RELEASE)
v0.1.91-alpha
v0.1.90-alpha
v0.1.89-alpha
v0.1.88-alpha
v0.1.87-alpha
v0.1.85/86-alpha
v0.1.84-alpha
https://github.com/jup-ag/jupiter-swap-api/releases/tag/v6.0.33
https://station.jup.ag/docs/token-list/token-list-api
v0.1.83-alpha
https://gist.github.com/NotArchon/85ae7e05a0aa2aeaabee0a0327f170cd
v0.1.82-alpha
v0.1.81-alpha
https://solscan.io/account/XXXaoN1GUF9895Tf9ojksGiGJa37F5op23QTYPvUH5H
v0.1.80-alpha
https://github.com/jup-ag/jupiter-swap-api/releases/tag/v6.0.32
v0.1.79-alpha
v0.1.78-alpha
https://github.com/jup-ag/jupiter-swap-api/releases/tag/v6.0.31
https://solscan.io/account/DUBzXRUEF4RSvbTga2yNEsjW3HAx95rPMjQLJmKqjTQF
v0.1.77-alpha
v0.1.76-alpha
https://github.com/jup-ag/jupiter-swap-api/releases/tag/v6.0.30
https://solscan.io/account/FAMBuBHJ1U8DUeY3HNGuW9XsCM4bPZKYk9NXSyR2W2zd
v0.1.75-alpha
v0.1.74-alpha
v0.1.72-alpha
v0.1.71-alpha
v0.1.70-alpha
v0.1.69-alpha
v0.9.50 (EXPERIMENTAL RELEASE)
NotArb