Analytics Dashboard
Learn how to build powerful DeFi analytics dashboards using the Hoops Finance API. This guide shows you how to fetch platform metrics, pair statistics, and create visualizations for key DeFi insights.
Overview
This page covers:
- Fetching platform-wide metrics (TVL, volume, fees)
- Getting detailed pair statistics
- Sorting and filtering data for dashboards
- Basic visualization examples
Platform Metrics
Get Total TVL and Platform Fees
The /getmetrics
endpoint provides comprehensive platform-wide data.
- Python
- JavaScript
- TypeScript
- cURL
- Go
- Rust
- Java
- Shell
import requests
import json
def get_platform_metrics(period="24h"):
"""Fetch platform metrics for specified period"""
url = f"https://api.hoops.finance/getmetrics?period={period}"
response = requests.get(url)
response.raise_for_status()
return response.json()
# Usage
metrics = get_platform_metrics("24h")
print(f"Total TVL: ${metrics['tvl']:,.2f}")
print(f"24h Volume: ${metrics['volume24h']:,.2f}")
print(f"Total Fees: ${metrics['fees24h']:,.2f}")
print(f"Active Pairs: {metrics['activePairs']}")
async function getPlatformMetrics(period = '24h') {
try {
const response = await fetch(`https://api.hoops.finance/getmetrics?period=${period}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching metrics:', error.message);
throw error;
}
}
// Usage
getPlatformMetrics('24h').then(metrics => {
console.log(`Total TVL: $${metrics.tvl.toLocaleString()}`);
console.log(`24h Volume: $${metrics.volume24h.toLocaleString()}`);
console.log(`Total Fees: $${metrics.fees24h.toLocaleString()}`);
console.log(`Active Pairs: ${metrics.activePairs}`);
});
interface PlatformMetrics {
tvl: number;
volume24h: number;
fees24h: number;
activePairs: number;
}
async function getPlatformMetrics(period: string = '24h'): Promise<PlatformMetrics> {
try {
const response = await fetch(`https://api.hoops.finance/getmetrics?period=${period}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching metrics:', error);
throw error;
}
}
// Usage
getPlatformMetrics('24h').then(metrics => {
console.log(`Total TVL: $${metrics.tvl.toLocaleString()}`);
console.log(`24h Volume: $${metrics.volume24h.toLocaleString()}`);
console.log(`Total Fees: $${metrics.fees24h.toLocaleString()}`);
console.log(`Active Pairs: ${metrics.activePairs}`);
});
# Get platform metrics
curl -s "https://api.hoops.finance/getmetrics?period=24h" | jq '.'
# Extract specific values
TVL=$(curl -s "https://api.hoops.finance/getmetrics?period=24h" | jq -r '.tvl')
VOLUME=$(curl -s "https://api.hoops.finance/getmetrics?period=24h" | jq -r '.volume24h')
FEES=$(curl -s "https://api.hoops.finance/getmetrics?period=24h" | jq -r '.fees24h')
PAIRS=$(curl -s "https://api.hoops.finance/getmetrics?period=24h" | jq -r '.activePairs')
echo "Total TVL: \$${TVL}"
echo "24h Volume: \$${VOLUME}"
echo "Total Fees: \$${FEES}"
echo "Active Pairs: ${PAIRS}"
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type PlatformMetrics struct {
TVL float64 `json:"tvl"`
Volume24h float64 `json:"volume24h"`
Fees24h float64 `json:"fees24h"`
ActivePairs int `json:"activePairs"`
}
func getPlatformMetrics(period string) (*PlatformMetrics, error) {
url := fmt.Sprintf("https://api.hoops.finance/getmetrics?period=%s", period)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var metrics PlatformMetrics
err = json.Unmarshal(body, &metrics)
return &metrics, err
}
func main() {
metrics, err := getPlatformMetrics("24h")
if err != nil {
panic(err)
}
fmt.Printf("Total TVL: $%.2f\n", metrics.TVL)
fmt.Printf("24h Volume: $%.2f\n", metrics.Volume24h)
fmt.Printf("Total Fees: $%.2f\n", metrics.Fees24h)
fmt.Printf("Active Pairs: %d\n", metrics.ActivePairs)
}
use reqwest;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct PlatformMetrics {
tvl: f64,
volume24h: f64,
fees24h: f64,
active_pairs: i32,
}
async fn get_platform_metrics(period: &str) -> Result<PlatformMetrics, Box<dyn std::error::Error>> {
let url = format!("https://api.hoops.finance/getmetrics?period={}", period);
let response = reqwest::get(&url).await?;
let metrics: PlatformMetrics = response.json().await?;
Ok(metrics)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let metrics = get_platform_metrics("24h").await?;
println!("Total TVL: ${:.2}", metrics.tvl);
println!("24h Volume: ${:.2}", metrics.volume24h);
println!("Total Fees: ${:.2}", metrics.fees24h);
println!("Active Pairs: {}", metrics.active_pairs);
Ok(())
}
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
public class PlatformMetrics {
private double tvl;
private double volume24h;
private double fees24h;
private int activePairs;
// Getters and setters
public double getTvl() { return tvl; }
public void setTvl(double tvl) { this.tvl = tvl; }
public double getVolume24h() { return volume24h; }
public void setVolume24h(double volume24h) { this.volume24h = volume24h; }
public double getFees24h() { return fees24h; }
public void setFees24h(double fees24h) { this.fees24h = fees24h; }
public int getActivePairs() { return activePairs; }
public void setActivePairs(int activePairs) { this.activePairs = activePairs; }
}
public class HoopsApiClient {
private static final String BASE_URL = "https://api.hoops.finance";
private final HttpClient client = HttpClient.newHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
public PlatformMetrics getPlatformMetrics(String period) throws Exception {
String url = String.format("%s/getmetrics?period=%s", BASE_URL, period);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
return mapper.readValue(response.body(), PlatformMetrics.class);
}
public static void main(String[] args) throws Exception {
HoopsApiClient client = new HoopsApiClient();
PlatformMetrics metrics = client.getPlatformMetrics("24h");
System.out.printf("Total TVL: $%.2f%n", metrics.getTvl());
System.out.printf("24h Volume: $%.2f%n", metrics.getVolume24h());
System.out.printf("Total Fees: $%.2f%n", metrics.getFees24h());
System.out.printf("Active Pairs: %d%n", metrics.getActivePairs());
}
}
#!/bin/bash
BASE_URL="https://api.hoops.finance"
get_platform_metrics() {
local period=${1:-"24h"}
curl -s "${BASE_URL}/getmetrics?period=${period}" | jq '.'
}
# Usage
metrics=$(get_platform_metrics "24h")
tvl=$(echo "$metrics" | jq -r '.tvl')
volume=$(echo "$metrics" | jq -r '.volume24h')
fees=$(echo "$metrics" | jq -r '.fees24h')
pairs=$(echo "$metrics" | jq -r '.activePairs')
echo "Total TVL: \$${tvl}"
echo "24h Volume: \$${volume}"
echo "Total Fees: \$${fees}"
echo "Active Pairs: ${pairs}"
Use Case
Great for: Dashboard overview cards, portfolio tracking, and platform health monitoring
Response Fields Explained
Field | Description | Example |
---|---|---|
tvl | Total Value Locked across all pools | 1234567.89 |
volume24h | 24-hour trading volume | 987654.32 |
fees24h | 24-hour fee revenue | 1234.56 |
activePairs | Number of active liquidity pairs | 150 |
totalPairs | Total number of pairs | 200 |
Pair Statistics
Get All Pairs with Statistics
- Python
- JavaScript
- TypeScript
- cURL
- Go
- Rust
- Java
- Shell
def get_all_pairs_with_stats():
"""Fetch all pairs with their statistics"""
url = "https://api.hoops.finance/pairs"
response = requests.get(url)
response.raise_for_status()
return response.json()
def sort_pairs_by_volume(pairs, limit=10):
"""Sort pairs by 24h volume and return top pairs"""
sorted_pairs = sorted(pairs['pairs'],
key=lambda x: float(x.get('volume24h', 0)),
reverse=True)
return sorted_pairs[:limit]
# Usage
pairs = get_all_pairs_with_stats()
top_volume_pairs = sort_pairs_by_volume(pairs, 5)
for pair in top_volume_pairs:
print(f"{pair['token0Symbol']}/{pair['token1Symbol']}: "
f"${float(pair['volume24h']):,.2f} (24h volume)")
async function getAllPairsWithStats() {
try {
const response = await fetch('https://api.hoops.finance/pairs');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching pairs:', error.message);
throw error;
}
}
function sortPairsByVolume(pairs, limit = 10) {
return pairs.pairs
.sort((a, b) => parseFloat(b.volume24h || 0) - parseFloat(a.volume24h || 0))
.slice(0, limit);
}
// Usage
getAllPairsWithStats().then(data => {
const topPairs = sortPairsByVolume(data, 5);
topPairs.forEach(pair => {
console.log(`${pair.token0Symbol}/${pair.token1Symbol}: $${parseFloat(pair.volume24h).toLocaleString()} (24h volume)`);
});
});
interface Pair {
token0Symbol: string;
token1Symbol: string;
volume24h: string;
tvl: string;
fee: string;
}
interface PairsResponse {
pairs: Pair[];
}
async function getAllPairsWithStats(): Promise<PairsResponse> {
try {
const response = await fetch('https://api.hoops.finance/pairs');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching pairs:', error);
throw error;
}
}
function sortPairsByVolume(pairs: PairsResponse, limit: number = 10): Pair[] {
return pairs.pairs
.sort((a, b) => parseFloat(b.volume24h || '0') - parseFloat(a.volume24h || '0'))
.slice(0, limit);
}
// Usage
getAllPairsWithStats().then(data => {
const topPairs = sortPairsByVolume(data, 5);
topPairs.forEach(pair => {
console.log(`${pair.token0Symbol}/${pair.token1Symbol}: $${parseFloat(pair.volume24h).toLocaleString()} (24h volume)`);
});
});
# Get all pairs
curl -s "https://api.hoops.finance/pairs" | jq '.'
# Get top 5 pairs by volume
curl -s "https://api.hoops.finance/pairs" | jq '.pairs | sort_by(.volume24h | tonumber) | reverse | .[0:5][] | "\(.token0Symbol)/\(.token1Symbol): $\(.volume24h) (24h volume)"'
# Extract specific pair data
PAIRS=$(curl -s "https://api.hoops.finance/pairs")
echo "$PAIRS" | jq -r '.pairs[0:5][] | "\(.token0Symbol)/\(.token1Symbol): $\(.volume24h) (24h volume)"'
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"sort"
"strconv"
)
type Pair struct {
Token0Symbol string `json:"token0Symbol"`
Token1Symbol string `json:"token1Symbol"`
Volume24h string `json:"volume24h"`
TVL string `json:"tvl"`
Fee string `json:"fee"`
}
type PairsResponse struct {
Pairs []Pair `json:"pairs"`
}
func getAllPairsWithStats() (*PairsResponse, error) {
resp, err := http.Get("https://api.hoops.finance/pairs")
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var pairsResponse PairsResponse
err = json.Unmarshal(body, &pairsResponse)
return &pairsResponse, err
}
func sortPairsByVolume(pairs *PairsResponse, limit int) []Pair {
sortedPairs := make([]Pair, len(pairs.Pairs))
copy(sortedPairs, pairs.Pairs)
sort.Slice(sortedPairs, func(i, j int) bool {
volI, _ := strconv.ParseFloat(sortedPairs[i].Volume24h, 64)
volJ, _ := strconv.ParseFloat(sortedPairs[j].Volume24h, 64)
return volI > volJ
})
if limit > len(sortedPairs) {
limit = len(sortedPairs)
}
return sortedPairs[:limit]
}
func main() {
pairs, err := getAllPairsWithStats()
if err != nil {
panic(err)
}
topPairs := sortPairsByVolume(pairs, 5)
for _, pair := range topPairs {
volume, _ := strconv.ParseFloat(pair.Volume24h, 64)
fmt.Printf("%s/%s: $%.2f (24h volume)\n",
pair.Token0Symbol, pair.Token1Symbol, volume)
}
}
use reqwest;
use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
#[derive(Debug, Serialize, Deserialize, Clone)]
struct Pair {
token0_symbol: String,
token1_symbol: String,
volume24h: String,
tvl: String,
fee: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct PairsResponse {
pairs: Vec<Pair>,
}
async fn get_all_pairs_with_stats() -> Result<PairsResponse, Box<dyn std::error::Error>> {
let response = reqwest::get("https://api.hoops.finance/pairs").await?;
let pairs_response: PairsResponse = response.json().await?;
Ok(pairs_response)
}
fn sort_pairs_by_volume(mut pairs: Vec<Pair>, limit: usize) -> Vec<Pair> {
pairs.sort_by(|a, b| {
let vol_a: f64 = a.volume24h.parse().unwrap_or(0.0);
let vol_b: f64 = b.volume24h.parse().unwrap_or(0.0);
vol_b.partial_cmp(&vol_a).unwrap_or(Ordering::Equal)
});
pairs.into_iter().take(limit).collect()
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let pairs = get_all_pairs_with_stats().await?;
let top_pairs = sort_pairs_by_volume(pairs.pairs, 5);
for pair in top_pairs {
let volume: f64 = pair.volume24h.parse().unwrap_or(0.0);
println!("{}/{}: ${:.2} (24h volume)",
pair.token0_symbol, pair.token1_symbol, volume);
}
Ok(())
}
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;
public class Pair {
@JsonProperty("token0Symbol")
private String token0Symbol;
@JsonProperty("token1Symbol")
private String token1Symbol;
@JsonProperty("volume24h")
private String volume24h;
private String tvl;
private String fee;
// Getters and setters
public String getToken0Symbol() { return token0Symbol; }
public void setToken0Symbol(String token0Symbol) { this.token0Symbol = token0Symbol; }
public String getToken1Symbol() { return token1Symbol; }
public void setToken1Symbol(String token1Symbol) { this.token1Symbol = token1Symbol; }
public String getVolume24h() { return volume24h; }
public void setVolume24h(String volume24h) { this.volume24h = volume24h; }
public String getTvl() { return tvl; }
public void setTvl(String tvl) { this.tvl = tvl; }
public String getFee() { return fee; }
public void setFee(String fee) { this.fee = fee; }
}
public class PairsResponse {
private List<Pair> pairs;
public List<Pair> getPairs() { return pairs; }
public void setPairs(List<Pair> pairs) { this.pairs = pairs; }
}
public class HoopsApiClient {
private static final String BASE_URL = "https://api.hoops.finance";
private final HttpClient client = HttpClient.newHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
public PairsResponse getAllPairsWithStats() throws Exception {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/pairs"))
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
return mapper.readValue(response.body(), PairsResponse.class);
}
public List<Pair> sortPairsByVolume(PairsResponse pairsResponse, int limit) {
return pairsResponse.getPairs().stream()
.sorted(Comparator.comparing(pair ->
Double.parseDouble(pair.getVolume24h() != null ? pair.getVolume24h() : "0"),
Comparator.reverseOrder()))
.limit(limit)
.collect(Collectors.toList());
}
public static void main(String[] args) throws Exception {
HoopsApiClient client = new HoopsApiClient();
PairsResponse pairsResponse = client.getAllPairsWithStats();
List<Pair> topPairs = client.sortPairsByVolume(pairsResponse, 5);
for (Pair pair : topPairs) {
double volume = Double.parseDouble(pair.getVolume24h() != null ? pair.getVolume24h() : "0");
System.out.printf("%s/%s: $%.2f (24h volume)%n",
pair.getToken0Symbol(), pair.getToken1Symbol(), volume);
}
}
}
#!/bin/bash
BASE_URL="https://api.hoops.finance"
get_all_pairs_with_stats() {
curl -s "${BASE_URL}/pairs" | jq '.'
}
sort_pairs_by_volume() {
local limit=${1:-10}
local pairs=$(curl -s "${BASE_URL}/pairs")
echo "$pairs" | jq -r --arg limit "$limit" '
.pairs |
sort_by(.volume24h | tonumber) |
reverse |
.[0:$limit | tonumber][] |
"\(.token0Symbol)/\(.token1Symbol): $\(.volume24h) (24h volume)"
'
}
# Usage
echo "Getting all pairs..."
pairs=$(get_all_pairs_with_stats)
echo "Top 5 pairs by volume:"
sort_pairs_by_volume 5
# Alternative: Extract specific data
echo "$pairs" | jq -r '.pairs[0:5][] | "\(.token0Symbol)/\(.token1Symbol): $\(.volume24h) (24h volume)"'
Use Case
Great for: Trading dashboards, volume analysis, and identifying trending pairs
Detailed Pair Statistics
Get Specific Pair Details
- Python
- JavaScript
- TypeScript
- cURL
- Go
- Rust
- Java
- Shell
def get_pair_details(pair_contract):
"""Fetch detailed information for a specific pair"""
url = f"https://api.hoops.finance/pairs/{pair_contract}"
response = requests.get(url)
response.raise_for_status()
return response.json()
def get_pair_statistics(pair_contract):
"""Fetch statistics for a specific pair"""
url = f"https://api.hoops.finance/getstatistics?pairContract={pair_contract}"
response = requests.get(url)
response.raise_for_status()
return response.json()
# Usage
pair_address = "CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU"
pair_details = get_pair_details(pair_address)
pair_stats = get_pair_statistics(pair_address)
print(f"Pair: {pair_details['token0Symbol']}/{pair_details['token1Symbol']}")
print(f"TVL: ${float(pair_details['tvl']):,.2f}")
print(f"Fee: {pair_details['fee']}%")
print(f"24h Volume: ${float(pair_details['volume24h']):,.2f}")
async function getPairDetails(pairContract) {
try {
const response = await fetch(`https://api.hoops.finance/pairs/${pairContract}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching pair details:', error.message);
throw error;
}
}
async function getPairStatistics(pairContract) {
try {
const response = await fetch(`https://api.hoops.finance/getstatistics?pairContract=${pairContract}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching pair statistics:', error.message);
throw error;
}
}
// Usage
const pairAddress = "CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU";
Promise.all([
getPairDetails(pairAddress),
getPairStatistics(pairAddress)
]).then(([details, stats]) => {
console.log(`Pair: ${details.token0Symbol}/${details.token1Symbol}`);
console.log(`TVL: $${parseFloat(details.tvl).toLocaleString()}`);
console.log(`Fee: ${details.fee}%`);
console.log(`24h Volume: $${parseFloat(details.volume24h).toLocaleString()}`);
});
interface PairDetails {
token0Symbol: string;
token1Symbol: string;
tvl: string;
fee: string;
volume24h: string;
}
interface PairStatistics {
[key: string]: any;
}
async function getPairDetails(pairContract: string): Promise<PairDetails> {
try {
const response = await fetch(`https://api.hoops.finance/pairs/${pairContract}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching pair details:', error);
throw error;
}
}
async function getPairStatistics(pairContract: string): Promise<PairStatistics> {
try {
const response = await fetch(`https://api.hoops.finance/getstatistics?pairContract=${pairContract}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
} catch (error) {
console.error('Error fetching pair statistics:', error);
throw error;
}
}
// Usage
const pairAddress = "CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU";
Promise.all([
getPairDetails(pairAddress),
getPairStatistics(pairAddress)
]).then(([details, stats]) => {
console.log(`Pair: ${details.token0Symbol}/${details.token1Symbol}`);
console.log(`TVL: $${parseFloat(details.tvl).toLocaleString()}`);
console.log(`Fee: ${details.fee}%`);
console.log(`24h Volume: $${parseFloat(details.volume24h).toLocaleString()}`);
});
# Get pair details
PAIR_ADDRESS="CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU"
# Get pair details
curl -s "https://api.hoops.finance/pairs/${PAIR_ADDRESS}" | jq '.'
# Get pair statistics
curl -s "https://api.hoops.finance/getstatistics?pairContract=${PAIR_ADDRESS}" | jq '.'
# Extract specific values
TOKEN0=$(curl -s "https://api.hoops.finance/pairs/${PAIR_ADDRESS}" | jq -r '.token0Symbol')
TOKEN1=$(curl -s "https://api.hoops.finance/pairs/${PAIR_ADDRESS}" | jq -r '.token1Symbol')
TVL=$(curl -s "https://api.hoops.finance/pairs/${PAIR_ADDRESS}" | jq -r '.tvl')
FEE=$(curl -s "https://api.hoops.finance/pairs/${PAIR_ADDRESS}" | jq -r '.fee')
VOLUME=$(curl -s "https://api.hoops.finance/pairs/${PAIR_ADDRESS}" | jq -r '.volume24h')
echo "Pair: ${TOKEN0}/${TOKEN1}"
echo "TVL: \$${TVL}"
echo "Fee: ${FEE}%"
echo "24h Volume: \$${VOLUME}"
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type PairDetails struct {
Token0Symbol string `json:"token0Symbol"`
Token1Symbol string `json:"token1Symbol"`
TVL string `json:"tvl"`
Fee string `json:"fee"`
Volume24h string `json:"volume24h"`
}
type PairStatistics struct {
Data map[string]interface{} `json:"data"`
}
func getPairDetails(pairContract string) (*PairDetails, error) {
url := fmt.Sprintf("https://api.hoops.finance/pairs/%s", pairContract)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var pairDetails PairDetails
err = json.Unmarshal(body, &pairDetails)
return &pairDetails, err
}
func getPairStatistics(pairContract string) (*PairStatistics, error) {
url := fmt.Sprintf("https://api.hoops.finance/getstatistics?pairContract=%s", pairContract)
resp, err := http.Get(url)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
var pairStats PairStatistics
err = json.Unmarshal(body, &pairStats)
return &pairStats, err
}
func main() {
pairAddress := "CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU"
pairDetails, err := getPairDetails(pairAddress)
if err != nil {
panic(err)
}
pairStats, err := getPairStatistics(pairAddress)
if err != nil {
panic(err)
}
fmt.Printf("Pair: %s/%s\n", pairDetails.Token0Symbol, pairDetails.Token1Symbol)
fmt.Printf("TVL: $%s\n", pairDetails.TVL)
fmt.Printf("Fee: %s%%\n", pairDetails.Fee)
fmt.Printf("24h Volume: $%s\n", pairDetails.Volume24h)
}
use reqwest;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct PairDetails {
token0_symbol: String,
token1_symbol: String,
tvl: String,
fee: String,
volume24h: String,
}
#[derive(Debug, Serialize, Deserialize)]
struct PairStatistics {
data: std::collections::HashMap<String, serde_json::Value>,
}
async fn get_pair_details(pair_contract: &str) -> Result<PairDetails, Box<dyn std::error::Error>> {
let url = format!("https://api.hoops.finance/pairs/{}", pair_contract);
let response = reqwest::get(&url).await?;
let pair_details: PairDetails = response.json().await?;
Ok(pair_details)
}
async fn get_pair_statistics(pair_contract: &str) -> Result<PairStatistics, Box<dyn std::error::Error>> {
let url = format!("https://api.hoops.finance/getstatistics?pairContract={}", pair_contract);
let response = reqwest::get(&url).await?;
let pair_stats: PairStatistics = response.json().await?;
Ok(pair_stats)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let pair_address = "CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU";
let pair_details = get_pair_details(pair_address).await?;
let pair_stats = get_pair_statistics(pair_address).await?;
println!("Pair: {}/{}", pair_details.token0_symbol, pair_details.token1_symbol);
println!("TVL: ${}", pair_details.tvl);
println!("Fee: {}%", pair_details.fee);
println!("24h Volume: ${}", pair_details.volume24h);
Ok(())
}
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Map;
public class PairDetails {
@JsonProperty("token0Symbol")
private String token0Symbol;
@JsonProperty("token1Symbol")
private String token1Symbol;
private String tvl;
private String fee;
@JsonProperty("volume24h")
private String volume24h;
// Getters and setters
public String getToken0Symbol() { return token0Symbol; }
public void setToken0Symbol(String token0Symbol) { this.token0Symbol = token0Symbol; }
public String getToken1Symbol() { return token1Symbol; }
public void setToken1Symbol(String token1Symbol) { this.token1Symbol = token1Symbol; }
public String getTvl() { return tvl; }
public void setTvl(String tvl) { this.tvl = tvl; }
public String getFee() { return fee; }
public void setFee(String fee) { this.fee = fee; }
public String getVolume24h() { return volume24h; }
public void setVolume24h(String volume24h) { this.volume24h = volume24h; }
}
public class PairStatistics {
private Map<String, Object> data;
public Map<String, Object> getData() { return data; }
public void setData(Map<String, Object> data) { this.data = data; }
}
public class HoopsApiClient {
private static final String BASE_URL = "https://api.hoops.finance";
private final HttpClient client = HttpClient.newHttpClient();
private final ObjectMapper mapper = new ObjectMapper();
public PairDetails getPairDetails(String pairContract) throws Exception {
String url = String.format("%s/pairs/%s", BASE_URL, pairContract);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
return mapper.readValue(response.body(), PairDetails.class);
}
public PairStatistics getPairStatistics(String pairContract) throws Exception {
String url = String.format("%s/getstatistics?pairContract=%s", BASE_URL, pairContract);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(url))
.GET()
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());
return mapper.readValue(response.body(), PairStatistics.class);
}
public static void main(String[] args) throws Exception {
HoopsApiClient client = new HoopsApiClient();
String pairAddress = "CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU";
PairDetails pairDetails = client.getPairDetails(pairAddress);
PairStatistics pairStats = client.getPairStatistics(pairAddress);
System.out.printf("Pair: %s/%s%n", pairDetails.getToken0Symbol(), pairDetails.getToken1Symbol());
System.out.printf("TVL: $%s%n", pairDetails.getTvl());
System.out.printf("Fee: %s%%%n", pairDetails.getFee());
System.out.printf("24h Volume: $%s%n", pairDetails.getVolume24h());
}
}
#!/bin/bash
BASE_URL="https://api.hoops.finance"
get_pair_details() {
local pair_contract=$1
curl -s "${BASE_URL}/pairs/${pair_contract}" | jq '.'
}
get_pair_statistics() {
local pair_contract=$1
curl -s "${BASE_URL}/getstatistics?pairContract=${pair_contract}" | jq '.'
}
# Usage
PAIR_ADDRESS="CAB6MICC2WKRT372U3FRPKGGVB5R3FDJSMWJL5XK6R3XWMJUCA4RJMXU"
# Get pair details
pair_details=$(get_pair_details "$PAIR_ADDRESS")
# Get pair statistics
pair_stats=$(get_pair_statistics "$PAIR_ADDRESS")
# Extract values
token0=$(echo "$pair_details" | jq -r '.token0Symbol')
token1=$(echo "$pair_details" | jq -r '.token1Symbol')
tvl=$(echo "$pair_details" | jq -r '.tvl')
fee=$(echo "$pair_details" | jq -r '.fee')
volume=$(echo "$pair_details" | jq -r '.volume24h')
echo "Pair: ${token0}/${token1}"
echo "TVL: \$${tvl}"
echo "Fee: ${fee}%"
echo "24h Volume: \$${volume}"
Use Case
Great for: Individual pair analysis, detailed trading views, and portfolio tracking
Building a Complete Dashboard
Python Dashboard Example
import requests
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
class HoopsDashboard:
def __init__(self):
self.base_url = "https://api.hoops.finance"
def get_dashboard_data(self):
"""Fetch all data needed for dashboard"""
# Get platform metrics
metrics = requests.get(f"{self.base_url}/getmetrics?period=24h").json()
# Get all pairs
pairs = requests.get(f"{self.base_url}/pairs").json()
return {
'metrics': metrics,
'pairs': pairs['pairs']
}
def create_volume_chart(self, pairs, top_n=10):
"""Create a bar chart of top volume pairs"""
# Sort by volume and get top pairs
top_pairs = sorted(pairs, key=lambda x: float(x.get('volume24h', 0)), reverse=True)[:top_n]
fig = go.Figure(data=[
go.Bar(
x=[f"{p['token0Symbol']}/{p['token1Symbol']}" for p in top_pairs],
y=[float(p['volume24h']) for p in top_pairs],
name='24h Volume'
)
])
fig.update_layout(
title='Top Trading Pairs by Volume',
xaxis_title='Pair',
yaxis_title='Volume (USD)',
height=400
)
return fig
def generate_dashboard(self):
"""Generate complete dashboard"""
data = self.get_dashboard_data()
# Print summary metrics
print("=== HOOP FINANCE DASHBOARD ===")
print(f"Total TVL: ${data['metrics']['tvl']:,.2f}")
print(f"24h Volume: ${data['metrics']['volume24h']:,.2f}")
print(f"Active Pairs: {data['metrics']['activePairs']}")
print(f"Total Fees (24h): ${data['metrics']['fees24h']:,.2f}")
# Create volume chart
volume_chart = self.create_volume_chart(data['pairs'])
volume_chart.show()
# Usage
dashboard = HoopsDashboard()
dashboard.generate_dashboard()
JavaScript Dashboard Example
class HoopsDashboard {
constructor() {
this.baseUrl = 'https://api.hoops.finance';
}
async getDashboardData() {
try {
const [metricsResponse, pairsResponse] = await Promise.all([
fetch(`${this.baseUrl}/getmetrics?period=24h`),
fetch(`${this.baseUrl}/pairs`)
]);
if (!metricsResponse.ok || !pairsResponse.ok) {
throw new Error(`HTTP error! status: ${metricsResponse.status} or ${pairsResponse.status}`);
}
const [metrics, pairs] = await Promise.all([
metricsResponse.json(),
pairsResponse.json()
]);
return {
metrics: metrics,
pairs: pairs.pairs
};
} catch (error) {
console.error('Error fetching dashboard data:', error.message);
throw error;
}
}
generateSummary(data) {
console.log('=== HOOP FINANCE DASHBOARD ===');
console.log(`Total TVL: $${data.metrics.tvl.toLocaleString()}`);
console.log(`24h Volume: $${data.metrics.volume24h.toLocaleString()}`);
console.log(`Active Pairs: ${data.metrics.activePairs}`);
console.log(`Total Fees (24h): $${data.metrics.fees24h.toLocaleString()}`);
}
getTopVolumePairs(pairs, limit = 10) {
return pairs
.sort((a, b) => parseFloat(b.volume24h || 0) - parseFloat(a.volume24h || 0))
.slice(0, limit);
}
async generateDashboard() {
const data = await this.getDashboardData();
this.generateSummary(data);
const topPairs = this.getTopVolumePairs(data.pairs, 5);
console.log('\n=== TOP VOLUME PAIRS ===');
topPairs.forEach((pair, index) => {
console.log(`${index + 1}. ${pair.token0Symbol}/${pair.token1Symbol}: $${parseFloat(pair.volume24h).toLocaleString()}`);
});
}
}
// Usage
const dashboard = new HoopsDashboard();
dashboard.generateDashboard();
Visualization Libraries
Recommended Charting Libraries
Python:
- Plotly - Interactive charts with web export
- Matplotlib - Static charts for reports
- Streamlit - Quick dashboard creation
JavaScript:
- Chart.js - Simple, responsive charts
- D3.js - Advanced custom visualizations
- Recharts - React-based charting
Example: Chart.js Integration
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
<canvas id="volumeChart" width="400" height="200"></canvas>
<script>
async function loadChartData() {
const response = await fetch('https://api.hoops.finance/pairs');
const data = await response.json();
const topPairs = data.pairs
.sort((a, b) => parseFloat(b.volume24h || 0) - parseFloat(a.volume24h || 0))
.slice(0, 10);
const ctx = document.getElementById('volumeChart').getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: topPairs.map(p => `${p.token0Symbol}/${p.token1Symbol}`),
datasets: [{
label: '24h Volume (USD)',
data: topPairs.map(p => parseFloat(p.volume24h)),
backgroundColor: 'rgba(54, 162, 235, 0.2)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
loadChartData();
</script>
</body>
</html>
Next Steps
- Combine with Token Data to add token metadata to your charts
- Use Liquidity Monitoring to track pool health
- Integrate with Wallet Tracking for user-specific analytics
Rate Limiting
Remember to implement proper rate limiting in production applications. The API allows 120 requests per minute.