Build a simple Node.js crypto portfolio checker with CoinMarketCap data, sample holding values and price-alert rules - no API key required.
A first crypto app does not need authentication, a database or a user interface. It needs a working data loop.
This tutorial builds a small Node.js portfolio checker that retrieves CMC market data through Trial Pro API, calculates sample holding values and checks sample price-alert rules.
Use Node.js 18 or later so fetch is available without an added dependency.
Step 1: Create The Project
mkdir cmc-keyless-portfoliocd cmc-keyless-portfoliotouch app.js
Step 2: Add The Complete Script
const API_URL = "https://pro-api.coinmarketcap.com/trial-pro-api/v1/cryptocurrency/listings/latest";
const WATCHLIST = {
BTC: { cmcId: 1, amount: 0.05, alertAbove: 120000 },
ETH: { cmcId: 1027, amount: 1.2, alertAbove: 6000 },
SOL: { cmcId: 5426, amount: 15, alertBelow: 100 },
};
async function fetchListings() {
const params = new URLSearchParams({
start: "1",
limit: "100",
convert: "USD",
});
const response = await }`, {
headers: { Accept: "application/json" },
});
if (!response.ok) {
throw new Error(`Request failed: ${response.status} ${response.statusText}`);
}
const json = await response.json();
if (json.status?.error_code !== 0) {
throw new Error(json.status?.error_message || "CoinMarketCap API error");
}
return json.data;
}
function buildPortfolioRows(listings) {
return Object.entries(WATCHLIST).map(([symbol, config]) => {
const asset = listings.find((coin) => coin.id === config.cmcId);
const quote = asset?.quote?.USD;
if (!asset || !quote) { return { symbol, found: false };
}
return {
symbol,
name: asset.name,
rank: asset.cmc_rank,
amount: config.amount,
price: quote.price,
value: quote.price * config.amount,
change24h: quote.percent_change_24h,
alertAbove: config.alertAbove,
alertBelow: config.alertBelow,
found: true,
};
});
}
function formatUsd(value) {
return new Intl.NumberFormat("en-US", {
style: "currency", currency: "USD",
maximumFractionDigits: 2,
}).format(value);
}
function formatPercent(value) {
return typeof value === "number" ? `${value.toFixed(2)}%` : "n/a";
}
function printDashboard(rows) {
let total = 0;
console.log("\nCMC Keyless Portfolio Prototype\n");
for (const row of rows) { if (!row.found) {
console.log(`${row.symbol}: not found in returned listings`);
continue;
}
total += row.value;
console.log(
[
`${row.symbol} (${row.name})`,
`Rank #${row.rank}`,
`Price: ${formatUsd(row.price)}`,
`24h: ${formatPercent(row.change24h)}`,
`Holding: ${row.amount}`,
`Value: ${formatUsd(row.value)}`,
].join(" | ")
);
if (row.alertAbove && row.price >= row.alertAbove) {
console.log(` Alert: ${row.symbol} is above
${formatUsd(row.alertAbove)}`);
}
if (row.alertBelow && row.price <= row.alertBelow) {
console.log(` Alert: ${row.symbol} is below ${formatUsd(row.alertBelow)}`);
}
}
console.log(`\nTotal sample value: ${formatUsd(total)}\n`);}async function main() {
try {
const listings = await fetchListings();
const rows = buildPortfolioRows(listings);
printDashboard(rows);
} catch (error) {
console.error("Request failed:", error.message);
process.exit(1);
}
}
main();
Step 3: Run The App
node app.js
The script retrieves a listings response, finds BTC, ETH and SOL by their CMC IDs, calculates a sample portfolio value and evaluates test alert levels.
Why Use CMC IDs
Symbols are readable, but they are not always unique and can change after rebrands. CoinMarketCap recommends identifier-based API workflows. This prototype uses CMC IDs in the application logic while keeping symbols for display.
The tutorial uses a broad listings response because it is easy to understand in a first build. A stronger production workflow should resolve stored assets and request targeted quotes rather than assuming every tracked asset appears inside a listings window.
What The Prototype Proves
With one file, the developer can test:
- retrieving selected live CMC data without an API key
- mapping saved assets through CMC IDs
- calculating holding value
- displaying percentage movement
- evaluating application-owned alert rules
What To Build Next
A later version may add:
- stored portfolios or watchlists
- targeted quote requests for saved CMC IDs
- scheduled refresh jobs
- push, email or webhook alert delivery
- historical charts on a plan supporting history
- authenticated CMC API access for ongoing product use
Where The Prototype Ends
This script is not a production portfolio system. It does not store holdings or deliver notifications. It validates the first data loop.
