SolanaMevBot
  • 🤖SolanaMevBot - Solana Arbitrage Bot
    • 📘Blog
      • The Current Landscape of MEV on Solana
      • How to Frontrun on Solana: A Step-by-Step Guide
    • đŸ’ĩFees
  • Onchain Bot
    • â„šī¸How this bot work
    • đŸ› ī¸Getting started
    • â›“ī¸Onchain program
    • 🔍Address lookup table
    • 📝Bot configurations
  • 🚀Releases
  • â€ŧī¸Trouble shooting
  • 💹Performance tuning
  • Onchain Bot Dashboard
  • Jupiter Bot
    • â„šī¸How this bot work
    • đŸ› ī¸Getting started
    • 📝Bot configurations
      • 📚Config examples
    • 🔡Common workflow
    • 💹Performance tuning
    • 🧩Bot Strategy
    • â€ŧī¸Trouble shooting
    • 🚀Releases
    • ❓FAQ
    • Dashboard
  • Community
    • Discord
Powered by GitBook
On this page
  • Example config.yaml
  • KEYS
  • PRIVATE_KEY
  • HELIUS_API_KEY
  • CIRCULAR_API_KEY
  • YELLOWSTONE
  • YELLOWSTONE_URL
  • YELLOWSTONE_XTOKEN
  • JUPITER
  • DISABLE_LOCAL_JUPITER
  • INCLUDED_DEXES
  • EXCLUDED_DEXES
  • JUPITER_RPC_URL
  • JUPITER_URL
  • JUP_MAX_ACCOUNTS
  • USE_LOCAL_MARKET_CACHE
  • ENABLE_CIRCULAR_MARKET_CACHE
  • LOCAL_JUPITER_PORT
  • MARKET_MODE
  • TOTAL_THREAD_COUNT
  • WEBSERVER_THREAD_COUNT
  • UPDATE_THREAD_COUNT
  • USE_DIRECT_ROUTE_ONLY
  • JUPITER_API_KEY
  • ADDITIONAL_JUPITER_URL_PARAMS
  • SKIP_JUPITER_TOKEN_LIST_CHECK
  • RESTRICT_INTERMEDIATE_TOKENS
  • INTERMEDIUM_MINTS
  • INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE
  • INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE_TRENDING
  • INTERMEDIUM_MINT_COUNT_FROM_JUPITER_TRENDING
  • INTERMEDIUM_MINT_COUNT_FROM_GECKO
  • INTERMEDIUM_MINT_FROM_FILE
  • INTERMEDIUM_MINT_FROM_FILES
  • INTERMEDIUM_MINT_LIST
  • INTERMEDIUM_MINT_EXCLUDE_FROM_FILE
  • INTERMEDIUM_MINT_FROM_ADDRESSES
  • INTERMEDIUM_MINT_FROM_CIRCULAR
  • INTERMEDIUM_MINT_FILTER
  • BOT
  • AUTO_RESTART
  • ENABLE_SIMULATION
  • ENABLE_JITO_RPC
  • ENCRYPT_PRIVATE_KEY
  • FIXED_COMPUTE_UNIT_LIMIT
  • COMPUTE_UNIT_LIMIT_MULTIPLIER
  • MAX_COMPUTE_TIME
  • MAX_WRAP_SOL_COMPUTE_UNIT_PRICE
  • MEMO
  • PULL_BLOCKHASH_WITH_YELLOWSTONE
  • MIN_SOL_BALANCE
  • RPC_URL
  • SKIP_SAME_OPPORTUNITY
  • PAY_FEE_WITH_PROFIT
  • JUPITER_WORKER_COUNT
  • DOWNLOAD_RPC_URL
  • DOWNLOAD_RPC_RATE_LIMIT_PER_SECOND
  • ENABLE_FIXED_SIZE_OPTIMIZATION
  • JITO
  • ENABLE_JITO
  • ENABLE_JITO_GRPC
  • BLOCK_ENGINE_URL
  • JITO_KEYPAIR
  • BLOCK_ENGINES
  • TIP_STRATEGIES
  • DYNAMIC_TIP_BP
  • STATIC_TIP_BP
  • STATIC_TIP_BP_LIST
  • FIXED_TIP
  • FIXED_TIP_LIST
  • FIXED_TIP_RANGE
  • FIXED_TIP_RANGE_COUNT
  • FIXED_TIP_RANGE_STRATEGY
  • MAX_TIP
  • JITO_UUID
  • SHOW_JITO_LOGS
  • USE_SEPARATE_TIP_ACCOUNT
  • USE_DIFFERENT_TX_FOR_BLOCK_ENGINES
  • USE_DIFFERENT_TIP_ACCOUNT_FOR_BLOCK_ENGINES
  • ENABLE_MULTIPLE_IP_ADDRESSES_FOR_JITO
  • START_IP
  • END_IP
  • IP_LIST
  • SPAM
  • ENABLE_SPAM
  • COMPUTE_UNIT_PRICE
  • MAX_RETRIES
  • PRIORITY_FEE_STRATEGY
  • PRIORITY_FEE_UPDATE_INTERVAL
  • SEND_RPC_URLS
  • PRIORITY_FEE_PERCENTILE
  • SPAM_FEE_BPS
  • MAX_COMPUTE_UNIT_PRICE
  • MIN_COMPUTE_UNIT_PRICE
  • SKIP_PREFLIGHT
  • SPAM_RESTRICT_LEVEL
  • USE_DIFFERENT_TX_FOR_SENDERS
  • BLOXROUTE
  • ENABLE_BLOXROUTE
  • BLOXROUTE_REGION
  • BLOXROUTE_REGION_LIST
  • BLOXROUTE_KEY
  • BLOXROUTE_FEE
  • BLOXROUTE_DYNAMIC_FEE
  • BLOXROUTE_DYNAMIC_FEE_BP
  • BLOXROUTE_MAX_DYNAMIC_FEE
  • BLOXROUTE_JITO_ONLY
  • NEXTBLOCK
  • ENABLE_NEXTBLOCK
  • NEXTBLOCK_REGION
  • NEXTBLOCK_REGION_LIST
  • NEXTBLOCK_KEY
  • NEXTBLOCK_FEE
  • NEXTBLOCK_DYNAMIC_FEE
  • NEXTBLOCK_DYNAMIC_FEE_BP
  • NEXTBLOCK_MAX_DYNAMIC_FEE
  • NEXTBLOCK_SHOW_SENDING_ERROR
  • NEXTBLOCK_JITO_ONLY
  • TEMPORAL
  • ENABLE_TEMPORAL
  • TEMPORAL_REGION
  • TEMPORAL_REGION_LIST
  • TEMPORAL_KEY
  • TEMPORAL_FEE
  • TEMPORAL_DYNAMIC_FEE
  • TEMPORAL_DYNAMIC_FEE_BP
  • TEMPORAL_MAX_DYNAMIC_FEE
  • TEMPORAL_SHOW_SENDING_ERROR
  • FAST
  • ENABLE_FAST
  • FAST_FEE
  • FAST_DYNAMIC_FEE
  • FAST_DYNAMIC_FEE_BP
  • FAST_MAX_DYNAMIC_FEE
  • FAST_SHOW_SENDING_ERROR
  • FAST_JITO_ONLY
  • LOGGING
  • DEBUG
  • ENABLE_LANDING_LOG
  • ENABLE_SENDING_LOG
  • HIDE_ERROR
  • FLASHLOAN
  • ENABLE_FLASHLOAN
  • FLASHLOAN_PROVIDER
  • WRAP_SOL_AMOUNT
  • BLIND_QUOTE_STRATEGY
  • ENABLE_BLIND_QUOTE_STRATEGY
  • BASE_MINTS
  • Config override
  • BACKRUN_STRATEGY
  • ENABLE_BACKRUN_STRATEGY
  • MEMO
  • SLOT_MEMO
  • DEXES_TO_MONITOR
  • MIN_PRICE_IMPACT_PCT
  • BASE_MINTS
  1. Jupiter Bot

Bot configurations

PreviousGetting startedNextConfig examples

Last updated 1 month ago

The bot uses config.yaml file to load all the configurations.

Different configuration can greatly impact your profitability using the bot. Tweak it based on your own setup. Join our discord to learn more.

You can also refer the config examples as a starting point to tweak for your own config.

If a config does not exist in your config.yaml file, just refer to config.yaml.example and add the ones you are missing.

Example config.yaml


# !!!!!!!!!!!!!!IMPORTANT!!!!!!!!!!!!!
# If you just get started use the demo configs on the solanamevbot.com website,
# DO NOT USE THIS FILE as your starting point. This file is for reference when adding new configs ONLY.


# SolanaMevBot Configuration. For detailed explanation of each configuration option,
# see https://docs.solanamevbot.com/home/fundamentals/bot-configurations

# (warning: sensitive information). Make sure you don't share it with anyone.
KEYS:
  PRIVATE_KEY: '' # You can use a JSON file or just a private key string
  HELIUS_API_KEY: '' # API key for Helius. Only needed if you use priorityFeePercentile
  CIRCULAR_API_KEY: '' # API key for Circular. Only needed if you use Circular API

# Yellowstone Configuration. This is optional. Yellowstone will be used for Jupiter if set.
YELLOWSTONE:
  YELLOWSTONE_URL: '' # Yellowstone API URL
  YELLOWSTONE_XTOKEN: '' # Yellowstone authentication token

# Jupiter Configuration
JUPITER:
  DISABLE_LOCAL_JUPITER: false # Disable local Jupiter instance
  JUPITER_RPC_URL: '' # Jupiter RPC URL. If not set the bot will use the RPC_URL
  JUPITER_URL: 'http://127.0.0.1:18080' # URL for Jupiter API
  JUP_MAX_ACCOUNTS: 24 # Maximum number of accounts in a single swap
  LOCAL_JUPITER_PORT: 18080 # Port for local Jupiter instance
  MARKET_MODE: 'remote' # 'remote' or 'europa' or 'file'. 'europa' is very RPC heavy and can cause issues with RPC nodes.
  USE_DIRECT_ROUTE_ONLY: true # Use only direct swap routes
  USE_LOCAL_MARKET_CACHE: false # Use local cache for market data
  WEBSERVER_THREAD_COUNT: 2
  UPDATE_THREAD_COUNT: 4
  ENABLE_CIRCULAR_MARKET_CACHE: false # Use Circular API to get market data, only supports up to 50 mints including base mints
  INCLUDED_DEXES:
    - '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'
    - 'MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG'
  EXCLUDED_DEXES: # List of DEX program IDs to exclude
    - '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'
    - 'MoonCVVNZFSYkqNXP6bxHLPL6QQJiMagDL3qcqUQTrG'

  JUPITER_API_KEY: '' # Jupiter API key, only needed if you use a 3rd party Jupiter instance like shyft
  SKIP_JUPITER_TOKEN_LIST_CHECK: false # Skip Jupiter token list check
  ADDITIONAL_JUPITER_URL_PARAMS: '' # Additional URL params to append to the Jupiter API URL

