Skip to content

divi2806/brute

Repository files navigation

Brute

Brute is a Solana devnet perpetuals trading platform built for a hackathon-style demo. A user connects a wallet, mints devnet BRUTE collateral from the app faucet, deposits collateral into the protocol vault, and opens long or short perpetual positions against Pyth-backed markets.

This repo includes the on-chain Anchor program, Next.js frontend, API routes, Pyth price streaming, BRUTE faucet, Postgres-backed event indexer, TP/SL trigger-order keeper, and an OpenCode-powered AI signal agent.

Devnet Deployment

Item Value
Product Brute
Network Solana devnet
Program ID P5cZ4zoxU7XJiKuYyarXgrnXDWjkPSqontfwTm4hrWL
BRUTE mint n5q7mdopFVkQMRH7FP8Y99sDckJi2rd2Yk714DV5eL2
Latest deploy signature 3B91JH4uMEFXuLe5Npcu2QAcUzNfbmmuvFBz45hgx12Gi8a8n9pC8rDanNKWe69tdnEqqMeUcGSCbDtztPiJN9uc
Deploy slot 466210026

What Is Included

  • Anchor perps program with protocol config, markets, BRUTE vault custody, user collateral accounts, positions, funding, liquidation, fee accounting, and admin controls.
  • Next.js trading app with wallet connect, live ticker, Pyth price cards, market chart, trade ticket, order confirmation, positions table, portfolio, settings, architecture view, and devnet status panel.
  • BRUTE faucet and deposit/withdraw flows.
  • Pyth Hermes SSE display pricing and on-chain Pyth verified settlement pricing.
  • Postgres/Prisma indexer for Anchor trade events.
  • Off-chain TP/SL order storage plus keeper execution script.
  • AI signal endpoint powered by OpenCode-compatible chat completions, with a deterministic fallback for demos.

Tradeable Markets

The app is configured for devnet markets with Pyth-backed feeds:

  • XAU/USD Gold
  • XAG/USD Silver
  • EUR/USD Euro
  • AAPL/USD Apple equity price feed
  • TSLA/USD Tesla equity price feed
  • BTC/USD Bitcoin
  • ETH/USD Ethereum
  • SOL/USD Solana

Market-open state is respected in the UI. When traditional markets are closed or a feed is stale, the app shows the market as closed/stale and the contract freshness checks prevent settlement with old oracle data.

Architecture

flowchart LR
  Wallet["User Wallet"] --> App["Next.js Brute App"]
  App --> Hermes["Pyth Hermes SSE"]
  App --> Api["Next.js API Routes"]
  App --> Program["Anchor Program on Solana Devnet"]
  Program --> PythSolana["Pyth Solana Price Account"]
  Program --> Vault["BRUTE Token Vault"]
  Api --> Db["Postgres / Prisma"]
  Api --> OpenCode["OpenCode AI Endpoint"]
  Indexer["Event Indexer"] --> Program
  Indexer --> Db
  Keeper["TP/SL Keeper"] --> Db
  Keeper --> Program
Loading

Display prices stream from Pyth Hermes so the UI updates without refresh. Settlement uses the on-chain Pyth price account passed into the Anchor instruction, where the program verifies owner, discriminator, feed ID, freshness, confidence, and price normalization before using the value.

User Flow

  1. Connect a Solana devnet wallet.
  2. Use Settings or the trade sidebar faucet to mint devnet BRUTE.
  3. Deposit BRUTE into the protocol vault.
  4. Pick a market and review live oracle price, feed age, confidence, leverage, and estimated liquidation price.
  5. Open a long or short position.
  6. Track positions with entry, mark, liquidation price, margin ratio, PnL, and funding.
  7. Close manually, set TP/SL trigger orders, or let a keeper/liquidator close eligible positions.
  8. Withdraw free collateral back to the wallet.

AI Signal Agent

The AI signal endpoint is:

POST /api/agent/signal
Content-Type: application/json

{ "marketKey": "BTCUSD" }

Implementation file:

app/src/app/api/agent/signal/route.ts

UI location: the agent is in the Trade tab, right sidebar, inside the Brute AI Signal card. It is not in the Portfolio page. Press Analyze and the app sends the selected market to /api/agent/signal.

The endpoint reads recent candles from /api/candles, pulls the current Pyth price, computes lightweight momentum features, and calls:

${LLM_BASE_URL}/chat/completions

using LLM_MODEL. If OPENCODE_API_KEY is missing or the provider is unavailable, the route returns a deterministic fallback signal. Agent responses are currently stateless request/response results and are not stored as chat history in the database.

API Routes

Route Purpose
GET /api/health Devnet status panel data: RPC, Pyth, program ID, BRUTE mint.
GET /api/architecture Architecture data used by the architecture page.
GET /api/candles Historical candle data for charts and AI features.
GET /api/trades Indexed trade events from Postgres, with RPC fallback.
POST /api/faucet Mint devnet BRUTE to the connected wallet.
GET /api/orders List TP/SL trigger orders.
POST /api/orders Create a TP/SL trigger order in Postgres.
PATCH /api/orders Cancel/update trigger order status.
POST /api/agent/signal OpenCode-powered perps signal for the selected market.

