See every market move before it happens.
NinjaScope is a powerful REST API that transforms Injective's raw on-chain data into developer-ready intelligence. It aggregates markets, computes real-time analytics, ranks market health, detects whale activity, and profiles wallets β all through 20 clean JSON endpoints with automatic caching and interactive Swagger docs.
Built for the Ninja API Forge hackathon.
Building on Injective means dealing with:
- Complex gRPC/protobuf protocols β not developer-friendly
- Raw decimal formats β prices like
0.000000000003078instead of$3.078 - Scattered data across multiple indexer APIs β spot, derivatives, oracle, accounts
- No computed analytics β no health scores, no whale detection, no market rankings
NinjaScope wraps all of this into one simple API:
# Before: Deal with gRPC, protobuf, decimal math, multiple API clients...
# After:
curl http://localhost:3000/api/v1/markets/ticker/INJ-USDTReturns clean, structured JSON with human-readable prices β ready for trading bots, dashboards, or DeFi apps.
| Track | What NinjaScope Delivers |
|---|---|
| Data Aggregation | 200+ markets, orderbooks, trades, oracle prices, wallet portfolios β all normalized to JSON with human-readable prices |
| Computed / Derived Data | Spread analysis, orderbook depth, volatility, composite health scores (0-100), market rankings, whale trade detection |
| Developer Utility | Ticker-based lookup (no hex hashes), multi-market compare, all-in-one snapshots, intelligent caching, Swagger docs |
git clone https://github.com/anhfactor/ninja-scope.git
cd ninja-scope
npm install
cp .env.example .env
npm startAPI: http://localhost:3000/api/v1 | Docs: http://localhost:3000/docs
Base URL: http://localhost:3000/api/v1
| Method | Endpoint | Description |
|---|---|---|
GET |
/markets |
All spot + derivative markets (~200 on mainnet) |
GET |
/markets/ticker/:ticker |
Lookup by human-readable ticker (INJ-USDT, ?type=derivative) |
GET |
/markets/:marketId |
Single market detail with token metadata |
GET |
/markets/:marketId/orderbook |
Full orderbook with human-readable prices & quantities |
GET |
/markets/:marketId/trades |
Recent trades with pagination (?limit=20&skip=0) |
GET |
/oracle/prices |
All oracle price feeds (?symbol=INJ to filter) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/markets/:marketId/spread |
Bid-ask spread, spread %, mid price |
GET |
/markets/:marketId/depth |
Orderbook depth at 1%, 2%, 5%, 10% price levels |
GET |
/markets/:marketId/volatility |
Volatility via log-return standard deviation |
GET |
/markets/:marketId/health |
Composite health score (0-100) with component breakdown |
GET |
/markets/:marketId/funding |
Funding rate history (derivatives only) |
| Method | Endpoint | Description |
|---|---|---|
GET |
/markets/rankings |
Rank all markets by health, spread, or depth |
GET |
/markets/compare?ids=X,Y |
Side-by-side comparison of up to 5 markets |
GET |
/markets/:marketId/whales |
Detect large trades (auto top-10% or custom ?minValue=) |
GET |
/markets/:marketId/snapshot |
All-in-one: market + orderbook + trades + health + spread |
| Method | Endpoint | Description |
|---|---|---|
GET |
/accounts/:address/portfolio |
Bank balances, subaccounts, open position count |
GET |
/accounts/:address/positions |
Open derivative positions with unrealized PnL |
| Method | Endpoint | Description |
|---|---|---|
GET |
/markets/summary |
Aggregated stats across all markets |
GET |
/markets/search?q= |
Search by ticker, base/quote denom, or symbol |
GET |
/status |
API health, cache hit rate, uptime |
Interactive Docs: Visit
http://localhost:3000/docsfor full Swagger UI
For derivatives, add ?type=derivative:
curl 'http://localhost:3000/api/v1/markets/ticker/BTC-USDT?type=derivative'
# β { ticker: "BTC/USDT PERP", type: "derivative", ... }Raw Injective prices like 0.000000000002990 are automatically converted to $2.99:
Health is computed from 3 weighted factors: spread tightness (40%), orderbook depth (30%), and recent trade activity (30%).
Automatically surfaces the top 10% of trades by notional value:
Get everything about a market in one API call β perfect for dashboards:
curl 'http://localhost:3000/api/v1/markets/compare?ids=0xa508cb...,0x9b9980...'Returns spread, depth, health, and volatility for each market in parallel β great for building comparison tools or arbitrage bots.
# Search by keyword
curl 'http://localhost:3000/api/v1/markets/search?q=btc'
# Filter by market type
curl 'http://localhost:3000/api/v1/markets?type=spot'
# Orderbook depth analysis
curl 'http://localhost:3000/api/v1/markets/0xa508cb.../depth'
# Funding rates (derivatives)
curl 'http://localhost:3000/api/v1/markets/0x9b9980.../funding'
# Open derivative positions for a wallet
curl 'http://localhost:3000/api/v1/accounts/inj1.../positions'
# API status & cache hit rate
curl 'http://localhost:3000/api/v1/status'Every endpoint returns a consistent JSON envelope:
{
"success": true,
"data": { "..." },
"meta": {
"cached": true,
"timestamp": "2026-02-13T04:35:04.762Z",
"took_ms": 0
}
}meta.cachedβtrueif served from cache,falseif fetched fresh from Injectivemeta.took_msβ response time (cached responses are near-instant at 0ms)- Error responses include a structured
error.code+error.message
| Decision | Why |
|---|---|
| Human-readable prices | Orderbooks and trades include humanPrice / humanQuantity β converts 0.000000000002990 β $2.99 using token decimals |
| Ticker-based lookup | /markets/ticker/INJ-USDT instead of memorizing 0xa508cb... hex hashes |
| Intelligent caching | Per-type TTLs: 5s orderbook, 10s trades, 30s analytics. meta.cached tells clients if data is fresh |
| Composite health score | Weighted formula: spread (40%) + depth (30%) + activity (30%) β 0-100 score with letter rating |
| Auto whale detection | Automatically finds top 10% trades by notional value β or use a custom ?minValue= threshold |
| One-call snapshots | /snapshot endpoint aggregates market + orderbook + trades + health + spread in a single request |
| Graceful shutdown | SIGINT/SIGTERM handlers for clean process management |
NinjaScope uses the official Injective TypeScript SDK (@injectivelabs/sdk-ts):
| SDK Client | Used For |
|---|---|
IndexerGrpcSpotApi |
Spot markets, orderbooks, trades |
IndexerGrpcDerivativesApi |
Derivative markets, orderbooks, trades, funding rates, positions |
IndexerGrpcOracleApi |
Oracle price feeds |
IndexerGrpcAccountPortfolioApi |
Wallet portfolio, bank balances, subaccounts |
All data is fetched from Injective mainnet by default (configurable via .env).
src/
βββ index.ts # Fastify entry point + graceful shutdown
βββ config.ts # Network, port, cache TTL configuration
βββ plugins/
β βββ swagger.ts # OpenAPI/Swagger docs setup
β βββ cache.ts # In-memory cache layer with hit tracking
βββ services/
β βββ injective.ts # SDK client singleton
β βββ markets.ts # Market data, ticker lookup, decimal info
β βββ orderbook.ts # Orderbook + human-readable price conversion
β βββ trades.ts # Trade history + human-readable prices
β βββ oracle.ts # Oracle price feeds
β βββ analytics.ts # Spread, depth, volatility, health, rankings, whales, snapshots
β βββ account.ts # Wallet portfolio + derivative positions
βββ routes/
β βββ markets.ts # Market data + analytics + rankings (18 endpoints)
β βββ oracle.ts # Oracle routes (1 endpoint)
β βββ account.ts # Wallet routes (2 endpoints)
β βββ status.ts # Status route (1 endpoint)
βββ utils/
βββ decimals.ts # Spot/derivative decimal conversion utilities
βββ response.ts # Standardized response wrapper
| Component | Technology |
|---|---|
| Runtime | Node.js + TypeScript |
| Framework | Fastify (high-performance Node.js web framework) |
| Data Source | @injectivelabs/sdk-ts (official Injective SDK) |
| Caching | node-cache (in-memory with TTL) |
| API Docs | @fastify/swagger + Swagger UI |
Edit .env to configure:
# Network: mainnet or testnet
NETWORK=mainnet
# Server
PORT=3000
HOST=0.0.0.0npm run devMIT