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 directory | Source files |
|---|---|
nextjs | 14 |
relayer | 1 |
✅ 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)
- Rust:
rustc 1.99.1 (58cf8f9c3 2026-10-13) - Solana CLI (Agave):
solana-cli 1.18.17 (src:c027cfc3; feat:4215500110, client:Agave) - Node.js:
v24.22.1 - npm:
11.21.1 - pnpm:
10.34.6
2. Clone at the tested commit
git clone https://github.com/Blockchains/stealthfolio.git && cd stealthfolio
git checkout 7781de14155a013f6b66dac7d008f1750fa50fa73. Configure
The repo reads these environment variables. Copy the example file and fill in your own values. Never commit real keys.
nextjs/.env.template:RPC,SECRET_KEY,SOLANA_ENDPOINT,METIS_ENDPOINT
Fixes we had to apply to the pinned commit before it would build or run, with the reason for each:
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
| Directory | Command | Result | Time |
|---|---|---|---|
. | npm install --no-audit --no-fund --legacy-peer-deps | ✅ pass | 1s |
nextjs | npm install --no-audit --no-fund --legacy-peer-deps | ✅ pass | 339s |
relayer | npm install --no-audit --no-fund --legacy-peer-deps | ✅ pass | 1s |
5. Build
| Directory | Command | Result | Time |
|---|---|---|---|
nextjs | npm run build | ✅ pass | 18s |
relayer | npm run build | ✅ pass | 151s |
7. Deploy to a local validator
8. Run and exercise it
| Directory | Command | Result | Time |
|---|---|---|---|
nextjs | bash /workspace/sol-college/repo/tests/serve_probe.sh 3101 / npx next start -p 3101 | ✅ pass | 3s |
Mainnet (your own wallet, at your own risk)
- Use a dedicated wallet, and fund it with only a small amount.
- Set the RPC env var to a mainnet endpoint you control (
https://api.mainnet-beta.solana.comis rate-limited). - Build and start the app exactly as above, then connect the wallet in the browser.
- Simulate first: check the amounts, recipients and programs your wallet shows before you sign.
Extend it
- Add an integration test that runs the main flow end to end and asserts every account state change.
- Add a negative test: call each instruction with the wrong signer or account and check that it fails.
- Make the frontend read the cluster from an env var, deploy it to GitHub Pages and point it at your devnet program.
- 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.
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, {- Line 190
} = await connection.getLatestBlockhashAndContext();: Fetches a recent blockhash. Transactions expire if it gets too old. - Line 192
const signature = await sendTransaction(transactions[0], connection, {: Submits the signed transaction to the cluster.
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)- Line 209
} = await connection.getLatestBlockhashAndContext();: Fetches a recent blockhash. Transactions expire if it gets too old. - 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.
| Directory | Command | Runs |
|---|---|---|
relayer | npm run dev | npx nodemon src/app.ts |
relayer | npm run start | node dist/app.js |
relayer | npm run build | npm install && npx tsc |
nextjs | npm run dev | next dev |
nextjs | npm run start | next start |
nextjs | npm run build | next build |
nextjs | npm run lint | next lint |
What you could build from it
- Fork the SuperStack copy and extend it within the DeFi gaps listed on the idea page.
- Learn the pattern first: Program Derived Addresses (PDAs)
- Learn the pattern first: Cross-Program Invocations (CPIs)
- Learn the pattern first: SPL Tokens: mints, accounts and transfers