Contract Overview

Instruction What it does
initialize Creates protocol config and stores authority, BRUTE mint, vault, fee state, insurance state, and pause flag.
set_paused Lets authority pause or unpause trading.
create_market Creates a market PDA with symbol, Pyth feed ID, max leverage, fees, margin, OI, and funding indexes.
set_market_active Enables or disables trading for one market.
create_user_account Creates the user PDA that tracks deposited collateral and reserved collateral.
deposit_collateral Transfers BRUTE from user ATA to protocol vault and credits user collateral.
withdraw_collateral Transfers free BRUTE from vault to user ATA after reserved-collateral checks.
open_position Verifies oracle price, checks leverage and risk limits, charges taker fee, reserves collateral, and creates a position PDA.
close_position Verifies oracle price, realizes PnL/funding, releases collateral, settles user account, and closes the position.
keeper_close_position Devnet helper for off-chain trigger-order execution. Settlement still goes to the owner PDA.
liquidate Closes unhealthy positions, pays liquidation bonus, handles bad debt through insurance accounting, and releases reserve.
update_funding Updates market funding indexes from long/short open interest skew.
collect_fees Moves accrued protocol fees from pending accounting into fee-vault accounting.
withdraw_fees Lets authority withdraw collected protocol fees from vault to a fee receiver token account.

Technical Deep Dive

For the full contract walkthrough, PDA seeds, instruction-level behavior, oracle verification, PnL/funding/liquidation math, Anchor events, indexer behavior, TP/SL keeper flow, and AI signal architecture, see:

docs/TECHNICAL_OVERVIEW.md

Contract Math

All USD-style values use micro units:

MICRO = 1_000_000
$1.00 = 1_000_000

Opening a position:

notional = size_usd
required initial check: collateral_usd * max_leverage >= size_usd
taker_fee = size_usd * taker_fee_bps / 10_000
position_collateral = collateral_usd - taker_fee

PnL:

price_delta = exit_price - entry_price
raw_pnl = price_delta * size_usd / entry_price
long_pnl = raw_pnl
short_pnl = -raw_pnl

Funding:

total_oi = long_open_interest + short_open_interest
skew = long_open_interest - short_open_interest
funding_delta ~= skew / total_oi * max_funding_rate * elapsed / 8h
funding_payment = (current_funding_index - entry_funding_index) * size_usd / FUNDING_SCALE

Liquidation:

effective_collateral = position_collateral + pnl - funding_payment
maintenance_margin = size_usd * maintenance_margin_bps / 10_000
liquidatable = effective_collateral < maintenance_margin
liquidation_bonus = size_usd * 50 / 10_000

Local Development

Install dependencies:

npm install
npm --prefix app install

Run checks:

cargo test
npm --prefix app run typecheck
npm --prefix app run build

Run the frontend:

npm --prefix app run dev

Run database setup:

npm --prefix app run db:generate
npm --prefix app run db:push

Backfill program events:

npm --prefix app run indexer:backfill

Run the TP/SL keeper once:

npm --prefix app run keeper:orders

Deploy the program to devnet:

anchor deploy --provider.cluster devnet

Environment Variables

Create app/.env.local for local development and configure these names in Vercel/Railway/Render for deployed services:

NEXT_PUBLIC_SOLANA_RPC_URL=
NEXT_PUBLIC_BRUTE_PROGRAM_ID=
NEXT_PUBLIC_BRUTE_MINT=
NEXT_PUBLIC_PYTH_HERMES_URL=
DATABASE_URL=
POSTGRES_URL=
PRISMA_DATABASE_URL=
FAUCET_AUTHORITY_KEYPAIR=
OPENCODE_API_KEY=
LLM_PROVIDER=opencode
LLM_BASE_URL=https://opencode.ai/zen/v1
LLM_MODEL=kimi-k2.6

Do not commit .env, .env.local, private keypairs, or faucet authority secrets.

Deployment

  • Frontend/API routes: Vercel is the easiest free option for the Next.js app.
  • Database: Prisma Postgres, Supabase Postgres, Neon, or another hosted Postgres.
  • Indexer and keeper: Railway or Render background worker/cron jobs. On a free tier, run them on an interval rather than expecting always-on uptime.
  • Program: deployed separately with Anchor/Solana CLI to devnet.

See DEPLOYMENT.md for service-by-service deployment notes.

Security Status

This is a devnet/hackathon product, not a mainnet-audited protocol. The code includes important safety checks such as PDA seed validation, oracle verification, stale price rejection, confidence checks, fee accounting, market pause controls, max open interest, max skew, max position size, and tests for core math/oracle behavior.

Before mainnet, Brute needs a professional audit, stronger keeper authorization design, durable indexer infrastructure, richer economic simulations, and production-grade monitoring.

About

An onchain perps trading with AI agent execution

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages