This repository contains a full-stack, on-chain AI chat application built on Solana, combining:
- an Anchor smart contract (
chat-agent) - a Next.js frontend
- a verifiable LLM oracle workflow
- fully on-chain AI response persistence
It demonstrates how to build trust-minimized AI agents where:
- prompts are submitted on-chain
- inference is executed by an oracle
- responses are written back to Solana
- users can independently verify AI outputs
No centralized backend. No hidden server logic.
Users can:
- Create a new chat session on Solana
- Send messages via a wallet-signed transaction
- Trigger LLM inference through an oracle
- Receive AI responses written on-chain
- Resume chats even after refresh or disconnect
- Reclaim unused lamports after inference completes
Everything important is either:
- signed by the user, or
- signed by the oracle, or
- enforced by PDA constraints
┌────────────┐
│ Frontend │ Next.js + Wallet
└─────┬──────┘
│ signed tx
▼
┌────────────┐
│ Chat Agent │ Anchor Program
│ Program │
└─────┬──────┘
│ CPI
▼
┌────────────┐
│ LLM Oracle │ Off-chain inference
└─────┬──────┘
│ callback
▼
┌────────────┐
│ Response │ PDA on Solana
└────────────┘
.
├── programs/
│ └── chat-agent/ # Anchor smart contract
│
├── app/ # Next.js app router
│ ├── page.tsx # Chat creation
│ ├── chat/[chatContext]/ # Chat session UI
│
├── lib/
│ ├── useChatLogic.ts # Core chat + tx orchestration
│ ├── chatUtils.ts # Polling + tx helpers
│ ├── chatHistory.ts # Local chat persistence
│ ├── llm-accounts.ts # PDA derivation helpers
│
├── components/ # UI components
├── context/ # Prompt + state contexts
└── program-helpers/ # Instruction builders
| Instruction | Purpose |
|---|---|
initialize |
Create a new chat context |
ai_inference |
Request LLM inference |
callback_from_ai |
Oracle writes AI response |
close_vault |
Reclaim unused lamports |
- Created and owned by the oracle
- Represents a conversation session
["response", user_pubkey]
Stores the AI-generated response string.
["vault", response_pubkey]
Used to:
- fund dynamic resizing
- pay rent during callbacks
- safely reclaim unused lamports
AI responses are variable-length.
Instead of:
- guessing max size
- over-allocating rent
- recreating accounts
This design:
- starts small
- resizes only when needed
- uses a vault PDA as a controlled lamport buffer
Callbacks enforce:
- oracle identity must sign
- PDA seeds must match
- only the oracle can write AI responses
Spoofed callbacks are impossible.
The frontend is not a backend proxy.
It:
- constructs instructions
- signs transactions
- polls on-chain state
- renders chat UI
Handles:
- message submission
- transaction sending
- polling for AI responses
- retrying unfetched responses
- syncing local + on-chain state
This hook is the bridge between UX and Solana.
Since inference is async:
- Transaction is sent
- UI enters loading state
- Client polls response PDA
- AI response appears when finalized
- Fallback stores unfetched PDAs in
localStorage
This allows:
- page refresh recovery
- wallet disconnect recovery
- deterministic UX
Chat history is stored in localStorage:
- chat metadata
- last messages
- last AI response (for deduplication)
On reload:
- frontend rehydrates state
- continues polling if needed
User types message
↓
Frontend builds ai_inference instruction
↓
Wallet signs transaction
↓
Oracle executes LLM inference
↓
Oracle calls callback_from_ai
↓
Response PDA updated
↓
Frontend polls + renders AI response
Optional cleanup:
User calls close_vault
↓
Vault lamports returned
This project proves you can build:
- On-chain AI agents
- Verifiable inference pipelines
- Asynchronous oracle workflows
- No-backend AI apps
- Recoverable UX despite async execution
It’s especially useful for:
- AI-powered dApps
- autonomous agents
- DAO copilots
- trust-minimized assistants
- on-chain coordination tools
pnpm installanchor buildanchor deploypnpm dev- Solana Devnet
- LLM Oracle program
- Anchor framework
- Next.js App Router