Skip to content

TeaBay/agent-challenge

Β 
Β 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

164 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ“Š SolFolio β€” Solana Portfolio Intelligence Agent

Your personal AI-powered Solana portfolio analyst β€” running 100% on decentralized infrastructure.

SolFolio

πŸ† Submission for the Nosana x ElizaOS Agent Challenge on Superteam Earn


Overview

SolFolio is a personal AI agent that gives you instant, conversational intelligence about any Solana wallet. Paste a wallet address and get a full portfolio breakdown β€” token holdings, USD valuations, allocation charts, transaction history, and AI-powered risk analysis β€” all through natural language chat.

Built on ElizaOS v2 with a custom plugin-solfolio that connects to real-time on-chain data via Solana RPC and the Jupiter aggregator, SolFolio transforms raw blockchain data into actionable insights. The entire stack β€” from the Qwen3.5 LLM to the agent runtime β€” runs on the Nosana decentralized GPU network. No centralized cloud. No API keys to third-party AI providers. Your data, your infrastructure, your agent.


✨ Features

  • πŸ“Š Instant portfolio analysis β€” Enter any Solana wallet address and get a complete breakdown of SOL balance, SPL token holdings, and total USD value
  • πŸ’¬ Natural language chat β€” Ask questions in plain English, powered by Qwen3.5 running on Nosana's decentralized inference
  • πŸ“ˆ Real-time token prices β€” Live price data from the Jupiter aggregator with 24h change tracking
  • πŸ”„ Transaction history β€” Recent transactions with automatic type detection (transfers, swaps, staking)
  • 🎯 Portfolio allocation visualization β€” Interactive pie charts showing how your holdings are distributed
  • 🧠 AI-powered risk analysis β€” Concentration metrics (HHI, effective positions), risk scoring, and actionable diversification suggestions
  • 🌐 100% decentralized β€” The full stack runs on Nosana's GPU network β€” no AWS, no GCP, no centralized cloud
  • πŸ”Œ Custom ElizaOS plugin β€” Purpose-built plugin-solfolio with 4 actions and 2 providers for deep Solana integration

πŸ“Έ Screenshots

Portfolio Dashboard
Portfolio dashboard with allocation chart, token table, and live chat

Chat Analysis
Natural language portfolio analysis and risk insights


πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Nosana GPU Network                          β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚                   Docker Container                        β”‚  β”‚
β”‚  β”‚                                                           β”‚  β”‚
β”‚  β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚
β”‚  β”‚  β”‚   Frontend   β”‚    β”‚       ElizaOS v2 Runtime         β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  React+Vite  │◄──►  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  Tailwind    β”‚    β”‚  β”‚    plugin-solfolio          β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  Recharts    β”‚    β”‚  β”‚                            β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚             β”‚    β”‚  β”‚  Actions:                   β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  :5173 ──────┼─────  β”‚   β€’ GET_PORTFOLIO          β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚  (proxies    β”‚    β”‚  β”‚   β€’ GET_TOKEN_PRICE        β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚   to :3000)  β”‚    β”‚  β”‚   β€’ GET_TRANSACTIONS       β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β”‚             β”‚    β”‚  β”‚   β€’ ANALYZE_HOLDINGS        β”‚  β”‚  β”‚  β”‚
β”‚  β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β”‚  β”‚                            β”‚  β”‚  β”‚  β”‚
β”‚  β”‚                      β”‚  β”‚  Providers:                β”‚  β”‚  β”‚  β”‚
β”‚  β”‚                      β”‚  β”‚   β€’ walletProvider         β”‚  β”‚  β”‚  β”‚
β”‚  β”‚                      β”‚  β”‚   β€’ priceProvider          β”‚  β”‚  β”‚  β”‚
β”‚  β”‚                      β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚  β”‚
β”‚  β”‚                      β”‚             β”‚      β”‚              β”‚  β”‚  β”‚
β”‚  β”‚                      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β”‚                                       β”‚      β”‚                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                        β”‚      β”‚
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      └──────────────┐
                          β–Ό                                   β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚   Solana RPC     β”‚                β”‚   Jupiter API    β”‚
                β”‚                  β”‚                β”‚                  β”‚
                β”‚ β€’ getBalance     β”‚                β”‚ β€’ Price API v2   β”‚
                β”‚ β€’ getTokenAccts  β”‚                β”‚ β€’ Token list     β”‚
                β”‚ β€’ getSignatures  β”‚                β”‚ β€’ Token search   β”‚
                β”‚ β€’ getParsedTxs   β”‚                β”‚                  β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data flow: The frontend communicates with the ElizaOS REST API (/api). When a user sends a message or wallet address, ElizaOS routes it to the appropriate plugin-solfolio action. The action queries Solana RPC for on-chain data and Jupiter for real-time prices, composes a natural-language response via Qwen3.5, and returns it to the frontend.


