⚙️ Engineering deep-dive

The engine behind Prune

A transparent look at how every component in the system connects — from browser to blockchain.

How the pieces fit together

Two layers: the admin stack that users interact with, and isolated bot containers that execute on-chain autonomously.

Admin layer — handles all user-facing requests
🌐
Browser
HTML / JS
HTTPS
🔁
Nginx
Reverse proxy + static
HTTP
FastAPI Admin
Python asyncio
TCP
🔀
PgBouncer
Connection pooler
TCP
🗄️
PostgreSQL
Primary database
Docker Socket API
Bot layer — runs autonomously in isolated containers
burnbot_1_WAGMI_01
burnbot_1_PEPE_02
+ up to N bots
Solana RPC
Balance · TX submit
JSON-RPC
🪐
Jupiter API
Swap quotes · routing
HTTPS
💧
Raydium / PumpSwap
Liquidity pools
HTTPS
📱
Telegram
Cycle notifications

What happens each cycle

Each bot runs a continuous asyncio loop. Here is exactly what happens on every iteration.

01
Check SOL balance via RPC

The bot calls getBalance on its treasury wallet. If balance is below the configured reserve + fee buffer, the cycle is skipped and the bot sleeps.

solana.rpc.async_api
02
Calculate spendable amount

Spendable = balance − sol_reserve − fee_buffer, then multiplied by the configured buyback_percent. This prevents the wallet from ever running dry.

in-memory arithmetic
03
Get Jupiter swap quote

Requests a quote from Jupiter Aggregator for SOL → TOKEN. Jupiter routes through all Solana DEXes to find the best price with minimal slippage.

GET /swap/v1/quote
04
Build, sign and submit transaction

Jupiter returns a serialized VersionedTransaction. The bot signs it with the treasury keypair (decrypted in-memory, never on disk) and submits via Solana RPC.

solders · VersionedTransaction
05
Mode-specific action

Buyback & Burn: calls the SPL Token burn instruction on the received tokens.
Buyback Only: tokens stay in treasury.
Add Liquidity: pairs SOL + tokens into the Raydium or PumpSwap pool.

spl.token.instructions · Raydium SDK
06
Persist stats & notify

Stats (SOL spent, tokens burned/bought, cycle count) are written to a JSON file readable by the admin service. A Telegram message with the transaction link is sent if enabled.

json · aiohttp · Telegram Bot API
07
Sleep until next cycle

asyncio.sleep(INTERVAL_SECONDS) — configurable from 60 s to several hours. Near-zero CPU while sleeping.

asyncio.sleep
bot_loop.py
async def bot_loop(config, keypair): while True: # 01 — check treasury balance balance = await get_sol_balance(client, owner) spendable = balance - config.sol_reserve - FEE_BUFFER if spendable < MIN_BUYBACK: await asyncio.sleep(config.interval_seconds) continue # 02 — apply buyback percent amount = int(spendable * config.buyback_percent / 100) # 03 — Jupiter quote (SOL → TOKEN) quote = await jupiter_quote( session, SOL_MINT, config.token_mint, amount, config.slippage_bps ) # 04 — sign & submit swap tx tx_bytes = await jupiter_swap_tx(session, quote, owner) sig = await send_versioned_tx(client, tx_bytes, keypair) tokens_received = int(quote["outAmount"]) # 05 — mode-specific action if config.mode == "BUYBACK_AND_BURN": await burn_tokens( client, keypair, config.token_mint, tokens_received ) elif config.mode == "ADD_LIQUIDITY": await add_to_pool( pool_id, amount // 2, tokens_received ) # 06 — persist stats & notify stats["sol_spent_total"] += amount stats["cycles"] += 1 save_stats(stats) await telegram_notify(sig, amount, tokens_received) # 07 — sleep await asyncio.sleep(config.interval_seconds)

How secrets are protected

Private keys are sensitive. Here is every layer of protection applied to keypairs and credentials.

🔐
AES-256-GCM keypair encryption

Every treasury and creator wallet is encrypted with AES-256-GCM before being written to the database. The encryption key lives only in the server environment — never stored alongside ciphertext.

key = ENCRYPT_KEY (env, 32 bytes) iv = os.urandom(12) # unique per key cipher = AES-256-GCM(key, iv) stored = iv + tag + ciphertext plaintext only in memory during bot run
🪪
JWT Bearer authentication

All admin API endpoints require a signed JWT token. Tokens are issued on login and expire after 30 days. The signing secret is a configurable environment variable — never hardcoded.

algorithm : HS256 expiry : 30 days secret : SECRET_KEY (env) public endpoints (bot stats) use X-API-Key — SHA-256 hashed in DB
🐳
Docker process isolation

Each bot runs in a dedicated Docker container with its own filesystem, process namespace, and network stack. A crash or compromise in one bot cannot affect any other bot or the admin service.

restart : unless-stopped network : isolated bridge per bot no shared volumes between bots container name: burnbot_{user_id}_{TOKEN}_{id}

Technologies powering Prune

Every component chosen for reliability, performance, and Solana ecosystem fit.

Solana
Blockchain

All buybacks, burns, and liquidity operations are on-chain Solana transactions — finalised in ~400 ms with sub-cent fees.

Jupiter Aggregator
DEX routing

Routes every swap across all major Solana DEXes for best price. Bots use the lite API for lower latency and no Metis dependency.

Raydium / PumpSwap
AMM liquidity pools

Add Liquidity mode deposits into the pool that the token lives on — PumpSwap or Raydium AMM V4, auto-detected at bot startup.

FastAPI
Admin API · Python asyncio

Async Python framework with Pydantic validation. Handles auth, bot management, stats, avatar uploads, and the public API — all in one process.

PgBouncer
Connection pooler

Sits between FastAPI and PostgreSQL in transaction pooling mode. Caps DB connections to ~20 regardless of concurrent requests or bot count.

PostgreSQL 16
Primary database

Stores users, bots, API keys (SHA-256 hashed), bot stats, and encrypted keypairs. SQLAlchemy async ORM with asyncpg driver.

Docker
Container runtime

The admin service manages bot containers via the Docker socket API at runtime. Each bot is an independent container with its own lifecycle and logs.

Nginx
Reverse proxy · static

Serves all static files directly with browser caching and proxies only API calls to FastAPI. Handles file uploads up to 10 MB.

AES-256-GCM
Keypair encryption

Python's cryptography library encrypts every private key before DB write. Unique 12-byte IV per key and 16-byte authentication tag prevent tampering.