# Intermedium Mints Configuration
INTERMEDIUM_MINTS:
  INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE: 0 # Number of top 24h volume tokens from Birdeye to use as intermediaries
  INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE_TRENDING: 0 # Number of trending tokens from Birdeye to use as intermediaries
  INTERMEDIUM_MINT_COUNT_FROM_GECKO: 0 # Number of new tokens from Gecko to use as intermediaries
  INTERMEDIUM_MINT_COUNT_FROM_JUPITER: 0 #  You should only use this when you use a remote Jupiter instance. Number of new tokens from the Jupiter instance you connect to as intermediaries.
  INTERMEDIUM_MINT_FROM_FILE: '' # Json file containing a list of mints to use as intermediaries
  INTERMEDIUM_MINT_FROM_FILES: [] # List of json files containing a list of mints to use as intermediaries
  INTERMEDIUM_MINT_LIST: # List of mints to use as intermediaries
    - 'mint1'
    - 'mint2'
    - 'mint3'
  INTERMEDIUM_MINT_EXCLUDE_FROM_FILE: '' # Json file containing a list of mints to exclude as intermediaries
  INTERMEDIUM_MINT_FROM_ADDRESSES:
    MAX_MINT_COUNT: 10 # Maximum number of mints to extract from addresses
    ADDRESSES:
      - ADDRESS: 'address1'
        TX_COUNT_PER_ADDRESS: 100 # Number of latest transactions to check on start
        SUCCESSFUL_ONLY: true # Only consider successful transactions
        MAX_MINT_COUNT: 10 # Maximum number of mints to extract from addresses
      - ADDRESS: 'address2'
        TX_COUNT_PER_ADDRESS: 50
        MAX_MINT_COUNT: 10 # Maximum number of mints to extract from addresses
  INTERMEDIUM_MINT_FROM_CIRCULAR:
    MAX_TOKENS_LIST: 5 # Maximum number of tokens to fetch from Circular API
    MAX_TIME_RANGE: 900 # Maximum time range in seconds for the data to be fetched from Circular API
    TOKEN: 'So11111111111111111111111111111111111111112' # Base Token to fetch from Circular API
    EXCLUDE_TOKENS: # List of tokens to exclude from the fetched data, can be empty
      - 'So11111111111111111111111111111111111111112'
    PROVIDER: '' # Optional, Filter by provider list ("JITO", "FAST", "TEMPORAL", "BLOX", "NEXTBLOCK", "NO_PROVIDER")
  INTERMEDIUM_MINT_FILTER:
    MAX_MINT_COUNT: 10 # Maximum number of mints to keep 
    FILTER_METHOD: 'random' # Filter method, only 'random' is supported for now

# Bot Configuration
BOT:
  RPC_URL: 'https://api.mainnet-beta.solana.com' # Primary RPC endpoint. You should use your own private RPC endpoint.
  AUTO_RESTART: 0 # Automatically restart the bot after specified minutes (0 to disable)
  MAX_COMPUTE_TIME: 5000 # Maximum for total compute times in milliseconds
  MEMO: '' # Memo to include in transactions
  MIN_SOL_BALANCE: 0 # Minimum SOL balance to maintain in lamports
  ENABLE_SIMULATION: false # Simulate transactions before sending
  PULL_BLOCKHASH_WITH_YELLOWSTONE: false # Use Yellowstone for blockhash
  FIXED_COMPUTE_UNIT_LIMIT: 0 # Fixed compute unit limit (0 to use dynamic limit)
  COMPUTE_UNIT_LIMIT_MULTIPLIER: 1 # Compute unit limit multiplier, 1 is usually enough to cover 95% of the cases.
  ENABLE_JITO_RPC: false # Use Jito RPC endpoint. Only enable this if you know what you are doing.
  PAY_FEE_WITH_PROFIT: false # Pay fee with profit. Only works for SOL.
  JUPITER_WORKER_COUNT: 1 # Number of Jupiter worker threads
  MAX_WRAP_SOL_COMPUTE_UNIT_PRICE: 20_000_000 # Maximum compute unit price in micro lamports when wrapping/unwrapping SOL
  ENABLE_FIXED_SIZE_OPTIMIZATION: false # Enable fixed size optimization

  # Download Configuration
  DOWNLOAD_RPC_URL: '' # RPC URL used for downloading, when not set the bot will use RPC_URL
  DOWNLOAD_RPC_RATE_LIMIT_PER_SECOND: 0 # Rate limit for RPC in requests per second, 0 is no limit

# Spam Configuration
SPAM:
  ENABLE_SPAM: false # Using RPCs to send arbitrage transactions
  SPAM_RESTRICT_LEVEL: 0 # Spam restriction level (0-5). 0 is no restriction.
  SKIP_PREFLIGHT: true # Skip preflight transaction checks
  USE_DIFFERENT_TX_FOR_SENDERS: false # Use different transactions for each RPC sender
  MAX_RETRIES: 0 # Maximum number of retries for failed operations
  PRIORITY_FEE_STRATEGY: 'fixed' # Supported strategies: profit-based, fixed, helius. You can only use one of them.
  SEND_RPC_URLS: [] # RPC endpoints for transaction submission. You can use multiple RPC endpoints to increase the chance of success.

  # Only matter if you set PRIORITY_FEE_STRATEGY to helius
  PRIORITY_FEE_PERCENTILE: 50 # Priority fee percentile for priority fee transactions. Need Helius API key.
  PRIORITY_FEE_UPDATE_INTERVAL: 60 # Interval for updating priority fees in seconds

  # Only matter if you set PRIORITY_FEE_STRATEGY to profit-based
  SPAM_FEE_BPS: 500 # This allows you to set your gas fee to be a fixed percentage of the projected gain.

  # Only matter if you set PRIORITY_FEE_STRATEGY to fixed
  COMPUTE_UNIT_PRICE: 0 # Price per compute unit in micro-lamports

  MAX_COMPUTE_UNIT_PRICE: 100_000 # Maximum compute unit price in micro lamports
  MIN_COMPUTE_UNIT_PRICE: 0 # Minimum compute unit price in micro lamports

  # Bloxroute Configuration, Rate limit is 10/s if you use the default key. No limit for your own key.
  BLOXROUTE: 
    ENABLE_BLOXROUTE: false # Enable Bloxroute as a sending RPC. Note you need to also ENABLE_SPAM for this to work.
    BLOXROUTE_REGION: 'ny' # Bloxroute region. ny/uk/la/tokyo/germany/amsterdam
    BLOXROUTE_REGION_LIST: # If you want to send to multiple region for the same tx, you can use this.
      - ny
      - uk
    BLOXROUTE_FEE: 500_000 # Bloxroute fee in lamports, minimum is 500_000
    BLOXROUTE_KEY: '' # Bloxroute API key, when not set the bot will use the default key with a 10/s rate limit
    BLOXROUTE_DYNAMIC_FEE: false # Use dynamic fee for Bloxroute, will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito.
    BLOXROUTE_DYNAMIC_FEE_BP: 0 # Dynamic fee in basis points, only works when BLOXROUTE_DYNAMIC_FEE is true. BP of the projected profit, similar to STATIC_TIP_BP in Jito.
    BLOXROUTE_MAX_DYNAMIC_FEE: 0 # Maximum dynamic fee in lamports, 0 to disable  
    BLOXROUTE_JITO_ONLY: false # Use Jito only for Bloxroute

  # Temporal Configuration
  TEMPORAL:
    ENABLE_TEMPORAL: false # Enable Temporal as a sending RPC. Note you need to also ENABLE_SPAM for this to work.
    TEMPORAL_REGION: ams1 # Temporal region. ams1/ewr1/pit1/fra2
    TEMPORAL_REGION_LIST: # If you want to send to multiple region for the same tx, you can use this.
      - ams1
      - ewr1
    TEMPORAL_FEE: 1_000_000 # Temporal fee in lamports, minimum is 1_000_000
    TEMPORAL_KEY: '' # Temporal API key, required to use Temporal
    TEMPORAL_DYNAMIC_FEE: false # Use dynamic fee for Temporal, will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito.
    TEMPORAL_DYNAMIC_FEE_BP: 0 # Dynamic fee in basis points, only works when TEMPORAL_DYNAMIC_FEE is true. BP of the projected profit, similar to STATIC_TIP_BP in Jito.
    TEMPORAL_SHOW_SENDING_ERROR: true # Show error messages in logs
    TEMPORAL_MAX_DYNAMIC_FEE: 0 # Maximum dynamic fee in lamports, 0 to disable

  # Nextblock Configuration
  NEXTBLOCK:
    ENABLE_NEXTBLOCK: false # Enable Nextblock as a sending RPC. Note you need to also ENABLE_SPAM for this to work.
    NEXTBLOCK_REGION: ny # Nextblock region. ny/fra
    NEXTBLOCK_REGION_LIST: # If you want to send to multiple region for the same tx, you can use this.
      - ny
      - fra
    NEXTBLOCK_FEE: 1_000_000 # Nextblock fee in lamports, minimum is 1_000_000
    NEXTBLOCK_KEY: '' # Nextblock API key, required to use Nextblock
    NEXTBLOCK_DYNAMIC_FEE: false # Use dynamic fee for Nextblock, will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito.
    NEXTBLOCK_DYNAMIC_FEE_BP: 0 # Dynamic fee in basis points, only works when NEXTBLOCK_DYNAMIC_FEE is true. BP of the projected profit, similar to STATIC_TIP_BP in Jito.
    NEXTBLOCK_SHOW_SENDING_ERROR: true # Show error messages in logs
    NEXTBLOCK_MAX_DYNAMIC_FEE: 0 # Maximum dynamic fee in lamports, 0 to disable
    NEXTBLOCK_JITO_ONLY: false # Use Jito only for Nextblock
    
  # Fast Configuration
  FAST:
    ENABLE_FAST: false # Enable Fast as a sending RPC. Note you need to also ENABLE_SPAM for this to work.
    FAST_FEE: 1_000_000 # Fast fee in lamports, minimum is 1_000_000
    FAST_DYNAMIC_FEE: false # Use dynamic fee for Fast, will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito.
    FAST_DYNAMIC_FEE_BP: 0 # Dynamic fee in basis points, only works when FAST_DYNAMIC_FEE is true. BP of the projected profit, similar to STATIC_TIP_BP in Jito.
    FAST_SHOW_SENDING_ERROR: true # Show error messages in logs
    FAST_MAX_DYNAMIC_FEE: 0 # Maximum dynamic fee in lamports, 0 to disable
    FAST_JITO_ONLY: false # Use Jito only for Fast

# Jito Configuration
JITO:
  ENABLE_JITO: false # Use jito to send arbitrage transactions
  SHOW_JITO_LOGS: false # Show Jito landing logs
  JITO_UUID: '' # Jito user identifier.
  TIP_STRATEGIES: # Supported strategies: dynamic, static, fixed, fixed-list, static-list, fixed-range. You can use a combination of them.
    - dynamic
    - static
    - fixed
    - 'static-list'
    - 'fixed-list'
    - 'fixed-range'
  DYNAMIC_TIP_BP: 5000 # Jito tip in basis points. The value is dynamically calculated onchain.
  STATIC_TIP_BP: 0 # Jito tip in basis points. The value is calculated based on the projected profit.
  FIXED_TIP: 0 # Fixed tip in lamports.
  FIXED_TIP_LIST:
    - 10_000_000
    - 100_000_000
    - 1_000_000_000
  STATIC_TIP_BP_LIST:
    - 5000
    - 7000
    - 9000
  FIXED_TIP_RANGE:
    FROM: 100_000
    TO: 10_000_000_000
  FIXED_TIP_RANGE_COUNT: 5
  FIXED_TIP_RANGE_STRATEGY: 'random' # Strategy for distributing tip sizes. Valid values: random, exponential, linear
  MAX_TIP: 1_000_000_000 # Maximum tip in lamports. If 0 the bot will use 80% of the wallet balance as the max tip.
  USE_SEPARATE_TIP_ACCOUNT: false # Use a separate account for tips
  USE_DIFFERENT_TX_FOR_BLOCK_ENGINES: true # Use different transactions for each block engine
  USE_DIFFERENT_TIP_ACCOUNT_FOR_BLOCK_ENGINES: false # Use different tip accounts for each block engine
  BLOCK_ENGINES: # List of block engines to use
    - 'ny'
    - 'amsterdam'
    - 'frankfurt'
    - 'tokyo'
    - 'slc'

  ENABLE_MULTIPLE_IP_ADDRESSES_FOR_JITO: false # Use multiple addresses to send jito transactions. You need to have your ip setup correctly on your machine first to utilize this.
  START_IP: '1.1.1.1' # Optional. When set bot will use the IPV4 ip start from this ip
  END_IP: '1.1.1.6'  # Optional. When set bot will use the IPV4 ip end with this ip
  IP_LIST: # Optional. If you want to set multiple ips manually, you can use this.
    - 1.1.1.1
    - 2.2.2.2

# Flashloan Configuration
FLASHLOAN:
  ENABLE_FLASHLOAN: false # Enable flashloan functionality
  FLASHLOAN_PROVIDER: 'kamino' # Flashloan provider. Currently supported: solend, kamino
  WRAP_SOL_AMOUNT: 0 # Amount of SOL to wrap in lamports

# Logging Configuration
LOGGING:
  DEBUG: false # Enable debug mode for additional logging
  HIDE_ERROR: false # Hide error messages in logs
  ENABLE_LANDING_LOG: false # Enable logging of landing transactions
  ENABLE_SENDING_LOG: true # Enable logging of sending transactions

# Blind Quote Strategy Configuration
# How blind quote strategy works:
# 1. Bot will use the trade size you defined in this config to quote for all the intermedium mints you defined, both to buy and sell.
# 2. If a buy and sell quote has profit and it's higher than the MIN_QUOTE_PROFIT you defined here, it will send out tx try to catch it
BLIND_QUOTE_STRATEGY:
  ENABLE_BLIND_QUOTE_STRATEGY: true # Enable blind quote strategy
  MEMO: '' # Memo override for the blind quote strategy
  SKIP_SAME_OPPORTUNITY: false # Skip duplicate arbitrage opportunities
  BASE_MINTS:
    - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
      TRADE_RANGE:
        FROM: 1_000_000_000  # 1 SOL
        TO: 10_000_000_000   # 10 SOL
      PROCESS_DELAY: 1000 # Delay between processing a new round of routes and checking for new opportunities in milliseconds
      TRADE_RANGE_COUNT: 5   # Number of trade sizes within the range
      TRADE_RANGE_STRATEGY: 'random' # Strategy for distributing trade sizes. Valid values: random, exponential, linear
      MIN_QUOTE_PROFIT: 1_000_000 # Minimum profit in lamports
      MIN_SIMULATED_PROFIT: 100_000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit
      ROUTE_TYPES: # List of route types to use
        - 2hop
        - 3hop
      THREE_HOP_MINTS: # List of mints to use for 3hop route
        - EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v


    # You can also use USDC/USDT as base mints, or config a different strategy for the same mint multiple times.
    - MINT: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v # USDC
      TRADE_SIZES: 
        - 50_000_000
        - 500_000_000 # Trade size in USDC (6 decimals)
      MIN_QUOTE_PROFIT: 5000 # Minimum profit in USDC (6 decimals)
      PROCESS_DELAY: 1000 # Delay between processing a new round of routes and checking for new opportunities in milliseconds
      MIN_SIMULATED_PROFIT: 5000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit

    - MINT: Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB # USDT
      TRADE_SIZES: 
        - 50_000_000
        - 500_000_000 # Trade size in USDT (6 decimals)
      MIN_QUOTE_PROFIT: 5000 # Minimum profit in USDT (6 decimals)
      PROCESS_DELAY: 1000 # Delay between processing a new round of routes and checking for new opportunities in milliseconds
      MIN_SIMULATED_PROFIT: 5000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit

# Backrun Strategy Configuration
# How backrun strategy works:
# 1. Bot will monitor the markets you defined in DEXES_TO_MONITOR, with all the intermedium mints you defined above
# 2. If the pool's price moved more than MIN_PRICE_IMPACT_PCT, bot will try to create a trade to backrun it
# 3. Bot will use the trade size you defined in TRADE_CONFIGS, to randomly generate a size between MIN_TRADE_BP 
#    and MAX_TRADE_BP, based on the trade you are back running
# 4. Bot will quote the other size of the trade with jupiter, create a full arb trade tx
# 5. If the tx has profit and it's higher than MIN_QUOTE_PROFIT, bot will send it out
BACKRUN_STRATEGY:
  ENABLE_BACKRUN_STRATEGY: false # Enable backrun strategy
  MEMO: '' # Memo override for the backrun strategy
  SLOT_MEMO: true # Add the backrun tx's slot to the memo, useful to see how far you landed your backrun tx.
  DEXES_TO_MONITOR: # List of DEXes to monitor. Valid values: Raydium, Whirlpool, RaydiumCLMM, Meteora, MeteoraDLMM
    - Raydium
    - Whirlpool
    - RaydiumCLMM
    - Meteora
    - MeteoraDLMM
    - SolFi
    - LifinityV2
  MIN_PRICE_IMPACT_PCT: 0.1 # Minimum price impact in percentage, for the pool you are monitoring. Bot will only backrun trades that caused the price to move more than this percentage.
  BASE_MINTS: # List of base mints to use for the backrun. Currently only SOL and USDC are supported.
    - MINT: So11111111111111111111111111111111111111112
      MIN_QUOTE_PROFIT: 100_000 # Minimum profit in lamports for the quote
      MIN_SIMULATED_PROFIT: 100_000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit
      MIN_TRADE_SIZE: 500_000_000 # Minimum trade size in lamports, if the generated trade size is less than this bot will skip the trade
      MAX_TRADE_SIZE: 150_000_000_000 # Maximum trade size in lamports, if the generated trade size is more than this bot will cap it at this size
      SENDING_COOLDOWN: 0 # If one opportunity is found and tx is sent out, wait at least this time(ms) before sending another one.
      TRADE_CONFIGS: # List of trade configs to use for the backrun. You can define multiple configs to backrun the same tx
        # Bot will randomly pick a trade size between MIN_TRADE_BP and MAX_TRADE_BP, based on the trade you are backrunning
        # Or you can define a FIXED_SIZE, bot will use this size for the backrun
        # You can define multiple configs, and bot will create different txs to backrun the same trade
        - MIN_TRADE_BP: 2000 # Min trade size in basis points
          MAX_TRADE_BP: 2000 # Max trade size in basis points
        - FIXED_SIZE: 100_000_000 # Fixed trade size in lamports. You should only define MIN/MAX or FIXED_SIZE, not both in the same config item.
      ROUTE_TYPES: # Currently only 2hop is supported
        - 2hop
    - MINT: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v # USDC
      MIN_QUOTE_PROFIT: 100_000 # Minimum profit in lamports for the quote
      MIN_SIMULATED_PROFIT: 100_000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit
      MIN_TRADE_SIZE: 500_000_000 # Minimum trade size in lamports, if the generated trade size is less than this bot will skip the trade
      MAX_TRADE_SIZE: 150_000_000_000 # Maximum trade size in lamports, if the generated trade size is more than this bot will cap it at this size
      TRADE_CONFIGS: # List of trade configs to use for the backrun. You can define multiple configs to backrun the same tx
        # Bot will randomly pick a trade size between MIN_TRADE_BP and MAX_TRADE_BP, based on the trade you are backrunning
        # You can define multiple configs, and bot will create different txs to backrun the same trade
        - MIN_TRADE_BP: 2000 # Min trade size in basis points
          MAX_TRADE_BP: 2000 # Max trade size in basis points
      ROUTE_TYPES: # Currently only 2hop is supported
        - 2hop

KEYS

This section contains configurations like private keys, api keys.

PRIVATE_KEY

Private key for your wallet. All formats are supported, you can export from Phantom/Solflare or just use a json file path. The wallet needs to hold enough SOL/WSOL/USDC for your configuration.

HELIUS_API_KEY

CIRCULAR_API_KEY

YELLOWSTONE

YELLOWSTONE_URL

If present, JupV6 API will use it, otherwise JupV6 will be running in pull mode, which is very heavy on the read RPC.

YELLOWSTONE_XTOKEN

If your yellowstone provider also provides you an x token set it here.

JUPITER

When running the bot with JUPITER_URL=http://0.0.0.0:18080, or JUPITER_URL=http://127.0.0.1:18080 the bot will first pull the latest popular token mints from Birdeye, based on last 24h volume. Then spin up a JupV6 API with FILTER_MARKETS_WITH_MINTS set to the token mints pulled from Birdeye. INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE configures how many tokens to use from Birdeye. The higher you set for INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE, the more oppotunity you may see as there are more potential routes from different token pairs. Though higher number also means longer time to get a quote from JupV6 API, and it will also uses more resources from your machine. If YELLOWSTONE_URL is not set, it is not recommended to set

If YELLOWSTONE_URL is set, it will be used to start JupV6 API with it, otherwise the JupV6 API will run in pull mode, which is heavy for your read RPC and it is not recommended when you have too many intermedium mints(>100).

If JUPITER_URLis set to a different value, none of the params in the following form will apply. This can be used when you have a JupV6 API provider, or running it yourself separately.

DISABLE_LOCAL_JUPITER

Default: false

When set to true, it will not start the Jupiter API locally. This is useful when you want to run multiple bots on the same machine

INCLUDED_DEXES

default: []

You can only set one of INCLUDED_DEXES and EXCLUDED_DEXES not both.

EXCLUDED_DEXES

default: []

You should always exclude Moonshot and Pump.fun unless you know what you are doing.

You can only set one of INCLUDED_DEXES and EXCLUDED_DEXES not both.

JUPITER_RPC_URL

The RPC that is used to read data. When using default JUPITER_URL value, this RPC will also be used to spin up JupV6 API. If this is not set, the value of RPC_URL will be used.

JUPITER_URL

Default: http://0.0.0.0:18080

Endpoint for JupV6 API. When using default value, it will spin up a JupV6 using top popular mints from Birdeye. When set a value other than default, the rest of the parameters in this form will not be applied.

JUP_MAX_ACCOUNTS

Default: 24

the maxAccounts param that is used to call quote from JupV6. Recommended not setting this higher than 32. The higher this number is, the more routes you can find, though as there's a limit on the total accounts, a higher number here will also cause a higher chance to find an invalid route with too many accounts, and it also takes longer to search.

USE_LOCAL_MARKET_CACHE

Default: false

When this is set to true, it will load the market cache from the local file mainnet.json. This is useful when you run jup and it's very slow to start, or even fail with error reading a body from connection. You can update the local file with wget https://cache.jup.ag/markets?v=4 -O mainnet.json

ENABLE_CIRCULAR_MARKET_CACHE

Default: false

LOCAL_JUPITER_PORT

Default: 18080

MARKET_MODE

Default: remote

Supported value: europa,file, remote

The default behavior(remote) here will fetch a snapshot of all the markets given your intermedium mints, and will only update them on a restart. Europa mode will stream new markets for your mint list to Jupiter, but it can be very heavy for some RPC to handle.

TOTAL_THREAD_COUNT

Jup uses thread for 3 things: webserver, update, router. You can config thread count for webserver and update, the rest of the cores will be used for router.

Router thread is handling the workload to find the best route for each quote request. This can be heavy especially when you have USE_DIRECT_ROUTE_ONLY false.

Make sure you leave some cores beside WEBSERVER_THREAD_COUNT and UPDATE_THREAD_COUNT for routing calculation.

Default: the number of CPU cores on your machine

Routing engine thread = TOTAL_THREAD_COUNT - WEBSERVER_THREAD_COUNT - UPDATE_THREAD_COUNT.

Most of the time you shouldn't need to set this and can just let jupiter use all your cores to enhance performance.

WEBSERVER_THREAD_COUNT

Jup uses thread for 3 things: webserver, update, router. You can config thread count for webserver and update, the rest of the cores will be used for router.

Router thread is handling the workload to find the best route for each quote request. This can be heavy especially when you have USE_DIRECT_ROUTE_ONLY false.

Make sure you leave some cores beside WEBSERVER_THREAD_COUNT and UPDATE_THREAD_COUNT for routing calculation.

Default: 2

This is how many thread to handle the http requests. The bot is heavily using this so you should consider setting this to a high number if your jupiter quote per second is high.

UPDATE_THREAD_COUNT

Jup uses thread for 3 things: webserver, update, router. You can config thread count for webserver and update, the rest of the cores will be used for router.

Router thread is handling the workload to find the best route for each quote request. This can be heavy especially when you have USE_DIRECT_ROUTE_ONLY false.

Make sure you leave some cores beside WEBSERVER_THREAD_COUNT and UPDATE_THREAD_COUNT for routing calculation.

Default: 4

This is the number of threads used to handle markets update using the data pulled from yellowstone/rpc. If you are using a lot of mints you should consider setting a higher number for this to speed up your price update.

USE_DIRECT_ROUTE_ONLY

Default: true

When set to true, the bot will only look for 2hop(A -> B -> A) trade. Setting to true will lead to shorter quote time to Jup, with faster landing. Setting to false will lead to more opportunity, but taking more time to quote.

JUPITER_API_KEY

You should only set this when using jupiter from a third party provider, and are using x-api-key in the header(like shyft), you can set it here.

If your provider uses a url params, like api-key=xxxx in the url, please use ADDITIONAL_JUPITER_URL_PARAMS

ADDITIONAL_JUPITER_URL_PARAMS

If your provider uses a url params, like api-key=xxxx in the url, you can set this config to include that in all the jupiter requests.

example:

ADDITIONAL_JUPITER_URL_PARAMS = 'api-key=12345678'

SKIP_JUPITER_TOKEN_LIST_CHECK

Some providers does not expose the /tokens api endpoint for their jupiter service. In such case you can set this config to true to avoid the call. Otherwise the bot will stuck at Fetching Jupiter tokens from

RESTRICT_INTERMEDIATE_TOKENS

Default: false

From Jupiter: Restrict intermediate tokens to a top token set that has stable liquidity. This will help to ease potential high slippage error rate when swapping with minimal impact on pricing.

INTERMEDIUM_MINTS

The Bot tries to find profitable route by getting a quote from BASE_MINT to an INTERMEDIUM_MINT for a given trade size, then get another quote from INTERMEDIUM_MINT to BASE_MINT, and combine them together for a potential profitable route. Basically a route from A -> B -> A.

When USE_DIRECT_ROUTE_ONLY is set to true, the bot will only return route in the form of A -> B -> A like above. For potentially more opportunity, you can set it to false, which can lead to routes like A -> B -> C -> A. The downside of setting this to false is it will slow down the time to get a quote, end up sending out the transaction a bit slower.

You can set as many tokens as possible as the INTERMEDIUM_MINT, though the more you have, the heavier your RPC load is, so you may want to adjust this accordingly.

There are multiple ways for you to define which mints you use as intermedium. The bot will merge all the mints fetched through different ways into one list and use it as intermedium mints.

INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE

Default: 0

This param configs how many top tokens to use as intermedium mint that pulled from Birdeye's 24h volume list. This list has high volume but usually low velocity.

INTERMEDIUM_MINT_COUNT_FROM_BIRDEYE_TRENDING

Default: 0

This param configs how many top tokens to use as intermedium mint that pulled from Birdeye's trending list. Maximum 200. Update every 20min. This list has high velocity new mints, and usually works better with SOL as base mint.

You do not need birdeye api for this.

INTERMEDIUM_MINT_COUNT_FROM_JUPITER_TRENDING

Default: 0

This param configs how many top tokens to use as intermedium mint that pulled from Jupiter's trending list.

INTERMEDIUM_MINT_COUNT_FROM_GECKO

Default: 0

INTERMEDIUM_MINT_FROM_FILE

This provides a way to load intermedium mints for the bots to use. This is useful if you have a set of mints in mind that you want to use, or you write your own script to fetch intermedium tokens for the bot to use.

Example file:

[
  "So11111111111111111111111111111111111111112",
  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "fCuw5ppJ9aZYzjm8EsT2fHwxV1h5JwUfqXM44iX3Pzb"
]

INTERMEDIUM_MINT_FROM_FILES

Same as INTERMEDIUM_MINT_FROM_FILE except this take in a list of files.

Example:

INTERMEDIUM_MINT_FROM_FILES:
  - mint1.json
  - mint2.json
  - mint3.json

INTERMEDIUM_MINT_LIST

Just a list of mints. This is convenient when you just want to manually specify a few mints to run, you can do this without creating another file.

Example:

INTERMEDIUM_MINT_LIST:
  - EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v
  - Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB

INTERMEDIUM_MINT_EXCLUDE_FROM_FILE

This provides a way to exclude certain mints from intermedium mints.

This is useful when you want to exclude certain mints from birdeye/gecko. Especially if you only want to do SOL arbs and don't want to include USDC/USDT in the route, as it can be heavy for your RPC to load all.

The following example is to exclude USDC/USDT from your intermedium mints.

[
  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
]

INTERMEDIUM_MINT_FROM_ADDRESSES

This allows you to copy trade top players and use whatever intermedium mints they use.

For example, if you want to copy ben/bob's most recent 100 tx:

INTERMEDIUM_MINT_FROM_ADDRESSES:
  MAX_MINT_COUNT: 50 # 0 is no maximum, 
  ADDRESSES:
    - ADDRESS: 'benRLpbWCL8P8t51ufYt522419hGF5zif3CqgWGbEUm'
      TX_COUNT_PER_ADDRESS: 100 # Number of latest transactions to check on start
      SUCCESSFUL_ONLY: false # Only consider successful transactions
      MAX_MINT_COUNT: 50 # 0 is no maximum
    - ADDRESS: 'bobCPc5nqVoX7r8gKzCMPLrKjFidjnSCrAdcYGCH2Ye'
      TX_COUNT_PER_ADDRESS: 100
      SUCCESSFUL_ONLY: false
      MAX_MINT_COUNT: 50 # 0 is no maximum

MAX_MINT_COUNT

You can define an overall MAX_MINT_COUNT, and a MAX_MINT_COUNT for every address you are tracking. The bot will rank all the mints by number of times it appears and keep at most MAX_MINT_COUNT mints. If you have INTERMEDIUM_MINT_EXCLUDE_FROM_FILE defined, the mints will be excluded first then cut off the top rank.

INTERMEDIUM_MINT_FROM_CIRCULAR

INTERMEDIUM_MINT_FROM_CIRCULAR:
  MAX_TOKENS_LIST: 5 # Maximum number of tokens to fetch from Circular API
  MAX_TIME_RANGE: 900 # Maximum time range in seconds for the data to be fetched from Circular API
  TOKEN: 'So11111111111111111111111111111111111111112' # Base Token to fetch from Circular API
  EXCLUDE_TOKENS: # List of tokens to exclude from the fetched data, can be empty
    - 'So11111111111111111111111111111111111111112'
  PROVIDER: '' # Optional, Filter by provider list ("JITO", "FAST", "TEMPORAL", "BLOX", "NEXTBLOCK", "NO_PROVIDER")

INTERMEDIUM_MINT_FILTER

This is a useful feature when you run multiple machines and want them to run different mints. You can use all the other ways to fetch, and use this filter to randomly choose a few for all your machines.

  INTERMEDIUM_MINT_FILTER:
    MAX_MINT_COUNT: 10 # Maximum number of mints to keep 
    FILTER_METHOD: 'random' # Filter method, only 'random' is supported for now

BOT

This section contains configurations for the bot itself.

AUTO_RESTART

Default: 60

Unit in minutes. By default, the bot will auto restart every 60min. This will also restart JupV6 if hosted together, to allow fetching the lasted high volume tokens from birdeye. If set to 0, the bot will not auto restart.

ENABLE_SIMULATION

Default: true

Whether to run simulateTransaction before sending the transaction. This can help to reduce the number of failed transactions landed on chain if spam mode is enabled.

ENABLE_JITO_RPC

Default: false

DO NOT SET THIS TO TRUE if you don't know what is a Jito RPC. You have to use a Jito RPC when you enable this. When this is enabled, the bot will use simulateBundle to run simulation, which can give you the actual profit with the simulation. This value is more accurate than then one calculated from Jupiter quote. This is especially useful when you set spamFeeBps in your base-mint.json

Note: Most providers don't provide Jito RPC. Right now the only options to get one is to either host a RPC node yourself, or rent a dedicated RPC node from a provider like Helius/Triton.

ENCRYPT_PRIVATE_KEY

Default: true

By default the bot will encrypt your private key on first run, and ask you to remove your private key for better security practice. You can turn off this feature but it's highly not recommended.

FIXED_COMPUTE_UNIT_LIMIT

Default: 0

COMPUTE_UNIT_LIMIT_MULTIPLIER

Default: 1

Bot will use an estimated value for compute unit limit based on the route. The default value can make sure 95%+ of the tx have enough compute unit. But this can be too big/too small based on different JUP_MAX_ACCOUNT, you can adjust this value to higher/lower as needed.

MAX_COMPUTE_TIME

Default: 400

The maximum compute time to send tx for an opportunity. If you are trying to catch an opportunity right after it appears, you usually don't want to send anything when it takes too long to calculate in the first place. If the time took to compute is greater than MAX_COMPUTE_TIME, the bot won't send any tx for it.

MAX_WRAP_SOL_COMPUTE_UNIT_PRICE

Default: 20_000_000

The max compute unit price you set to wrap/unwrap SOL. This can be useful when the network is super congested.

MEMO

Text that will be added as the last instruction in the transaction. You can use this to distinguish which server you are running the bot from by setting a different value for each server.

When not set a MEMO will NOT be added to your tx.

PULL_BLOCKHASH_WITH_YELLOWSTONE

Default: false

MIN_SOL_BALANCE

Default: 0

Units in lamports. Does nothing by default. When set to a none 0 value, the bot will periodically check the wallet's SOL balance, and when it drops below the value, it will unwrap all the WSOL and wrap only the amount needed back, to rebalance the SOL account to avoid running out of SOL. e.g. set this to 1000000000 will auto balance your wsol/sol accounts when your sol drops below 1.

RPC_URL

The RPC that is used to read data. When using default JUPITER_URL value, this RPC will also be used to spin up JupV6 API.

SKIP_SAME_OPPORTUNITY

Default: false

When enabled and you are using fixed trade size(either using tradeSize or tradeRange with linear strategy), the bot will check if it's the same as last time and not generate a new opportunity for it if it's the same.

PAY_FEE_WITH_PROFIT

Default: false

This will only affect SOL as base mint. When enabled, the bot will unwrap your profit before sending the jito tip/bot fee, which can be very useful if you don't leave much SOL balance in your wallet, or if you are targeting larget opportunities and afraid to not have enough SOL to pay for a big hit.