πŸ› οΈ Tech Stack

Layer Technology Purpose
AI Framework ElizaOS v2 Agent runtime, plugin system, memory, REST API
LLM Qwen3.5 on Nosana Natural language understanding and generation
Language TypeScript Full-stack type safety
Frontend React 19 UI framework
Build Tool Vite 6 Frontend dev server and bundler
Styling Tailwind CSS 4 Utility-first styling
Charts Recharts Portfolio allocation visualization
Blockchain @solana/web3.js Solana RPC, transaction parsing
Token Data @solana/spl-token SPL token account parsing
Prices Jupiter Price API v2 Real-time token prices and search
Container Docker Multi-stage build for production
Compute Nosana Decentralized GPU deployment

πŸš€ Getting Started

Prerequisites

Requirement Version Notes
Node.js 23+ Required by ElizaOS v2
pnpm 9+ npm install -g pnpm
Docker Latest For containerized deployment
Git Latest β€”

1. Clone and Install

git clone https://github.com/YOUR-USERNAME/solfolio-agent.git
cd solfolio-agent

# Install backend dependencies
pnpm install

# Install frontend dependencies
cd frontend && pnpm install && cd ..

2. Configure Environment

cp .env.example .env

Edit .env with your Nosana endpoint (or use the defaults provided):

# Nosana-hosted LLM inference
OPENAI_API_KEY=nosana
OPENAI_API_URL=https://4ksj3tve5bazqwkuyqdhwdpcar4yutcuxphwhckrdxmu.node.k8s.prd.nos.ci/v1
MODEL_NAME=Qwen/Qwen3.5-4B

# Nosana-hosted embeddings
OPENAI_EMBEDDING_URL=https://4yiccatpyxx773jtewo5ccwhw1s2hezq5pehndb6fcfq.node.k8s.prd.nos.ci/v1
OPENAI_EMBEDDING_API_KEY=nosana
OPENAI_EMBEDDING_MODEL=Qwen3-Embedding-0.6B
OPENAI_EMBEDDING_DIMENSIONS=1024

# Server
SERVER_PORT=3000
πŸ”§ Alternative: Local development with Ollama
ollama pull qwen3.5:27b
ollama serve
OPENAI_API_KEY=ollama
OPENAI_API_URL=http://127.0.0.1:11434/v1
MODEL_NAME=qwen3.5:27b

3. Run in Development Mode

Terminal 1 β€” ElizaOS backend:

pnpm dev
# Starts ElizaOS agent server on http://localhost:3000

Terminal 2 β€” Frontend dev server:

cd frontend
pnpm dev
# Starts Vite dev server on http://localhost:5173
# API calls are proxied to :3000 automatically

Open http://localhost:5173 and paste a Solana wallet address to get started.

4. Docker Build and Run

# Build the multi-stage Docker image
docker build -t solfolio-agent:latest .

# Run locally
docker run -p 3000:3000 --env-file .env solfolio-agent:latest

The Docker image uses a two-stage build:

  1. Stage 1 β€” Builds the React frontend with Vite
  2. Stage 2 β€” Installs ElizaOS dependencies, copies the built frontend into the serving directory, and starts the agent

πŸ“ Project Structure

solfolio-agent/
β”œβ”€β”€ characters/
β”‚   └── solfolio.character.json        # Agent personality, system prompt, examples
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.ts                       # Plugin entry point (exports solfolioPlugin)
β”‚   └── plugin-solfolio/
β”‚       β”œβ”€β”€ index.ts                   # Plugin definition β€” registers all actions & providers
β”‚       β”œβ”€β”€ types.ts                   # Shared TypeScript interfaces
β”‚       β”œβ”€β”€ utils.ts                   # Formatting helpers (USD, addresses, timestamps)
β”‚       β”œβ”€β”€ actions/
β”‚       β”‚   β”œβ”€β”€ getPortfolio.ts        # GET_PORTFOLIO β€” fetch wallet holdings
β”‚       β”‚   β”œβ”€β”€ getTokenPrice.ts       # GET_TOKEN_PRICE β€” look up live token prices
β”‚       β”‚   β”œβ”€β”€ getTransactions.ts     # GET_TRANSACTIONS β€” recent transaction history
β”‚       β”‚   └── analyzeHoldings.ts     # ANALYZE_HOLDINGS β€” risk & diversification analysis
β”‚       β”œβ”€β”€ providers/
β”‚       β”‚   β”œβ”€β”€ walletProvider.ts      # Injects current portfolio into agent context
β”‚       β”‚   └── priceProvider.ts       # Injects live price data into agent context
β”‚       └── services/
β”‚           β”œβ”€β”€ solanaService.ts       # Solana RPC wrapper (balance, tokens, transactions)
β”‚           └── jupiterService.ts      # Jupiter API wrapper (prices, token list, search)
β”œβ”€β”€ frontend/
β”‚   β”œβ”€β”€ package.json                   # React 19, Recharts, Tailwind, Vite
β”‚   β”œβ”€β”€ vite.config.ts                 # Dev server with API proxy to :3000
β”‚   β”œβ”€β”€ index.html
β”‚   └── src/
β”‚       β”œβ”€β”€ main.tsx                   # React entry point
β”‚       β”œβ”€β”€ App.tsx                    # Root layout β€” dashboard + chat panels
β”‚       β”œβ”€β”€ api.ts                     # ElizaOS REST API client
β”‚       β”œβ”€β”€ types.ts                   # Frontend type definitions
β”‚       β”œβ”€β”€ index.css                  # Tailwind base styles
β”‚       └── components/
β”‚           β”œβ”€β”€ WalletInput.tsx        # Address input with validation
β”‚           β”œβ”€β”€ PortfolioSummary.tsx   # Total value, SOL balance, change cards
β”‚           β”œβ”€β”€ TokenTable.tsx         # Sortable table of all token holdings
β”‚           β”œβ”€β”€ AllocationChart.tsx    # Recharts pie chart of portfolio allocation
β”‚           β”œβ”€β”€ TransactionFeed.tsx    # Recent transactions with type badges
β”‚           └── ChatPanel.tsx          # Full chat interface with message history
β”œβ”€β”€ nos_job_def/
β”‚   └── nosana_eliza_job_definition.json  # Nosana deployment job definition
β”œβ”€β”€ Dockerfile                         # Multi-stage build (frontend + ElizaOS)
β”œβ”€β”€ .env.example                       # Environment variable template
β”œβ”€β”€ package.json                       # ElizaOS deps, @solana/web3.js, scripts
β”œβ”€β”€ tsconfig.json
└── LICENSE                            # MIT

πŸ”Œ ElizaOS Plugin β€” plugin-solfolio

SolFolio's core intelligence lives in a custom ElizaOS plugin that provides 4 actions (tools the agent can invoke) and 2 providers (context injected into every conversation turn).

Actions

Action Trigger What It Does
GET_PORTFOLIO User provides a wallet address or asks about "portfolio", "balance", "holdings" Fetches SOL balance + all SPL token accounts, resolves USD values via Jupiter, caches result, and returns a formatted summary
GET_TOKEN_PRICE User asks about "price", "cost", "worth", or "how much is X" Looks up any Solana token by symbol/name using Jupiter's verified token list and returns live price with 24h change
GET_TRANSACTIONS User asks about "transactions", "history", "activity", or "recent" Fetches parsed transactions from Solana RPC, detects types (transfer, swap, stake), and formats with Solscan links
ANALYZE_HOLDINGS User asks about "risk", "diversification", "analysis", or "allocation" Computes HHI (Herfindahl Index), effective positions, concentration risk, detects dust/scam tokens, and generates suggestions

Providers

Provider Description
walletProvider Automatically injects the currently loaded wallet's portfolio data into the agent's context so it can reference holdings in any response
priceProvider Injects live price data for SOL + all tracked portfolio tokens so the agent always has current pricing context

Services

Service API Features
SolanaService Solana RPC (mainnet-beta, Ankr fallback) Balance, token accounts, parsed transactions, automatic RPC rotation with retry/backoff
JupiterService Jupiter Price API v2 + Token List Batch price fetching (100/request), token search, 30s price cache, 6h token list cache

☁️ Deployment to Nosana

Step 1 β€” Build and Push Docker Image

