Sol.College

Full lesson

stealthfolio

Bringing privacy to defi portfolio management

What it does

From the project README:

StealthFolio is a private swap management tool for traders and investers. Leveraging Solana, Jupiter and Light protocol to build fast swaps with the option to conceal identity on certain trades.
Original
SwineCoder101/stealthfolio
SuperStack fork
Blockchains/stealthfolio @ 7781de1
Stars
1
Last push (original)
2024-04-01
Languages
JavaScript, CSS, TypeScript
Detected stack
Next.jsweb3.js
Categories
DeFi
Licence
MIT
Homepage
https://stealthfolio-six.vercel.app

Architecture

15 source files. By extension: .js ×14, .ts ×1.

Top-level directorySource files
nextjs14
relayer1

✅ Operational, verified 2026-11-02 Tested on 2026-11-02: full log results.json ⚠️ Needs real funds to run on mainnet

High risk: this app moves real money on mainnet

Swaps run through Jupiter on mainnet with your own wallet; Jupiter has no devnet liquidity. We never connected a funded wallet, signed a mainnet transaction or spent real funds while testing it. If you run the mainnet steps below, use a fresh wallet holding only what you can afford to lose, read every transaction before you sign it, and start with tiny amounts. Unaudited hackathon code can lose funds.

Build it yourself: step-by-step guide

Every command below was run on 2026-11-02 by tests/run_fork.py against the pinned commit, and the results come from that run. The full output is in the committed log.

1. Prerequisites (versions we tested with)

2. Clone at the tested commit

git clone https://github.com/Blockchains/stealthfolio.git && cd stealthfolio
git checkout 7781de14155a013f6b66dac7d008f1750fa50fa7

3. Configure

The repo reads these environment variables. Copy the example file and fill in your own values. Never commit real keys.

Fixes we had to apply to the pinned commit before it would build or run, with the reason for each:

  1. cp nextjs/.env.template nextjs/.env.local && sed -i 's#^RPC=.*#RPC=https://api.devnet.solana.com#; s#^SOLANA_ENDPOINT=.*#SOLANA_ENDPOINT=https://api.devnet.solana.com#' nextjs/.env.local.

4. Install dependencies

DirectoryCommandResultTime
.npm install --no-audit --no-fund --legacy-peer-deps✅ pass1s
nextjsnpm install --no-audit --no-fund --legacy-peer-deps✅ pass339s
relayernpm install --no-audit --no-fund --legacy-peer-deps✅ pass1s

5. Build

DirectoryCommandResultTime
nextjsnpm run build✅ pass18s
relayernpm run build✅ pass151s

7. Deploy to a local validator

8. Run and exercise it

DirectoryCommandResultTime
nextjsbash /workspace/sol-college/repo/tests/serve_probe.sh 3101 / npx next start -p 3101✅ pass3s

Mainnet (your own wallet, at your own risk)

  1. Use a dedicated wallet, and fund it with only a small amount.
  2. Set the RPC env var to a mainnet endpoint you control (https://api.mainnet-beta.solana.com is rate-limited).
  3. Build and start the app exactly as above, then connect the wallet in the browser.
  4. Simulate first: check the amounts, recipients and programs your wallet shows before you sign.

Extend it

  1. Add an integration test that runs the main flow end to end and asserts every account state change.
  2. Add a negative test: call each instruction with the wrong signer or account and check that it fails.
  3. Make the frontend read the cluster from an env var, deploy it to GitHub Pages and point it at your devnet program.
  4. Wire the build into CI by copying this site's verify-forks workflow.

Key code, explained

Excerpts chosen automatically where the code uses the most Solana concepts, pinned to the fork's commit.

SwineCoder101/stealthfolio · nextjs/src/app/transact/page.js L169–192 @ 7781de1 · MIT · original
          portfolio.push({            id: rows[i].toToken,            vsToken: rows[i].fromToken,            amount: rows[i].sellAmount * 100000,          });        } else {          continue;        }      }      const pricedPortfolio = await pricePortfolio(portfolio);       const swapItems = pricedPortfolio;      console.log('SWAP ITEMS')      const transactions = await createSwapTransactions(        swapItems,        publicKey.toString()      );       const {        context: { slot: minContextSlot },        value: { blockhash, lastValidBlockHeight },      } = await connection.getLatestBlockhashAndContext();       const signature = await sendTransaction(transactions[0], connection, {
  1. Line 190 } = await connection.getLatestBlockhashAndContext();: Fetches a recent blockhash. Transactions expire if it gets too old.
  2. Line 192 const signature = await sendTransaction(transactions[0], connection, {: Submits the signed transaction to the cluster.
SwineCoder101/stealthfolio · nextjs/src/app/home/page.js L193–216 @ 7781de1 · MIT · original
      }    }    console.log(portfolio);    const pricedPortfolio = await pricePortfolio(portfolio);    console.log(pricedPortfolio);     const swapItems = pricedPortfolio;    console.log('swap items:', swapItems)    console.log('public key:', publicKey.toString())    const transactions = await createSwapTransactions(swapItems, publicKey.toString());    console.log('transactions', transactions);    // const signedTransactions = await signAllTransactions(transactions);       const {        context: { slot: minContextSlot },        value: { blockhash, lastValidBlockHeight },    } = await connection.getLatestBlockhashAndContext();      const signature = await sendTransaction(transactions[0], connection, { minContextSlot });    console.log(signature)    let confirmation = await connection.confirmTransaction({ blockhash, lastValidBlockHeight, signature });        console.log(confirmation)
  1. Line 209 } = await connection.getLatestBlockhashAndContext();: Fetches a recent blockhash. Transactions expire if it gets too old.
  2. Line 212 const signature = await sendTransaction(transactions[0], connection, { minContextSlot });: Submits the signed transaction to the cluster.

How to run, build and test

These commands come from the repo's own manifests (package.json scripts, Anchor.toml, Cargo, go.mod, Makefile). Check the README for prerequisites and environment variables.

DirectoryCommandRuns
relayernpm run devnpx nodemon src/app.ts
relayernpm run startnode dist/app.js
relayernpm run buildnpm install && npx tsc
nextjsnpm run devnext dev
nextjsnpm run startnext start
nextjsnpm run buildnext build
nextjsnpm run lintnext lint

What you could build from it