JUPITER_WORKER_COUNT

Default: 1

Config how many worker(threads) to use when fetching quotes from Jupiter.

DOWNLOAD_RPC_URL

Default: ''

DOWNLOAD_RPC_RATE_LIMIT_PER_SECOND

Default: 0

When set to a none 0 value, it will apply a rate limit when doing RPC calls. This is helpful when using the free plan for some RPC.

ENABLE_FIXED_SIZE_OPTIMIZATION

Default: false

When you use blind quote mode, the bot will quote the first half of the transaction from SOL->X, then quote the second half X->SOL. The second quote need to wait for the first one's result before it can start. For fixed size, you can enable this optimization, which will use the quote result from the previous round's quote as an estimation, so the SOL->X and X->SOL quote can be sent out simultaneously. This will result in a shorter Jupiter quote time. But occasionally the two quote will find the same pool, which makes the oppotunity invalid, this is especially true when you are trading a new mint where it only has limited pools.

JITO

Following is the Jito related configs you can set in your config.yaml file

ENABLE_JITO

Default: true

Whether to use Jito bundle to send transaction. The good part about Jito is, it will never land if the transaction fails. So everything lands is profit.

ENABLE_JITO_GRPC

Default: false

Whether to use jito GRPC to send bundles. This is NOT recommended unless you have a key with high rate limit.

NOTE: BLOCK_ENGINES does not apply to jito GRPC. You need to set BLOCK_ENGINE_URL instead, and you can only send to one region with GRPC.

BLOCK_ENGINE_URL

Only apply to Jito GRPC.

The block engine url you want to use with your jito GRPC. e.g. amsterdam.mainnet.block-engine.jito.wtf

JITO_KEYPAIR

Only apply to Jito GRPC.

The key json file you want to use with your jito GRPC.

e.g. jito.json

BLOCK_ENGINES

Default: ny,amsterdam,frankfurt,tokyo,slc

You should not change this value unless you really know what you are doing. Config which block engines to send to for jito transactions.

TIP_STRATEGIES

Default value: ['dynamic']

Supported values: dynamic, static, static-list, fixed, fixed-list, fixed-range

Define which strategy to use when paying for jito's tip. DO NOT use static and fixed together before version 1.3.16.

static-list: Similar to static, but you send multiple tx with different static bp for the same opportunity. You need to set STATIC_TIP_BP_LIST for this to work.

fixed-range: Similar to fixed-list, but you instead of you provide the tip amount, bot will automatically generate it for you. You need to define FIXED_TIP_RANGE, FIXED_TIP_RANGE_COUNT, FIXED_TIP_RANGE_STRATEGY for this to work.

DYNAMIC_TIP_BP

Default: 0

Jito tip as part of your profit. 5000 means 50% of your profit will be used as Jito tip. The higher this number, the better chance you may land your transaction, but in return, less profit earned.

STATIC_TIP_BP

Default: 0

Jito tip as part of your profit. 5000 means 50% of your projected profit will be used as Jito tip. The higher this number, the better chance you may land your transaction, but in return, less profit earned.

The tx landed with this may not have the same percentage as you defined, as the tip value is set before you send the tx, but the actual profit may vary when it actually landed.

STATIC_TIP_BP_LIST

Sending multiple tx with different bp.

Example

STATIC_TIP_BP_LIST:
  - 5000
  - 7000
  - 9000

FIXED_TIP

Default: 0

Use a static jito tip when sending to Jito. Unit is SOL lamports. The bot will always use the same tip for all tx it sends, and still make sure the tx landed are all profitable.

When you set both DYNAMIC_TIP_BP and FIXED_TIP, bot will send both percentage based and fixed tip transactions.

Note: If you are using this without USE_SEPARATE_TIP_ACCOUNT set to true, the bot will use sendTransaction endpoint to sent it, which is using a different rate limit then sendBundle which is used with DYNAMIC_TIP_BP.

FIXED_TIP_LIST

Default: []

Example:

FIXED_TIP_LIST:
  - 10_000_000
  - 100_000_000
  - 1_000_000_000

Use a static jito tip when sending to Jito. Unit is SOL lamports. The bot will always use the same tip for all tx it sends, and still make sure the tx landed are all profitable.

When you set both DYNAMIC_TIP_BP and FIXED_TIP_LIST, bot will send both percentage based and fixed tip transactions.

Note: If you are using this without USE_SEPARATE_TIP_ACCOUNT set to true, the bot will use sendTransaction endpoint to sent it, which is using a different rate limit then sendBundle which is used with DYNAMIC_TIP_BP.

FIXED_TIP_RANGE

Define a range for your tip. Bot will generate a list of different tips based on the strategy you choose.

Example:

FIXED_TIP_RANGE:
  FROM: 100_000
  TO: 10_000_000_000
FIXED_TIP_RANGE_COUNT: 5
FIXED_TIP_RANGE_STRATEGY: linear

FIXED_TIP_RANGE_COUNT

How many different tip you want to generate for your tip range.

FIXED_TIP_RANGE_STRATEGY

Valid values: random, exponential, linear

linear will generate trade sizes evenly within the range.

random will generate a trade size randomly each time.

exponential will generate trade size on exponential values. For example for range 10 - 1000, with count 5, it will generate trade size like this: [10, 77, 315, 668, 1000]

MAX_TIP

Default: 0

Set the max tip the bot pays when using dynamic or static jito tip trategy.

Unit is SOL lamports. The bot also has a max tip amount of 80% of your remaining SOL balance, to avoid missing big opportunities when not having enough SOL left. 0 means no no max tip.

JITO_UUID

By default, jito has a 5/s/ip rate limit. You can ask for a rate limit raise from jito, and they will give you an uuid that you can set with the bot.

NOTE: Currently the key has a bug and the rate limit for the key is universal not per ip.

SHOW_JITO_LOGS

Default: false

When this is enabled, response for sending jito bundles will be added to the output log. This is helpful if you are trying to figure out how often you are hitting jito's rate limit, or testing your UUID to see if it works.

USE_SEPARATE_TIP_ACCOUNT

Default: false

USE_DIFFERENT_TX_FOR_BLOCK_ENGINES

Default: false

This will send different TX for different block engines, in theory increase your chance to land, and can some time land multiple tx for the same opportunity.

USE_DIFFERENT_TIP_ACCOUNT_FOR_BLOCK_ENGINES

Default: false

This will use different tip account for different block engines, in theory increase your chance to land, and can some time land multiple tx for the same opportunity.

ENABLE_MULTIPLE_IP_ADDRESSES_FOR_JITO

Default: false

This is the build in support for multiple ips on your machine. When this is enabled, bot will scan all your ip and round robin it when sending through jito. You can also define an ip range with START_IP and END_IP. Or IP_LIST to manually define the list of ips to use.

START_IP

Only applied when you have ENABLE_MULTIPLE_IP_ADDRESSES_FOR_JITO set to true.

The start ip for bot to use, in IPV4 format.

E.G.

START_IP: '1.1.1.1'

END_IP

Only applied when you have ENABLE_MULTIPLE_IP_ADDRESSES_FOR_JITO set to true.

The end ip for bot to use, in IPV4 format.

E.G.

END_IP: '1.1.1.1'

IP_LIST

Define the exact ips you want to use for ENABLE_MULTIPLE_IP_ADDRESSES_FOR_JITO .

Example:

IP_LIST: 
  - 1.1.1.1
  - 2.2.2.2

SPAM

Spam strategy means you will send many transactions and hope some of them get landed and landed successful. This is a more advanced strategy as you may lose money on gas fee if you didn't config it carefully.

You can enable spam by setting ENABLE_SPAM=true in your config.yaml file. The bot will then use all the rpcs you defined for SEND_RPC_URLS to send potential profitable transactions.

Jito and spam can be enabled together, the bot will just send 2 different transactions, one through jito and one through rpc.

ENABLE_SPAM

Default: false

Whether to send a normal transaction for every potential arbitrage oppotunity. Note most of the transactions will not even land on chain, for the ones that does, 90% of them will fail. Set ENABLE_SIMULATION=true can help reduce the number of failed transactions.

COMPUTE_UNIT_PRICE

Default: 0

MAX_RETRIES

Default: 0

PRIORITY_FEE_STRATEGY

Default: fixed

Supported strategies: profit-based, fixed, helius. You can only use one of them.

fixed: This will use the value of COMPUTE_UNIT_PRICE setting to set the compute unit price value.

PRIORITY_FEE_UPDATE_INTERVAL

Default: 600

SEND_RPC_URLS

The RPCs used to send transactions. This can be the same as RPC_URL You can also set multiple RPCs here, split by comma. Setting multiple ones can increase the rate of tx landing and success. Example:

SEND_RPC_URLS:
  - https://api.mainnet-beta.solana.com
  - https://api2.mainnet-beta.solana.com

PRIORITY_FEE_PERCENTILE

When this is set, it will override the COMPUTE_UNIT_PRICE value in config.yaml file.

"min": 0,
"low": 10000,
"medium": 60082,
"high": 1230000,
"veryHigh": 5000000

This should be set together with MAX_COMPUTE_UNIT_PRICE. The max COMPUTE_UNIT_PRICE you are willing to set. This is helpful to prevent setting a huge priority fee as market moves.

Example usage of the config:

SPAM:
  ...
  PRIORITY_FEE_PERCENTILE: 50 # Priority fee percentile for priority fee transactions. Need Helius API key.
  MAX_COMPUTE_UNIT_PRICE: 100_000 # Maximum priority fee in lamports

SPAM_FEE_BPS

This allows you to set your gas fee to be a fixed percentage of the projected gain. Note you can only set one of PRIORITY_FEE_PERCENTILE and SPAM_FEE_BPS, not both.

Example usage of the config:

SPAM:
  MAX_COMPUTE_UNIT_PRICE: 100_000 # Maximum priority fee in lamports
  SPAM_FEE_BPS: 500 # This allows you to set your gas fee to be a fixed percentage of the projected gain.

MAX_COMPUTE_UNIT_PRICE

Default: 0

For helius and profit-based PRIORITY_FEE_STRATEGY, this field is required. This is to prevent you from paying some absurd amount of gas fee.

MIN_COMPUTE_UNIT_PRICE

Default: 0

For helius and profit-based PRIORITY_FEE_STRATEGY, you can set a min compute unit price.

SKIP_PREFLIGHT

Default: true

This is a similar config to ENABLE_SIMULATION. The difference is ENABLE_SIMULATION will run the simulation with your RPC_URL before sending it, when you have SKIP_PREFLIGHT=false, the RPC received your transaction will run the simulation before it forward to the validator. This will also make landing slower as it's an additional call, but also it can reduce the failed transactions you land with ENABLE_SPAM. You should only have at most one of SKIP_PREFLIGHT=false and ENABLE_SIMULATION=true. Setting both is not worth it.

SPAM_RESTRICT_LEVEL

Default: 0

Valid values are 0,1,2,3,4,5.

This config will try to limit how long a tx land compares to when you send it when using spam. 0 is no restriction, the same behavior as before. 5 is maximum restriction and will only allow the tx to land within ~1-2 slots. Note the exact restriction time for each level can be affected by your RPC's latency and performance. You may not land anything when you set this value to 4-5 if your RPC is not fast enough.

This config allows you to use a very high fee for spam strategy and also not losing too much money on failed ones.

USE_DIFFERENT_TX_FOR_SENDERS

Default: false

BLOXROUTE

ENABLE_BLOXROUTE