# Build
docker build -t yourusername/solfolio-agent:latest .

# Test locally
docker run -p 3000:3000 --env-file .env yourusername/solfolio-agent:latest

# Push to Docker Hub (must be public)
docker login
docker push yourusername/solfolio-agent:latest

Step 2 β€” Configure Job Definition

The Nosana job definition is in nos_job_def/nosana_eliza_job_definition.json. Update the image field with your Docker Hub username:

{
  "ops": [
    {
      "id": "solfolio-agent",
      "type": "container/run",
      "args": {
        "image": "yourusername/solfolio-agent:latest",
        "expose": 3000,
        "env": {
          "OPENAI_API_KEY": "nosana",
          "OPENAI_API_URL": "https://...",
          "MODEL_NAME": "Qwen/Qwen3.5-4B",
          "SERVER_PORT": "3000",
          "NODE_ENV": "production"
        }
      }
    }
  ],
  "version": "0.1"
}

Step 3 β€” Deploy via Nosana Dashboard

  1. Go to dashboard.nosana.com/deploy
  2. Connect your Solana wallet
  3. Paste the contents of nosana_eliza_job_definition.json
  4. Select a compute market (e.g., nvidia-3090)
  5. Click Deploy
  6. Once running, you'll receive a public URL

Step 4 β€” Deploy via Nosana CLI (Alternative)

npm install -g @nosana/cli

nosana job post \
  --file ./nos_job_def/nosana_eliza_job_definition.json \
  --market nvidia-3090 \
  --timeout 300 \
  --api <YOUR_API_KEY>

# Monitor
nosana job status <job-id>
nosana job logs <job-id>

πŸ’‘ Get your API key at deploy.nosana.com/account and claim free builder credits at nosana.com/builders-credits.


πŸ”— API

SolFolio's frontend communicates with the ElizaOS REST API. In development, Vite proxies /api requests to http://localhost:3000.

Key Endpoints

Method Endpoint Description
GET /api/agents List all running agents (returns agent IDs)
POST /api/:agentId/message Send a message to the agent and get a response

Example: Send a Message

# Get the agent ID
AGENT_ID=$(curl -s http://localhost:3000/api/agents | jq -r '.agents[0].id')

# Send a portfolio request
curl -X POST "http://localhost:3000/api/${AGENT_ID}/message" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Analyze wallet 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU",
    "userId": "user1",
    "roomId": "default"
  }'

The response is an array of message objects:

[
  { "text": "Fetching portfolio for `7xKX...AsU`... This may take a moment." },
  { "text": "πŸ“Š **Portfolio Summary for `7xKX...AsU`**\n\nπŸ’° **Total Value**: $1,234.56\n..." }
]

πŸ… Judging Criteria Alignment

Criterion (Weight) How SolFolio Addresses It
Technical Implementation (25%) Custom ElizaOS plugin with 4 actions, 2 providers, 2 services. Multi-RPC fallback with retry/backoff. Jupiter batch pricing. Herfindahl Index risk scoring. Full TypeScript.
Nosana Integration Depth (25%) LLM inference via Nosana-hosted Qwen3.5 endpoint. Embeddings via Nosana-hosted Qwen3-Embedding. Deployed as containerized job on Nosana GPU network. No centralized cloud dependency.
Usefulness & UX (25%) Real-world portfolio analytics. Split-panel UI (dashboard + chat). Interactive charts. Works with any public Solana wallet β€” no wallet connection needed.
Creativity & Originality (15%) Combines conversational AI with on-chain analytics. Risk analysis with financial metrics (HHI, effective diversification). Dust/scam token detection. Transaction type classification.
Documentation (10%) Comprehensive README with architecture diagram, full project structure, API docs, deployment guide, and setup instructions.

πŸ™ Built With

  • ElizaOS β€” The AI agent framework that makes this possible
  • Nosana β€” Decentralized GPU compute for truly permissionless AI
  • Jupiter β€” Solana's leading DEX aggregator and price oracle
  • Solana β€” The blockchain powering the entire data layer
  • Qwen3.5 β€” The LLM brain behind the conversational interface

πŸ“„ License

This project is open source and available under the MIT License.


Built with ElizaOS Β· Deployed on Nosana Β· Powered by Qwen3.5
Your portfolio. Your agent. Your infrastructure.

About

Nosana Builders' Challenge: Agent 101

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • TypeScript 97.3%
  • Other 2.7%