Features · Architecture · Technology stack · Local setup
Note
This project was created as the second project of the John Bryce Full Stack Web Developer course.
Cryptonite presents live data about the top 100 cryptocurrencies, draws real-time price reports, and provides AI-powered buying advice in one responsive single page application.
| 100 market assets |
5 tracked coins |
20 live readings |
1s browser updates |
AI market advice |
| Project detail | Implementation |
|---|---|
| Market coverage | Top 100 cryptocurrencies by market capitalization |
| Live reporting | Up to five selected coins with the latest 20 readings |
| State management | Redux Toolkit with persistent selections in localStorage |
| API security | Same-origin Vercel Functions keep Production secrets outside the browser bundle |
| Deployment | Vercel with SPA routing and protected API endpoints |
- Links
- Features
- Architecture
- Technologies
- Project structure
- APIs
- Running locally
- Vercel API setup
- Production build
- Author
| Resource | Link |
|---|---|
| Live application | cryptonite-amber.vercel.app |
| GitHub repository | itaygoldenberg/Cryptonite |
| Author | Itay Goldenberg on LinkedIn |
The application includes Home, Reports, AI Advice and About pages. The navbar also includes a case-insensitive coin search field.
The Home page displays the top 100 coins. Each card shows the coin image, symbol, name, a More Info button and a selection switch.
The search filters the already loaded list locally by coin name or symbol, so typing does not create additional API requests.
More Info displays the current price in USD, EUR and ILS. Details are loaded once per coin and then kept in the card state.
Users can select up to five coins for the Reports and AI Advice pages. Selecting a sixth coin opens a replacement dialog. The selected coin IDs are stored in localStorage, so the switches remain selected after the browser is reopened.
Reports displays one live chart containing all selected coins. The chart checks for new data once per second and keeps the latest twenty readings. CoinCap requests are batched for all selected coins, and saved readings remain visible after API failures.
The AI Advice page lists the selected coins. Each coin can be sent to the ChatGPT API with the following market fields:
name
current_price_usd
market_cap_usd
volume_24h_usd
price_change_percentage_30d_in_currency
price_change_percentage_60d_in_currency
price_change_percentage_200d_in_currency
The response contains a short recommendation and an explanation paragraph.
The About page includes project information, technologies, a personal photo and contact links.
Production secrets are read only by the Vercel Functions. They are not included in the React source, browser bundle, GitHub repository or submission ZIP.
React 19.2 |
TypeScript 6.0 |
Redux Toolkit 2.12 |
React Router 7.18 |
Axios 1.13 |
Recharts 3.10 |
Vite 8.1 |
CSS3 Responsive UI |
Vercel Functions Protected API layer |
Git Version control |
OpenAI API AI recommendations |
| Area | Technologies |
|---|---|
| Frontend | React 19, TypeScript 6, CSS |
| State and routing | Redux Toolkit, React Router |
| Data and visualization | Axios, Recharts |
| Tooling | Vite |
| Hosting and API layer | Vercel, Vercel Functions |
api/ Protected Vercel API routes
scripts/ Local API-key obfuscation helper
src/
|-- components/
| |-- coins-area/ CoinCard, SearchBox, LimitDialog
| |-- layout-area/ Layout, Header, Menu, Routing
| |-- pages-area/ Home, Reports, AiAdvice, About, Page404
|-- models/ CoinModel, CoinDetailsModel, AiAdviceModel
|-- redux/ coins-slice, selected-slice, search-slice, store
|-- services/ CoinService, AiService, LocalApiService
|-- utils/ AppConfig and local key decryption
vercel.json Production routing and SPA fallback
Redux stores the coin list, selected coins and search term globally so navigation between pages does not require another coin-list request.
![]() CoinGecko Market list, coin details and AI market inputs |
CoinCap Batched live USD prices for Reports |
OpenAI Recommendation and explanation generation |
| Purpose | Provider |
|---|---|
| Top 100 coins | CoinGecko /coins/markets |
| More Info details | CoinGecko /coins/{id} |
| AI market data | CoinGecko /coins/{id} |
| Live report prices | CoinCap /assets |
| AI recommendation | OpenAI /v1/chat/completions |
CoinCap is used for the live report and was approved as the project's real-time price provider. Prices are matched by symbol because CoinGecko and CoinCap use different coin ID formats.
Create a CoinCap API key from the CoinCap Pro Dashboard. For Production, store the raw key only as the COINCAP_API_KEY Vercel Environment Variable.
Clone the repository and install the dependencies:
git clone https://github.com/itaygoldenberg/Cryptonite.git
cd Cryptonite
npm installThe recommended local setup uses the same protected API architecture as Production. Install the Vercel CLI and run:
npm install -g vercel
vercel login
vercel devVercel prints the local URL, normally http://localhost:3000.
This optional workflow lets the evaluator run the complete app with npm start, without a .env file and without storing the original CoinCap or OpenAI key in the source code.
Warning
The generated enc: strings are reversible obfuscation for local evaluation. Never commit them, publish them or include them in a submission ZIP.
-
Generate the encrypted CoinCap value:
npm run encrypt:key -- CoinCap
When the terminal displays
Paste the API key:, paste the original CoinCap key and press Enter. The command prints a new value beginning withenc:. Copy that entire value, including theenc:prefix. -
Generate the encrypted OpenAI value:
npm run encrypt:key -- OpenAI
Paste the original OpenAI key at the prompt, press Enter, and copy the complete printed value beginning with
enc:. -
Open
src/utils/app-config.tsand find these exact placeholder lines:const ENCRYPTED_COINCAP_API_KEY = "enc: "; const ENCRYPTED_OPENAI_API_KEY = "enc: ";
-
Replace only the text between the quotation marks with the matching generated value. The result should look like this:
const ENCRYPTED_COINCAP_API_KEY = "enc:GENERATED_COINCAP_VALUE"; const ENCRYPTED_OPENAI_API_KEY = "enc:GENERATED_OPENAI_VALUE";
The command output already contains
enc:, so do not add a secondenc:prefix. Do not paste either original key directly intoapp-config.ts. -
Start the local application:
npm start
Vite opens the app at
http://localhost:5173. In Development mode, the application decrypts the two local values in theAppConfigconstructor and uses the restored keys for CoinCap Reports and OpenAI Advice. CoinGecko does not require a key. -
Before committing, publishing or creating a submission ZIP, restore both lines to
"enc: ". The generated strings are reversible obfuscation intended only for local evaluation; Production continues to use the protected Vercel Environment Variables.
The API runs in a Vercel Function. Production API keys are stored in Vercel Environment Variables and are never placed in React source code, the browser bundle, GitHub or the ZIP. Vercel uses raw server-side values, not the optional enc: values.
From the project root, connect the project and deploy:
vercelIn the Vercel dashboard, open Project Settings > Environment Variables and add these Production variables:
COINCAP_API_KEY
OPENAI_API_KEY
Enter the real values only in the Vercel dashboard. Do not use a VITE_ prefix for secret variables because VITE_ values are exposed to the browser.
Deploy again after adding the variables:
vercel --prodThe live API architecture is:
Browser -> same-origin /api Vercel Function -> CoinGecko/CoinCap/OpenAI
The Function caches CoinGecko and CoinCap responses and requests CoinCap at most once every five seconds for Reports. Vercel Hobby Functions are free within the plan limits. The Hobby plan is intended for personal, non-commercial projects.
npm run buildThe production files are generated in the dist folder. Do not include node_modules, .env, dist or .git in the submitted ZIP archive.
Itay Goldenberg
Full Stack Developer Student
Built as part of the John Bryce Full Stack Web Developer course.