Default: false

Note when a tx landed successfully with BloXroute, it charges an additional 0.0005 SOL as fee to use BloXroute's api and send through its staked connection. The bot already takes this into consideration and will fail the tx if your profit is not enough to pay for this fee + the bot fee. But do take this into consideration when you enable it.

You need to have your own key to use BloXroute to send.

BLOXROUTE_REGION

Default: ny

Only relevant when you have ENABLE_BLOXROUTE=true. Valid values are ny/uk/la/tokyo/germany/amsterdam. Should only set it to be the closest one to your server.

BLOXROUTE_REGION_LIST

If you want to send to multiple region for the same tx, you can use this.

example:

BLOXROUTE_REGION_LIST:
  - ny
  - uk

BLOXROUTE_KEY

Default: ''

This is required to use Bloxroute.

BLOXROUTE_FEE

Default: 500_000

The bloxroute fee you pay, in theory the high this is, the faster you tx can be delivered. Minimum is 500_000.

BLOXROUTE_DYNAMIC_FEE

Default: false

Use dynamic fee for Bloxroute instead the fixed value from BLOXROUTE_FEE. The fee will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito. You can set the base points used with BLOXROUTE_DYNAMIC_FEE_BP

If the calculated fee is smaller than BLOXROUTE_FEE, BLOXROUTE_FEE will be used as the fee.

BLOXROUTE_DYNAMIC_FEE_BP

Default: 0

Calculate BloXRoute fee based on your projected profit. 500 means 5% of your projected profit will be used as the fee paid to BloXRoute.

The tx landed with this may not have the same percentage as you defined, as the tip value is set before you send the tx, but the actual profit may vary when it actually landed.

BLOXROUTE_MAX_DYNAMIC_FEE

Default: 0

Maximum dynamic fee in lamports, 0 to disable

BLOXROUTE_JITO_ONLY

Default: false

When enabled, bloxroute will only send through jito. aka you won't see failed tx with bloxroute.

NEXTBLOCK

There's no default key for NextBlock, you need to set your own key to use this.

ENABLE_NEXTBLOCK

Default: false

NEXTBLOCK_REGION

Default: ny

Supported region: ny or fra

NEXTBLOCK_REGION_LIST

If you want to send to multiple region for the same tx, you can use this.

example:

NEXTBLOCK_REGION_LIST:
  - ny
  - fra

NEXTBLOCK_KEY

You need to set this to use NextBlock

NEXTBLOCK_FEE

Default: 1000000

The fee you pay to nextblock for each successful transaction

NEXTBLOCK_DYNAMIC_FEE

Default: false

Use dynamic fee for NextBlock instead the fixed value from NEXTBLOCK_FEE. The fee will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito. You can set the base points used with NEXTBLOCK_DYNAMIC_FEE_BP

If the calculated fee is smaller than NEXTBLOCK_FEE, NEXTBLOCK_FEE will be used as the fee.

NEXTBLOCK_DYNAMIC_FEE_BP

Default: 0

Calculate NextBlock fee based on your projected profit. 500 means 5% of your projected profit will be used as the fee paid to NextBlock.

The tx landed with this may not have the same percentage as you defined, as the tip value is set before you send the tx, but the actual profit may vary when it actually landed.

NEXTBLOCK_MAX_DYNAMIC_FEE

Default: 0

Maximum dynamic fee in lamports, 0 to disable

NEXTBLOCK_SHOW_SENDING_ERROR

Default: true

Show NextBlock sending error messages in logs

NEXTBLOCK_JITO_ONLY

Default: false

When enabled, Nextblock will only send through jito. aka you won't see failed tx with Nextblock.

TEMPORAL

There's no default key for Temporal, you need to set your own key to use this.

ENABLE_TEMPORAL

Default: false

TEMPORAL_REGION

Default: pit1

Supported region: pit1 ,ams1, fra2 ,ewr1

TEMPORAL_REGION_LIST

If you want to send to multiple region for the same tx, you can use this.

example:

TEMPORAL_REGION_LIST:
  - pit1
  - ams1

TEMPORAL_KEY

You need to set this to use Temporal. Get one from their website.

TEMPORAL_FEE

Default: 1_000_000

The fee you pay to temporal for each successful transaction

TEMPORAL_DYNAMIC_FEE

Default: false

Use dynamic fee for Temporal instead the fixed value from TEMPORAL_FEE. The fee will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito. You can set the base points used with TEMPORAL_DYNAMIC_FEE_BP

If the calculated fee is smaller than TEMPORAL_FEE, TEMPORAL_FEE will be used as the fee.

TEMPORAL_DYNAMIC_FEE_BP

Default: 0

Calculate Temporal fee based on your projected profit. 500 means 5% of your projected profit will be used as the fee paid to Temporal.

The tx landed with this may not have the same percentage as you defined, as the tip value is set before you send the tx, but the actual profit may vary when it actually landed.

TEMPORAL_MAX_DYNAMIC_FEE

Default: 0

Maximum dynamic fee in lamports, 0 to disable

TEMPORAL_SHOW_SENDING_ERROR

Default: true

Show temporal sending error messages in logs

FAST

Fast currently only has one region amsterdam.

ENABLE_FAST

Default: false

FAST_FEE

Default: 1_000_000

The fee you pay to fast for each successful transaction

FAST_DYNAMIC_FEE

Default: false

Use dynamic fee for Fast instead the fixed value from FAST_FEE. The fee will calculate the fee based on the projected profit similar to STATIC_TIP_BP in Jito. You can set the base points used with FAST_DYNAMIC_FEE_BP

If the calculated fee is smaller than FAST_FEE, FAST_FEE will be used as the fee.

FAST_DYNAMIC_FEE_BP

Default: 0

Calculate Fast fee based on your projected profit. 500 means 5% of your projected profit will be used as the fee paid to Fast.

The tx landed with this may not have the same percentage as you defined, as the tip value is set before you send the tx, but the actual profit may vary when it actually landed.

FAST_MAX_DYNAMIC_FEE

Default: 0

Maximum dynamic fee in lamports, 0 to disable

FAST_SHOW_SENDING_ERROR

Default: true

Show fast sending error messages in logs

FAST_JITO_ONLY

Default: false

When enabled, Fast will only send through jito. aka you won't see failed tx with Fast.

LOGGING

DEBUG

Default: false

Enable debug mode for additional logging

ENABLE_LANDING_LOG

Default: false

When this is enabled, it will output an additional WIN log when a transaction is landed. Though if you turn this on while having ENABLE_SIMULATION=false, it may consume a lot of your RPC credits.

ENABLE_SENDING_LOG

Default: true

When this is enabled, it will output all the tx the bot sent out, through which provider(jito/rpc/bloxroute etc.). You can turn this off if the log is too overwhelming to you.

HIDE_ERROR

Default: false

If you don't want to see the error messages, you can turn this to true which will hide them.

FLASHLOAN

Flashloan is a power tool when you have limited budget. You can set a higher trade size than what you have in your wallet, and get arbitrage opportunities that you usually won't be able to get.

Flashloan may not success 100% of the time. When the vault you are borrowing from does not have enough tokens, your transaction will fail due to insufficient fund. Though this should rarely happen.

When flashloan is enabled with the bot, and you are using SOL as one of your base mint, you should also set WRAP_SOL_AMOUNT which is the amount of sol you want to wrap into WSOL. The bot will only use flashloan when the amount is larger than WRAP_SOL_AMOUNT, for trade with less amount it will just use the amount in the wallet, to maximize the potential profit.

ENABLE_FLASHLOAN

Default: false

Whether to enable flashloan. Note you need to have at least 0.5 SOL in the wallet to enable flashloan.

FLASHLOAN_PROVIDER

Default: kamino

Currently supported values are solend, kamino

kamino

Kamino is the recommended provider. It does not charge any fee and the liquidity pool is very deep so you can easily borrow up to a few million.

solend

Soland flashloan charges a 0.04% fee based on the amount you borrow. So a trade that borrows 1000 USDC as shown above will need to find an opportunity that gives you at least 1000.4 USDC back for you to make a profit, compares to at least 1000 USDC when you are not using flashloan. This will results in more failed transactions if you send using spam, or less overall landing if use with Jito. The upside is you can get opportunities that is only possible with big amount. You can also use flash loan as a kick start option to minimize your risk of putting too much amount in your wallet.

Solend only adds 2 more instructions instead of 4. So you will run into less Generated transaction is too large error compares to marginfi, but paying an additional fee as a trade off.

WRAP_SOL_AMOUNT

Default: 0

The amount of SOL to wrap into WSOL, only relevant when SOL is used as one of the base mint. By default the bot will wrap the largest amount in your trade size, but when flashloan is enabled you have to define how much you wrap. For all the trade with trade size less than this number, the bot will use the balance in the wallet, for larger ones the bot will use flashloan.

BLIND_QUOTE_STRATEGY

Blind quote strategy is one way to find opportunities with the bot. You define a list of intermedium mints, the base mints you want to trade with(SOL/USDC/USDT), and what trade size you want to trade with. The bot will use your trade size to quote for all the intermedium mints, one buy and one sell, and find profitable routes by combining the buy and sell routes together.

This strategy is a good start for beginner. It's easy to land as it can combine a lot of small opportunities into a big one, and generally less competitive.

ENABLE_BLIND_QUOTE_STRATEGY

You have to specifically set this to true to enable the strategy

BLIND_QUOTE_STRATEGY:
  ENABLE_BLIND_QUOTE_STRATEGY: true # Enable blind quote strategy

BASE_MINTS

This is used to control what base mint you want to use for your trades and what trade size you want to use. Base mint means the token you are going to trade and profit with, currently only SOL/USDC/USDT is supported.

The following setup means the bot will run with SOL and USDC. Note the unit is lamports here. So 1 SOL = 1,000,000,000 lamports. 1 USDC = 1,000,000 lamports. 1 USDT = 1,000,000 lamports.

Using 1 SOL/2.5 SOL/5 SOL as trade size for SOL, and will only try to send the transaction when the opportunity provides at least 0.0005 SOL in profit.

You can use the same mints for different TRADE_SIZES/MIN_QUOTE_PROFIT pair to customize your strategy.

Example:

BLIND_QUOTE_STRATEGY:
  ENABLE_BLIND_QUOTE_STRATEGY: true # Enable blind quote strategy
  BASE_MINTS:
    - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
      TRADE_SIZES: 
        - 1_000_000_000
        - 2_500_000_000
        - 5_000_000_000
      MIN_QUOTE_PROFIT: 500_000 # Minimum profit in lamports
      PROCESS_DELAY: 1000
      SENDING_COOLDOWN: 0 # If one opportunity is found and tx is sent out, wait at least this time(ms) before sending another one.

PROCESS_DELAY

Default: 1000

Unit in ms. The default value means the bot will wait for 1000ms then try again for the same token-trade size pair. Reducing this number will increase the chance to catch price change right away, but increase the read RPC load.

MIN_QUOTE_PROFIT

MIN_QUOTE_PROFIT is the threshold for when to send a transaction for the potential profit, it does not guarantee that the actual profit land on chain will be that. The actual profit landed on chain can vary, and the bot will fail all transactions that ends up with a negative profit, and land all the ones with a profit, even if the profit is smaller than MIN_QUOTE_PROFIT.

MIN_SIMULATED_PROFIT

SKIP_PROFIT_CHECK_FOR_QUOTE

SENDING_COOLDOWN

If one opportunity is found and tx is sent out, wait at least this time(ms) before sending another one.

TRADE_SIZES

