Skip to main content

Prerequisites

You’ll also need accounts for:
  • Privy — embedded Solana wallet + auth
  • Supabase — patterns, rules, events, and audit storage
  • A Solana RPC URL (Helius, Triton, QuickNode, or https://api.devnet.solana.com)
  • A Telegram bot token — for review notifications
  • Zerion — portfolio data

Install

This is a pnpm workspace. Run from the root:

Configure Environment

Create client/.env.local:
See backend/.env.example for the full template. Apply the Supabase schema once before first run:
SPONSOR_SECRET_KEY is the server’s Solana keypair as a JSON byte array. It fee-pays every transaction and is added to each vault as a member with Execute permission. NEXT_PUBLIC_SPONSOR_PUBKEY on the client must be its public address.

Run Locally

1

Start the server

2

Start the client

3

Link the Sage skill into Nanobot

Verify It Works

  1. Visit http://localhost:3000
  2. Sign in with Privy → an embedded Solana wallet is created
  3. A Squads multisig + vault is deployed for you (server-sponsored — no SOL needed)
  4. Fund the vault address, then go to Send → enter a recipient and amount
  5. Confirm → the transfer is sponsored, the proposal is registered with POST /queue, and the risk engine scores it
  6. APPROVE: the server co-signs and executes; the tx signature appears in the UI and Telegram
  7. REVIEW / BLOCK: check Telegram for the ✅ / ❌ / 🔎 message

Run the Tests

The Squads SDK helpers in src/ are covered by a Mocha suite:

Troubleshooting

Confirm SPONSOR_SECRET_KEY decodes to a valid keypair and the sponsor account holds enough SOL to pay rent. Check SOLANA_RPC_URL is reachable.
The risk engine needs the Supabase schema applied. Check server logs for getPatternsForSafe errors and confirm SUPABASE_SERVICE_ROLE_KEY is set.
Verify TELEGRAM_BOT_TOKEN is set, the bot has been started in your chat, and the vault has a telegram_chat_id (connect it from the app or /start the bot).
Portfolio data requires a valid ZERION_API_KEY in backend/.env.
Run nanobot skills check to confirm the Sage skill is detected and AGENT_SECRET matches the value in backend/.env.