Introduction
Kamino Finance dominates Solana lending.
With over $3.5 billion in TVL and a modular two-layer structure — a permissionless Market Layer and a curator-managed Vault Layer — Kamino has grow to be the foundational yield infrastructure on Solana. Knowledgeable curators like Gauntlet, Steakhouse Monetary, and Allez Labs handle vaults throughout danger tiers: Conservative, Balanced, and Aggressive. Customers deposit as soon as and let the protocol rebalance routinely.
The problem for builders shouldn’t be execution. It’s realizing which property and markets are value monitoring earlier than allocating capital.
CoinMarketCap API solves that. It offers you a structured knowledge layer to uncover vault-relevant property, monitor TVL and value momentum, validate DEX pool liquidity, and apply macro regime filters — all earlier than you work together with any Kamino vault on-chain.
On this information, you’ll construct a Kamino Finance Yield Vault Tracker with CoinMarketCap API, the place:
- CoinMarketCap API powers the sign engine
- Kamino SDK and Solana RPC deal with on-chain vault state validation
Why Use CoinMarketCap API for a Kamino Yield Vault Tracker?
Kamino offers you yield automation. CoinMarketCap offers you market context.
As a substitute of blindly depositing into vaults, you need to use CoinMarketCap to:
- uncover KMNO and vault-relevant property with their Solana contract addresses
- monitor TVL and value momentum throughout Kamino ecosystem tokens
- validate DEX pool liquidity for property in goal vaults
- detect whale transaction circulation on Raydium and Orca swimming pools
- apply macro regime filters earlier than deploying capital
- establish trending DeFi property producing yield rotation on Solana
This turns your tracker from a deposit dashboard into a decision-making system.
System Structure
CoinMarketCap API (Sign Layer)
├─ Asset Discovery (KMNO, vault property, SPL addresses)
├─ TVL + Value Context (quotes, momentum, tvl_ratio)
├─ DEX Pool Validation (liquidity, LP burn/lock)
├─ Transaction Movement (whale detection)
├─ Sub-minute Candles (momentum)
└─ Macro Regime (concern/greed, altcoin season)
↓
Yield Sign Engine
↓
Kamino SDK / Solana RPC (Validation Layer)
↓
Vault APY + On-chain State Verification
Structure Clarification
The CoinMarketCap API acts strictly as an off-chain Sign Layer for Kamino vault asset discovery, yield context monitoring, and lending market regime detection. It isn’t an on-chain yield oracle or vault state engine.
Actual vault APYs, utilization charges, borrow/provide charges, liquidation thresholds, and kToken NAV have to be validated straight on-chain through Kamino’s SDK or Solana RPC. CMC knowledge displays market circumstances with cache delays and doesn’t monitor particular person vault allocations, curator rebalancing occasions, or Kamino’s inner danger parameters.
Undertaking Setup
Python Dependencies
import os
import time
import requests
import pandas as pd
import numpy as np
Setting Variables
CMC_API_KEY = os.getenv(“CMC_API_KEY”)
CMC_BASE_URL = “https://pro-api.coinmarketcap.com”
HEADERS = {
“Settle for”: “utility/json”,
“Content material-Kind”: “utility/json”,
“X-CMC_PRO_API_KEY”: CMC_API_KEY,
}
Goal Property
# Core property to monitor throughout Kamino vaults
KAMINO_ASSETS = [“KMNO”, “USDC”, “SOL”, “USDT”, “JitoSOL”, “mSOL”]
# DEX slugs for Kamino-relevant swimming pools on Solana
# Notice: “meteora” returns 400 — the right slug is “meteora-dlmm”
SOLANA_DEX_SLUGS = [“raydium”, “orca”, “meteora-dlmm”]
Step 1: Map Property to CoinMarketCap IDs
Resolve all tracked property to their CoinMarketCap IDs. Use IDs — not symbols — for all subsequent Core API calls. Symbols are ambiguous.
Endpoint
GET /v1/cryptocurrency/map
def map_assets(symbols=”KMNO,USDC,SOL,USDT”):
url = f”{CMC_BASE_URL}/v1/cryptocurrency/map”
params = {“image”: symbols}
r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()
return r.json()[“data”]
From every asset object, extract:
- id — use for all Core API calls
- platform.token_address — SPL mint tackle on Solana
- image
Notice: /v1/cryptocurrency/map doesn’t help filtering by chain natively. Filter domestically by platform.identify == “Solana” after fetching outcomes.
kTokens notice: Kamino kTokens (vault shares like kSOL, kUSDC) are protocol-internal SPL tokens. They don’t seem to be listed within the CMC DEX API until they’ve energetic secondary swimming pools on Raydium or Orca. Monitor the underlying property (SOL, USDC) for market indicators fairly than kTokens straight.
Step 2: Fetch Quotes and TVL Context
Pull market knowledge and TVL for all tracked property. That is the bottom layer for yield rotation indicators.
Endpoint
GET /v3/cryptocurrency/quotes/newest
def fetch_quotes(ids):
url = f”{CMC_BASE_URL}/v3/cryptocurrency/quotes/newest”
params = {“id”: “,”.be a part of(str(i) for i in ids)}
r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()
return r.json()[“data”]
Within the V3 API, quote is a checklist, not a dict. Use subsequent() to extract the USD entry:
def parse_quote(asset):
# quote is a LIST in v3 — use subsequent() to discover USD entry by image
usd = subsequent(
(q for q in asset.get(“quote”, []) if q.get(“image”) == “USD”),
{}
)
return {
“id”: asset.get(“id”),
“image”: asset.get(“image”),
“value”: usd.get(“value”),
“volume_24h”: usd.get(“volume_24h”),
“market_cap”: usd.get(“market_cap”),
“fdv”: usd.get(“fully_diluted_market_cap”),
“pct_change_1h”: usd.get(“percent_change_1h”),
“pct_change_24h”: usd.get(“percent_change_24h”),
“pct_change_7d”: usd.get(“percent_change_7d”),
“tvl”: usd.get(“tvl”), # lives inside quote -> USD
“tvl_ratio”: asset.get(“tvl_ratio”), # lives at asset root}
tvl lives inside quote -> USD. tvl_ratio lives on the asset root. Each could return null — at all times parse defensively. For KMNO and main Kamino vault property, TVL is usually populated given Kamino’s scale, however deal with nulls as anticipated conduct beneath community load.
The info discipline is a checklist. Build the lookup dict by iterating:
# raw_quotes is a checklist — construct dict keyed by string ID
quotes = {str(a[“id”]): parse_quote(a) for a in raw_quotes}
Step 3: Rating Property for Yield Rotation
Rank property by yield rotation indicators earlier than checking vault availability.
def compute_yield_score(quote):
rating = 0
# TVL sign — excessive TVL signifies protocol confidence
tvl = quote.get(“tvl”) or 0
if tvl > 500_000_000: rating += 30
elif tvl > 50_000_000: rating += 15
# Momentum — rising value suggests energetic capital rotation
pct_24h = quote.get(“pct_change_24h”) or 0
if pct_24h > 5: rating += 25
elif pct_24h > 2: rating += 15
elif pct_24h < -10: rating -= 20
# Quantity — excessive quantity indicators energetic market
vol = quote.get(“volume_24h”) or 0
if vol > 50_000_000: rating += 25
elif vol > 10_000_000: rating += 10
# TVL ratio — value relative to TVL
tvl_ratio = quote.get(“tvl_ratio”) or 0
if 0 < tvl_ratio < 1: rating += 20 # undervalued relative to TVL
return rating
Step 4: Validate DEX Pool Liquidity
Verify that enough on-chain liquidity exists earlier than treating a sign as actionable.
Endpoint
GET /v1/dex/token/swimming pools
def fetch_token_pools(token_address):
url = f”{CMC_BASE_URL}/v1/dex/token/swimming pools”
params = {
“tackle”: token_address,
“platform”: “solana”
}r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()return r.json()[“data”]
Key fields per pool:
- exn — DEX identify (Raydium, Orca, Meteora)
- liqUsd – liquidity in USD
- v24 – 24h quantity
- addr – pool tackle
- pubAt – pool creation timestamp
- lr – locked fee, share of LP locked
- br – burned fee, share of LP burned
Notice: lr and br are documented as accessible for Solana swimming pools however are regularly absent in stay knowledge. Don’t depend on them as a sign. Use liqUsd and v24 as the first pool high quality indicators. For LP lock validation, question the pool contract straight on-chain.
def get_best_pool(swimming pools, min_liquidity=100_000):
legitimate = [
p for p in poolsif (p.get(“liqUsd”) or 0) >= min_liquidity
]
return max(legitimate, key=lambda p: p.get(“liqUsd”, 0)) if legitimate else None
Step 5: Get Pool-Stage Value and Reserves
Fetch exact pool-level pricing for execution context.
Endpoint
GET /v4/dex/pairs/quotes/newest
def fetch_pool_quote(pool_address, network_slug=”solana”):
url = f”{CMC_BASE_URL}/v4/dex/pairs/quotes/newest”
params = {
“network_slug”: network_slug, # required — disambiguates contracts throughout chains
“contract_address”: pool_address,
“aux”: “pool_base_asset,pool_quote_asset,buy_tax,sell_tax”}
r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()return r.json()[“data”]
network_slug is required alongside contract_address. Omitting it returns a 400 error.
Cache Warning: This endpoint has a ~60s cache. For deposit choices, validate vault state straight on-chain through Kamino SDK or Solana RPC instantly earlier than submitting any transaction.
Step 6: Uncover Lively Pairs on Solana DEXs
Discover energetic buying and selling pairs for vault-relevant property throughout Raydium, Orca, and Meteora.
Endpoint
GET /v4/dex/spot-pairs/newest
dex_slug is required alongside network_slug. Passing solely network_slug returns a 400 error. Make one request per DEX:
def fetch_pairs_for_dex(dex_slug, network_slug=”solana”):
url = f”{CMC_BASE_URL}/v4/dex/spot-pairs/newest”
params = {
“network_slug”: network_slug,
“dex_slug”: dex_slug,
“kind”: “liquidity”,
“sort_dir”: “desc”
}r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()
return r.json()[“data”]
def fetch_all_solana_pairs(asset_symbol):
outcomes = {}
for dex in SOLANA_DEX_SLUGS:
strive:
pairs = fetch_pairs_for_dex(dex)
matched = [
p for p in pairs
if asset_symbol.upper() in (
p.get(“base_asset_symbol”, “”).upper(),
p.get(“quote_asset_symbol”, “”).upper()
)
]
if matched:
outcomes[dex] = matched[0]
besides Exception:
proceed
return outcomes
Value, liquidity, and quantity stay contained in the quote array. Filter by convert_id == “2781” for USD values:
def parse_pair_quote(pair):
quotes = pair.get(“quote”, [])
usd = subsequent(
(q for q in quotes if str(q.get(“convert_id”)) == “2781”), {}
)
return {
“dex”: pair.get(“dex_slug”),
“value”: usd.get(“value”),
“liquidity”: usd.get(“liquidity”),
“volume_24h”: usd.get(“volume_24h”),
}
Step 7: Monitor On-Chain Transaction Movement
Monitor whale-level exercise to detect institutional rotation into or out of vault property.
Endpoint
GET /v1/dex/tokens/transactions
def fetch_transactions(token_address, min_volume=50_000):
url = f”{CMC_BASE_URL}/v1/dex/tokens/transactions”
params = {
“tackle”: token_address,
“platform”: “solana”, # “solana” solely — “sol” returns 400
“minVolume”: min_volume
}r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()return r.json()[“data”]
Returns uncooked swap data. Key fields per report: tx (hash), v (quantity USD), t0a (base asset), t1a (quote asset). Massive inflows into USDC or SOL swimming pools usually precede vault deposit surges on Kamino.
Step 8: Sub-Minute Momentum Detection
Monitor quick value actions on vault property to detect entry timing indicators.
Endpoint
GET /v1/k-line/candles
def fetch_candles(token_address, interval=”1min”):
url = f”{CMC_BASE_URL}/v1/k-line/candles”
params = {
“platform”: “solana”,
“tackle”: token_address,
“interval”: interval # 1s, 5s, 30s, 1min, 3min}
r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()return r.json()[“data”]
Every candle is a positional array of seven components — not a dict:
Index
Discipline
[0]
open
[1]
excessive
[2]
low
[3]
shut
[4]
quantity
[5]
timestamp, UNIX seconds
[6]
merchants, distinctive dealer depend
Don’t name .get() on a candle. Use parse_candle() to convert:
def parse_candle(c):
return {
“open”: c[0],
“excessive”: c[1],
“low”: c[2],
“shut”: c[3],
“quantity”: c[4],
“timestamp”: c[5],
“merchants”: c[6],
}
Notice: /v4/dex/pairs/ohlcv/historic returns 500 in manufacturing. Use /v1/k-line/candles for all DEX candle and historic knowledge on Solana.
Step 9: Apply Macro Regime Filters
Yield rotation is extra dependable in risk-on macro circumstances. Filter out antagonistic regimes earlier than flagging vault alternatives.
Endpoints
GET /v3/fear-and-greed/newest
GET /v1/altcoin-season-index/newest
def fetch_macro_regime():
fg_url = f”{CMC_BASE_URL}/v3/fear-and-greed/newest”
as_url = f”{CMC_BASE_URL}/v1/altcoin-season-index/newest”
fg = requests.get(fg_url, headers=HEADERS).json()[“data”]
as_idx = requests.get(as_url, headers=HEADERS).json()[“data”]
return {
“fear_greed_value”: fg.get(“worth”),
“fear_greed_classification”: fg.get(“value_classification”),
“altcoin_index”: as_idx.get(“altcoin_index”),
}def is_regime_favorable(regime):
fg = regime.get(“fear_greed_value”) or 0
as_i = regime.get(“altcoin_index”) or 0# Keep away from excessive concern; desire Solana DeFi circumstances
return fg > 35 and as_i >= 40
Concern & Greed updates each quarter-hour. Altcoin Season Index: ≥75 indicators Altcoin Season, <25 indicators Bitcoin Season. Each endpoints can be found on the Primary plan.
Step 10: Uncover Trending DeFi Property
Determine which Solana DeFi and lending property are attracting probably the most quantity.
Trending Endpoints (Paid Solely)
GET /v1/dex/tokens/trending/checklist (POST)
Paid Endpoint Warning
Error Code: 1006 [API_KEY_PLAN_NOT_AUTHORIZED]
Message: “Your API Key subscription plan would not help this endpoint.”
Returns HTTP 403 on the Primary plan.
Primary Plan Fallback
def fetch_trending_defi():
url = f”{CMC_BASE_URL}/v3/cryptocurrency/listings/newest”
params = {
“kind”: “volume_24h”,
“sort_dir”: “desc”,
“restrict”: 200,
“tag”: “defi”, # accepted worth on Primary
“percent_change_24h_min”: 2,
“volume_24h_min”: 5_000_000,}
r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()return r.json()[“data”]
# Filter domestically for Solana / Kamino ecosystem property
KAMINO_TAGS = {“solana-ecosystem”, “lending”, “defi”, “yield-farming”}
def filter_kamino_relevant(property):outcomes = []
for asset in property:
tags = set(asset.get(“tags”) or [])
if tags & KAMINO_TAGS or asset.get(“image”) in KAMINO_ASSETS:
outcomes.append(asset)
return outcomes
The tag question parameter accepts “defi” on the Primary plan. Filter for Solana-ecosystem and lending tags domestically — don’t move “solana-ecosystem” or “lending” straight as question params.
Step 11: Liquidity High quality — CEX Quantity Proxy
Paid Endpoint Warning
/v2/cryptocurrency/market-pairs/newest returns HTTP 403 on the Primary plan.
Error Code: 1006 [API_KEY_PLAN_NOT_AUTHORIZED]
Regardless of documentation itemizing Primary as supported, stay testing confirms 403.
Primary Plan Fallback
def estimate_liquidity(quote):
quantity = quote.get(“volume_24h”) or 0mkt_cap = quote.get(“market_cap”) or 0
return {
“volume_24h”: quantity,
“market_cap”: mkt_cap,
“liquidity_signal”: “excessive” if quantity > 20_000_000else “medium” if quantity > 5_000_000
else “low”,
}
When you have a paid plan, use /v2/cryptocurrency/market-pairs/newest with aux=”effective_liquidity,market_score,market_reputation”. Depth fields at quote -> USD -> depth_negative_two are regularly null for DeFi tokens.
Step 12: Historic Backtesting
Paid Endpoint Warning
/v3/cryptocurrency/quotes/historic returns HTTP 403 on the Primary plan.
Regardless of documentation itemizing Primary as supported, any time-series request returns 403.
Backtesting requires a paid CMC plan.
Cache: 5 minutes. Value: 1 credit score per 100 datapoints.
def fetch_historical_quotes(asset_id, time_start, time_end, interval=”1h”):
url = f”{CMC_BASE_URL}/v3/cryptocurrency/quotes/historic”
params = {
“id”: asset_id,
“time_start”: time_start,
“time_end”: time_end,
“interval”: interval, # “1h”, “4h”, “day by day”}
r = requests.get(url, headers=HEADERS, params=params)
r.raise_for_status()return r.json()[“data”]
Use /v1/k-line/candles because the free different for DEX-level candle historical past on Solana.
Step 13: Minimal Finish-to-Finish Movement
def run_kamino_vault_tracker(asset_ids, asset_map):
# 1. Macro regime — ballot each 15 min
regime = fetch_macro_regime()# 2. Quotes — raw_quotes is a checklist, construct dict by id
raw_quotes = fetch_quotes(checklist(asset_ids.values()))
quotes = {str(a[“id”]): parse_quote(a) for a in raw_quotes}outcomes = []
for image, asset_id in asset_ids.gadgets():
quote = quotes.get(str(asset_id), {})# 3. Rating the asset
yield_score = compute_yield_score(quote)if yield_score < 30:
proceed
# 4. Pool validation
token_addr = asset_map.get(image, {}).get(“token_address”)if not token_addr:
proceed
strive:
swimming pools = fetch_token_pools(token_addr)
best_pool = get_best_pool(swimming pools)besides Exception:
proceed
if not best_pool:
proceed
# 5. Momentum verify
strive:
candles = fetch_candles(token_addr, interval=”5min”)
newest = candles[-1] if candles else None
merchants = newest[6] if newest and len(newest) > 6 else 0besides Exception:
merchants = 0
# 6. Regime filter
if not is_regime_favorable(regime):
yield_score -= 20
outcomes.append({“image”: image,
“yield_score”: yield_score,
“value”: quote.get(“value”),
“tvl”: quote.get(“tvl”),
“pct_24h”: quote.get(“pct_change_24h”),
“volume_24h”: quote.get(“volume_24h”),
“pool_liq”: best_pool.get(“liqUsd”),
“pool_dex”: best_pool.get(“exn”),
“traders_5min”: merchants,
})return sorted(outcomes, key=lambda x: -x[“yield_score”])
Go high-scoring property to your Kamino SDK layer for on-chain vault APY validation and deposit execution.
Fee Limits and Polling
CoinMarketCap API is REST-only. There isn’t a WebSocket streaming.
Cache Intervals
Endpoint Group
Cache Interval
Quotes, /v3/cryptocurrency/quotes/newest
60 seconds
DEX pairs, /v4/dex/spot-pairs/newest
60 seconds
Pool knowledge, /v1/dex/token/swimming pools
60 seconds
Candles, /v1/k-line/candles
60 seconds
Concern & Greed, Altcoin Season
quarter-hour
Historic quotes
5 minutes, paid plan solely
Finest Practices
- ballot each 60 seconds for all value and pool endpoints
- ballot macro endpoints each quarter-hour
- cache responses domestically between polls
- use exponential backoff for HTTP 429 errors, fee reset at 60 seconds
def request_with_backoff(fn, retries=3, base_delay=2):
for try in vary(retries):
strive:
return fn()
besides requests.exceptions.HTTPError as e:
if e.response.status_code == 429:
time.sleep(base_delay ** try)
else:
elevate
elevate Exception(“Max retries exceeded”)
Frequent Errors
Parsing quote as a dict in v3
In /v3/cryptocurrency/quotes/newest, quote is a checklist. Utilizing asset[“quote”][“USD”] raises an AttributeError. The proper sample is:
subsequent((q for q in asset.get(“quote”, []) if q.get(“image”) == “USD”), {})
Iterating raw_quotes as a dict
The info discipline from /v3/cryptocurrency/quotes/newest is a checklist. Build the lookup dict by iterating:
{str(a[“id”]): parse_quote(a) for a in raw_quotes}
Passing solely network_slug to /v4/dex/spot-pairs/newest
dex_slug is required. Omitting it returns a 400 error. Make one request per DEX slug.
Omitting network_slug from pool quotes
/v4/dex/pairs/quotes/newest requires network_slug alongside contract_address. Omitting it returns a 400 error.
Utilizing “sol” because the platform worth
/v1/dex/tokens/transactions solely accepts “solana”. The abbreviated “sol” returns 400.
Monitoring kTokens through the DEX API
Kamino kTokens are protocol-internal vault shares. They don’t seem to be listed within the CMC DEX API until they’ve energetic secondary swimming pools. Monitor the underlying property (SOL, USDC, and so forth.) for market indicators.
Assuming /v2/cryptocurrency/market-pairs/newest works on Primary
Returns 403 in apply. Use volume_24h from quotes as a liquidity proxy.
Assuming /v3/cryptocurrency/quotes/historic works on Primary
Returns 403 for any time-series request. Backtesting requires a paid plan. Use /v1/k-line/candles for DEX-level candle historical past.
Utilizing /v4/dex/pairs/ohlcv/historic
Returns 500 in manufacturing. Use /v1/k-line/candles for all DEX candle knowledge.
Calling .get() on candle arrays
Candles from /v1/k-line/candles are positional arrays. Use candle[6] for merchants — not candle.get(“merchants”).
Treating CMC as a vault state engine
CMC doesn’t monitor vault APYs, utilization charges, curator rebalancing, or kToken NAV. At all times validate vault state on-chain through Kamino SDK or Solana RPC earlier than any deposit.
Ultimate Ideas
Kamino has made yield on Solana institutional-grade. Curated vaults, risk-tiered methods, and automatic rebalancing take away the handbook overhead of managing DeFi positions.
CoinMarketCap API offers you the structured sign layer to resolve which property and market circumstances are value appearing on earlier than you work together with any vault on-chain.
The important thing separation:
- CoinMarketCap identifies which property and regimes are value monitoring
- Kamino SDK and Solana RPC validate vault state and execute deposits
Subsequent Steps
- add TVL progress fee monitoring to detect vaults gaining inflows
- set alerts for yield_score threshold breaches per asset
- combine Kamino SDK to pull stay vault APYs and utilization charges
- cross-reference CMC momentum indicators with on-chain borrow fee modifications
- monitor curator-managed vault rebalancing occasions through Solana RPC
- retailer snapshots domestically to construct rolling yield sign historical past over time