Set in lamports on what sizes you want to trade with. Bot will quote jupiter api with the exact trade size you defined here periodically trying to find the most profitable routes.

Example:

BASE_MINTS:
  - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
    TRADE_SIZES:
      - 1_000_000
      - 10_000_000
    TRADE_RANGE_COUNT: 5 # Number of trade sizes within the range
    TRADE_RANGE_STRATEGY: 'linear' # Strategy for distributing trade sizes
    MIN_QUOTE_PROFIT: 5000 # Minimum profit in lamports
    PROCESS_DELAY: 1000

TRADE_RANGE

If you don't want to manually define every trade size, you can utilize the trade range parameters. To utilize this you need to define 3 params: TRADE_RANGE, TRADE_RANGE_COUNT, TRADE_RANGE_STRATEGY

TRADE_RANGE: This defines the lower bound and higher bound for the range(inclusive). Bot will generate trade sizes only within this range. So make sure you have enough balance of the token for the upper bound.

TRADE_RANGE_COUNT: This defines how many different trade size will be generated within the range.

TRADE_RANGE_STRATEGY: Three values are supported right now: linear , random ,exponential.

linear will generate trade sizes evenly within the range.

random will generate a trade size randomly each time.

exponential will generate trade size on exponential values. For example for range 10 - 1000, with count 5, it will generate trade size like this: [10, 77, 315, 668, 1000]

BASE_MINTS:
  - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
    TRADE_RANGE:
      FROM: 1_000_000_000 # 1 SOL
      TO: 10_000_000_000  # 10 SOL
    TRADE_RANGE_COUNT: 5 # Number of trade sizes within the range
    TRADE_RANGE_STRATEGY: 'linear' # Strategy for distributing trade sizes
    MIN_QUOTE_PROFIT: 5000 # Minimum profit in lamports
    PROCESS_DELAY: 1000

Note: quote using random is slightly slower than quote using linear or fixed trade size. As for random two quotes are sent out one by one while for fixed size two quotes are sent out together.

ROUTE_TYPES

Default: 2hop

Valid values: 2hop, 3hop

By default, only 2hop routes are calculated.

THREE_HOP_MINTS

A list of mints you want to use for your 3hop routes. The most common use case for this is to set USDC when you use SOL as base mint, or set SOL when you use USDC as base mint.

BASE_MINTS:
  - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
    TRADE_RANGE:
      FROM: 1_000_000_000 # 1 SOL
      TO: 10_000_000_000  # 10 SOL
    TRADE_RANGE_COUNT: 5 # Number of trade sizes within the range
    TRADE_RANGE_STRATEGY: 'linear' # Strategy for distributing trade sizes
    MIN_QUOTE_PROFIT: 5000 # Minimum profit in lamports
    PROCESS_DELAY: 1000
    ROUTE_TYPES:
      - 2hop
      - 3hop
    THREE_HOP_MINTS:
      - EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v

Config override

You can override JITO/SPAM configs for each base mint you define, this allows more complex strategy setups without the need to run a different instance of the bot.

Here's an example of overriding DYNAMIC_TIP_BP for two base mints. The one without any override will use the global defined value, the one with override will use the override value.

Note: Only JITO/SPAM configs support config override.

JITO:
  DYNAMIC_TIP_BP: 5000
BASE_MINTS:
  - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
    TRADE_RANGE:
      FROM: 1_000_000_000
      TO: 2_000_000_000
    TRADE_RANGE_COUNT: 5 # Number of trade sizes within the range
    TRADE_RANGE_STRATEGY: 'linear' # Strategy for distributing trade sizes
    MIN_QUOTE_PROFIT: 100_000
  - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
    TRADE_RANGE:
      FROM: 1_000_000_000
      TO: 2_000_000_000
    TRADE_RANGE_COUNT: 5 # Number of trade sizes within the range
    TRADE_RANGE_STRATEGY: 'linear' # Strategy for distributing trade sizes
    MIN_QUOTE_PROFIT: 100_000
    JITO:
      DYNAMIC_TIP_BP: 9000
  - MINT: So11111111111111111111111111111111111111112 # Wrapped SOL
    TRADE_RANGE:
      FROM: 5_000_000_000
      TO: 10_000_000_000
    TRADE_RANGE_COUNT: 5 # Number of trade sizes within the range
    TRADE_RANGE_STRATEGY: 'linear' # Strategy for distributing trade sizes
    MIN_QUOTE_PROFIT: 100_000
    JITO:
      DYNAMIC_TIP_BP: 8000

BACKRUN_STRATEGY

Backrun strategy is monitoring large trade onchain, and counter trade the ones found to find arbitrage opportunities. This is a more advanced strategy, and requires yellowstone to run.

Backrun strategy works like the following:

1. Bot will monitor the markets you defined in DEXES_TO_MONITOR, with all the intermedium mints you defined above

2. If a trade cause the pool's price moved more than MIN_PRICE_IMPACT_PCT, bot will try to create a trade to backrun it

3. Bot will use the trade size you defined in TRADE_CONFIGS, to randomly generate a size between MIN_TRADE_BP and MAX_TRADE_BP, based on the trade you are back running. Or you can just define a FIXED_SIZE as your trade size here.

4. Bot will quote the other size of the trade with jupiter, create a full arb trade tx

5. If the tx has profit and it's higher than MIN_QUOTE_PROFIT, bot will send it out

Example config:

BACKRUN_STRATEGY:
  ENABLE_BACKRUN_STRATEGY: true # Enable backrun strategy
  MEMO: '' # Memo override for the backrun strategy
  SLOT_MEMO: true # Add the backrun tx's slot to the memo, useful to see how far you landed your backrun tx.
  DEXES_TO_MONITOR: # List of DEXes to monitor. Valid values: Raydium, Whirlpool, RaydiumCLMM, Meteora, MeteoraDLMM
    - Raydium
    - Whirlpool
    - RaydiumCLMM
    - Meteora
    - MeteoraDLMM
    - LifinityV2
    - SolFi
  MIN_PRICE_IMPACT_PCT: 0.1 # Minimum price impact in percentage, for the pool you are monitoring. Bot will only backrun trades that caused the price to move more than this percentage.
  BASE_MINTS: # List of base mints to use for the backrun. Currently only SOL and USDC are supported.
    - MINT: So11111111111111111111111111111111111111112
      MIN_QUOTE_PROFIT: 100_000 # Minimum profit in lamports for the quote
      MIN_SIMULATED_PROFIT: 100_000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit
      MIN_TRADE_SIZE: 500_000_000 # Minimum trade size in lamports, if the generated trade size is less than this bot will skip the trade
      MAX_TRADE_SIZE: 150_000_000_000 # Maximum trade size in lamports, if the generated trade size is more than this bot will cap it at this size
      TRADE_CONFIGS: # List of trade configs to use for the backrun. You can define multiple configs to backrun the same tx
        # Bot will randomly pick a trade size between MIN_TRADE_BP and MAX_TRADE_BP, based on the trade you are backrunning
        # You can define multiple configs, and bot will create different txs to backrun the same trade
        - MIN_TRADE_BP: 2000 # Min trade size in basis points
          MAX_TRADE_BP: 2000 # Max trade size in basis points
        # Or you can define FIXED_SIZE
        - FIXED_SIZE: 1_000_000_000
      ROUTE_TYPES: # Currently only 2hop is supported
        - 2hop
    - MINT: EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v # USDC
      MIN_QUOTE_PROFIT: 100_000 # Minimum profit in lamports for the quote
      MIN_SIMULATED_PROFIT: 100_000 # Minimum profit in lamports for the simulated profit
      SKIP_PROFIT_CHECK_FOR_QUOTE: false # Skip profit check for the quote, jup quote can be very inaccurate sometimes, you can use this together with simulation to get the actual profit
      MIN_TRADE_SIZE: 500_000_000 # Minimum trade size in lamports, if the generated trade size is less than this bot will skip the trade
      MAX_TRADE_SIZE: 150_000_000_000 # Maximum trade size in lamports, if the generated trade size is more than this bot will cap it at this size
      TRADE_CONFIGS: # List of trade configs to use for the backrun. You can define multiple configs to backrun the same tx
        # Bot will randomly pick a trade size between MIN_TRADE_BP and MAX_TRADE_BP, based on the trade you are backrunning
        # You can define multiple configs, and bot will create different txs to backrun the same trade
        - MIN_TRADE_BP: 2000 # Min trade size in basis points
          MAX_TRADE_BP: 2000 # Max trade size in basis points
        # Or you can define FIXED_SIZE
        - FIXED_SIZE: 1_000_000_000
      ROUTE_TYPES: # Currently only 2hop is supported
        - 2hop

ENABLE_BACKRUN_STRATEGY

You have to specifically set this to true to enable the strategy

BACKRUN_STRATEGY:
  ENABLE_BACKRUN_STRATEGY: false # Enable backrun strategy

MEMO

You can add memo to all the tx generated from backrun strategy. This will override the BOT level memo.

SLOT_MEMO

This will append the slot of the tx you backrun to your memo, you can compare this value to the slot number you tx landed on, to get a sense of how fast you land your tx.

DEXES_TO_MONITOR

Which dexes to monitor for your intermedium mints. Supported values are:

    - Raydium
    - Whirlpool
    - RaydiumCLMM
    - Meteora
    - MeteoraDLMM
    - LifinityV2
    - SolFi

MIN_PRICE_IMPACT_PCT

This will filter out trades that only has a price impact over this number. This is useful as most of the small trades won't generate an arbitrage opportunity.

BASE_MINTS

This is used to control what base mint you want to use for your trades. Base mint means the token you are going to trade and profit with, currently only SOL/USDC is supported.

MIN_QUOTE_PROFIT

MIN_QUOTE_PROFIT is the threshold for when to send a transaction for the potential profit, it does not guarantee that the actual profit land on chain will be that. The actual profit landed on chain can vary, and the bot will fail all transactions that ends up with a negative profit, and land all the ones with a profit, even if the profit is smaller than MIN_QUOTE_PROFIT.

MIN_SIMULATED_PROFIT

SKIP_PROFIT_CHECK_FOR_QUOTE

MIN_TRADE_SIZE

Unit in lamports. If the generated opportunity has a trade size smaller than this value, it will be skipped.

MAX_TRADE_SIZE

Unit in lamports. If the generated opportunity has a trade size bigger than this value, it will be capped at this value instead.

TRADE_CONFIGS

This is a list that contains two value MIN_TRADE_BP and MAX_TRADE_BP.

Let's say you see a trade trading 100 SOL for WIF. And you want to counter trade it. Usually you don't want to trade back the full amount as it may not have the best price for you. This config allows you to set a range, the example below means the bot will randomly generate a trade size that is 20% - 30% of the original trade. In this case the generated backrun trade will has a trade size between 20 SOL and 30 SOL.

Note this is a list, so you can define multiple range so that you can capture one trade with multiple tx with different trade sizes.

      TRADE_CONFIGS: # List of trade configs to use for the backrun. You can define multiple configs to backrun the same tx
        # Bot will randomly pick a trade size between MIN_TRADE_BP and MAX_TRADE_BP, based on the trade you are backrunning
        # You can define multiple configs, and bot will create different txs to backrun the same trade
        - MIN_TRADE_BP: 2000 # Min trade size in basis points
          MAX_TRADE_BP: 3000 # Max trade size in basis points

ROUTE_TYPES

A list of route types you want to run the bot with. Currently the only supported type is 2hop, which means a trade like A->B->A. More types will be added later.

This is used for fetching lated priority fee. You can get one for free by register an account on .

This can be used to fetch tokens, fetch custom market cache etc.

is optional, but having it can greatly reduce your RPC calls and increase the number of mints you can have with Jupiter.

More info about self-hosted JupV6 can be found here:

The full list is . You can choose which Dex to include from your jup api when starting it. Using the address of the Dex not the name, separate by comma.

The full list is . You can choose which Dex to exclude from your jup api when starting it. Using the address of the Dex not the name, separate by comma.

You need to set to use this.

You also need to set to file and to true when using circular market cache

The port jupiter api uses. Note if you change this, you should also change your with the same port.

This only takes effect when you have to false.

This can help to speed up the jupiter quote time when you has set to false. Though as it says it will also restrict what additional mints it uses in your route.

Fetch new pools opened through gecko terminal and extract the mints used in the pool. API used here: .

Note can only return ~20-30 mints at maximum due to their limitation on the api.

If you have API key from , you can directly set it with the bot. It's the exact param as their document.

You can use a fixed COMPUTE_UNIT_LIMIT to avoid the additional computation needed. When this is set to 0, the bot will call jup to get an estimation of the COMPUTE_UNIT_LIMIT and use that instead. Which is more accurate but a bit slower, and will make 2 additional rpc calls getRecentPrioritizationFees and simulateTransaction for each quote. A suggested value is 250000 for USE_DIRECT_ROUTE_ONLY=true and 350000 for USE_DIRECT_ROUTE_ONLY=false The suggested value should work for 90% of the cases. Note: when using flashloan, the bot will add 100000 to the value to account for the additional instructions needed. You should not set this to be less than 200000, it may result in not landing anything successfully. Read more about what is compute unit limit .

when enabled, will use your Yellowstone to pull blockhash instead of RPC. This can save you a lot of RPC credits. You must also set to use this.

When set, ths RPC url will be used when loading . This is useful when your main RPC does not support transaction history.

Tested you can use a helius free RPC plan with set to 5 to download all the intermedium mint from addresses.

Jito provides a way to send transactions through . Bundles will only land when it succeeds, which is perfect for making arbitrage trade!

You can enable jito by setting ENABLE_JITO=true in your config.yaml file. The bot will then send all transactions to all jito regions defined in through Jito's http endpoint.

This now also accepts urls, if you have a custom jito endpoint you can set it here. For example if you want to use url for the official ny endpoint, you can use

dynamic: The onchain program will calculate your real profit and use a percentage defined with to pay for the jito tip. This always send through the endpoint of jito.

static: This will use a percentage defined with based on the projected profit(the one you see in your opportunity) to pay for the jito tip. This means the actual percentage of the profit when the tx land may not be the same as the projected profit. This will use the endpoint by default, and when is enabled.

fixed: This will use a fixed number(SOL lamports) as your jito profit with . This will use the endpoint by default, and when is enabled.

fixed-list: Similar to fixed, but you send multiple tx with different fixed tip for the same opportunity. You need to set for this to work.

Note: and does not share the same rate limit. they both have 1/ip/wallet/region/s rate limit.

Your need to has dynamic in it for this to take effect.

Your need to has static in it for this to take effect.

Your need to has static-list in it for this to take effect.

Your need to has fixed in it for this to take effect.

Example with a FIXED_TIP of 20000 :

Your need to has fixed-list in it for this to take effect.

Your need to has fixed-range in it for this to take effect.

When this is enabled, a new solana address will be used to send tip in its own tx instead of sending to Jito directly for every Jito transaction. Jito currently is rate limiting bundles based on the accounts in the tx that does the tip, this feature can get around this rate limit by wallet issue to allow you using the same wallet in all locations. This is useful when you have machines in multiple locations but still trying to use the same wallet to run the bot. Example transaction:

The COMPUTE_UNIT_PRICE aka gas fee set for the transaction. Note: this is not SOL lamport. Generally the higher this is, the better chance your tx can actually land on chain. Learn more about what this is here: This only applies to spam, jito transactions set its own value as it's not needed.

This is a config for RPC method, Maximum number of times for the RPC node to retry sending the transaction to the leader. The higher this number, the more chance your tx can land, but also lead to high chance of failure, as retried tx is likely too late for the opportunity.

helius: When using this, you also need to define , and . This will pull the fee dynamically from helius and use a certain percentile value from it.

profit-based: You can only use this when you have and . This will use the value of SPAM_FEE_BPS to decide what fee to use for your tx. 100 SPAM_FEE_BPS means you will pay 1% of your simulated profit as the fee for this tx. This is a very high risk strategy, and can burn you a lot of SOL very quickly. But can also be rewarding when you hit big like this .

Unit in seconds. This controls how often the priority fee is updated. This only works when you set in your base-mint.json

This is an example instruction when setting =true This image shows that the second RPC in the SEND_RPC_URLS list sent this tx(first RPC is RPC 0).

Value from 0 to 100(you can set higher than 100 but not recommended). Automatically set COMPUTE_UNIT_PRICE based on current priority fee level. You need to set HELIUS_API_KEY in order to use this. The bot utilize helius's , to fetch the latest priority fee levels. The response is something like the following from the api, value map to the response, aka 0 means min, 25 means low, 50 means medium, 75 means high, 100 means veryHigh. If the current response looks like below, and you set 30 as the value for priorityFeePercentile, the auto generated COMPUTE_UNIT_PRICE would be 10000 + (60082 - 10000) * ((30 - 25) / 25) = 20016. Note the value for each level will change all the time as market moves.

This config will use 5% of projected profit as the fee. Note this is not 5% of the final profit, it's 5% of the projected profit that bot calculated based on Jup API. If you set , this will be based on the simulated profit, which is more accurate than the projected one.

When setting multiple , this config will send a different tx for each of the RPCs. When this config is set to false, the same tx will be send to all RPCs. You can also see which RPC send the tx in the last instruction of the tx. Index start from 0. See later section for example*.

is a service provider that provides service to send transactions through their endpoint. Our bot has a special collaboration with them to provide you this service at a discounted rate.

You need to set to true when enabling this. Make sure you set the right value for when enabling this.

We have a collaboration with BloXroute, when this is set to true, your spam transaction will be sent through , in addition to all your SEND_RPC_URLS.

is a service provider that provides service to send transactions through their endpoint.

You need to set to true when enabling this. Make sure you set the right value for when enabling this.

is a service provider that provides service to send transactions through their endpoint.

You need to set to true when enabling this. Make sure you set the right value for when enabling this.

is a service provider that provides service to send transactions through their endpoint.

There's no default key for Fast, you need to set your own key and set it with

You need to set to true when enabling this.

Example:

Example:

This config only works with you have both and . Instead of using the quote profit that generated by jup, which can be very inaccurate sometimes, this allows you to use the simulated profit which is the exactly amount you will get if you land it right at your simulation time.

When this is set to true, no profit check for quote will be used. If you have simulation on the bot will still use that and only keep the ones that passed simulation. Jupiter quote can be very inaccurate sometimes so combining this with with ENABLE_SIMULATION can find you more opportunities. This can also be used as part of .

2hop: This means only routes like A -> B -> A will be considered. If you also set to false, there may be other mints between A->B and B->A.

3hop: This means only route like A -> B -> C -> A will be considered. You need to set which additional mints you want to include in the middle in addition to all the intermedium mints. The most common use case for this is to quote for route with SOL and USDC, like SOL -> USDC -> X -> SOL. 3hop will generate similar results like setting to false, but with much faster quote time.

You need to also define when using 3hop.

This config only works with you have both and . Instead of using the quote profit that generated by jup, which can be very inaccurate sometimes, this allows you to use the simulated profit which is the exactly amount you will get if you land it right at your simulation time.

When this is set to true, no profit check for quote will be used. If you have simulation on the bot will still use that and only keep the ones that passed simulation. Jupiter quote can be very inaccurate sometimes so combining this with with ENABLE_SIMULATION can find you more opportunities. This can also be used as part of .

📝
📚Config examples
https://www.helius.dev/
https://www.circular.bot/ref/SMB
Yellowstone
https://station.jup.ag/docs/apis/self-hosted
here
here
https://docs.birdeye.so/reference/get_defi-tokenlist
https://docs.birdeye.so/reference/get_defi-token-trending
https://fe-api.jup.ag/api/v1/tokens/trending
https://www.geckoterminal.com/dex-api
https://www.circular.bot/ref/SMB
here
YELLOWSTONE_URL
bundles
https://ny.mainnet.block-engine.jito.wtf/api/v1/
sendBundle
sendTransaction
https://solscan.io/tx/ZokReqrVXkQgC3gjJoBRDr4sNXKNAuR3Fb4pwD5rFoMRjF4caGwacDEavDiD5CPZRkURgaeCaw73kwqTDSR4F32
https://solscan.io/tx/41CBfg3cg1eKvxgJHJ7TqhmrGJ73BxikDVALV7SQYM4FmMqt22Cfpc18f5bErATSUoTDccKtFSVpGQe1WvMr1b9f
https://solana.com/docs/core/fees#prioritization-fee
sendTransaction
priority fee api
BloXRoute
BloXroute's Trader API v2
NextBlock
Temporal
Fast
https://solscan.io/tx/3o83KouSGE2tYzm7FgrPyXDpQozcytwEDZ8g1UBBn6aUrJoRXQmQUz2d56iHymmobCGy54YhKF9DKzxPnAHxLxEj
https://solscan.io/tx/3xdRkwsA9VrDLapTt3Trp4P2HPxrCDpmhyjTwK4nHDAWx5DDC4u9f1atdYomVV6TGBxSugrWNVTUNwLpNr1xXUBL
https://www.circular.bot/ref/SMB
CIRCULAR_API_KEY
MARKET_MODE
USE_LOCAL_MARKET_CACHE
JUPITER_URL
USE_DIRECT_ROUTE_ONLY
USE_DIRECT_ROUTE_ONLY
INTERMEDIUM_MINT_COUNT_FROM_GECKO
INTERMEDIUM_MINT_FROM_ADDRESSES
DOWNLOAD_RPC_RATE_LIMIT_PER_SECOND
BLOCK_ENGINES
sendBundle
DYNAMIC_TIP_BP
sendTransaction
sendBundle
STATIC_TIP_BP
USE_SEPARATE_TIP_ACCOUNT
sendTransaction
sendBundle
FIXED_TIP
USE_SEPARATE_TIP_ACCOUNT
FIXED_TIP_LIST
TIP_STRATEGIES
TIP_STRATEGIES
TIP_STRATEGIES
TIP_STRATEGIES
TIP_STRATEGIES
TIP_STRATEGIES
HELIUS_API_KEY
PRIORITY_FEE_UPDATE_INTERVAL
PRIORITY_FEE_PERCENTILE
82 SOL arb
ENABLE_SIMULATION
ENABLE_JITO_RPC
priorityFeePercentile
USE_DIFFERENT_TX_FOR_SENDERS
ENABLE_JITO_RPC
SEND_RPC_URLS
ENABLE_SPAM
BLOXROUTE_REGION
ENABLE_SPAM
NEXTBLOCK_REGION
ENABLE_SPAM
TEMPORAL_REGION
CIRCULAR_API_KEY
ENABLE_SPAM
ENABLE_SIMULATION
ENABLE_JITO_RPC
USE_DIRECT_ROUTE_ONLY
USE_DIRECT_ROUTE_ONLY
THREE_HOP_MINTS
ENABLE_SIMULATION
ENABLE_JITO_RPC
super spam strategy
super spam strategy
Base mint SOL