Skip to content

Instantly share code, notes, and snippets.

@rollendxavier
Last active May 8, 2025 12:00
Show Gist options
  • Save rollendxavier/ddf88a408cba5abbe9025ce9d9b07b6f to your computer and use it in GitHub Desktop.
Save rollendxavier/ddf88a408cba5abbe9025ce9d9b07b6f to your computer and use it in GitHub Desktop.
This command-line tool lets you interact with CoinGecko Pro API using the Goat SDK.
/**
* GoatGecko SDK CLI
*
* This command-line tool lets you interact with CoinGecko Pro API using the Goat SDK.
* Features:
* - Coin historical data
* - OHLC data
* - Trending coins
* - Trending pools by network
* - Top gainers & losers
*
* Usage:
* - Make sure you have a .env file with COINGECKO_API_KEY set.
* - Run: npm start or node dist/index.js
*/
import { coingecko } from "@goat-sdk/plugin-coingecko";
import { getTools } from "@goat-sdk/core";
import dotenv from "dotenv";
import { CoinGeckoTools } from "./cg-tools.enum.js";
import inquirer from "inquirer";
dotenv.config();
// Validate environment variables
if (!process.env.COINGECKO_API_KEY) {
console.error("[ERROR] COINGECKO_API_KEY is missing in the .env file.");
process.exit(1);
}
const wallet = {
getChain: () => ({
id: 1,
name: "Ethereum",
rpcUrls: [],
type: "radix" as const,
}),
getAccounts: () => [
{
address: "0x0",
balance: {
amount: "0",
decimals: 18,
symbol: "ETH",
name: "Ether",
value: "0",
inBaseUnits: "0",
},
},
],
signMessage: async () => ({ signature: "stub" }),
getAddress: () => "0x0",
balanceOf: async () => ({
amount: "0",
decimals: 18,
symbol: "ETH",
name: "Ether",
value: "0",
inBaseUnits: "0",
}),
getCoreTools: () => [],
};
// Utility function to validate inputs
function validateInput(input: string, fieldName: string): string {
if (!input || input.trim() === "") {
throw new Error(`[ERROR] ${fieldName} cannot be empty.`);
}
return input.trim();
}
function getToolByEnum(tools: any[], name: CoinGeckoTools) {
return tools.find(tool => tool.name === name);
}
async function main() {
try {
const tools = await getTools({
wallet,
plugins: [
coingecko({
apiKey: process.env.COINGECKO_API_KEY || "",
isPro: true,
}),
],
});
const getHistoricalData = getToolByEnum(tools, CoinGeckoTools.GetHistoricalData);
const getOHLCData = getToolByEnum(tools, CoinGeckoTools.GetOHLCData);
const getTrendingCoins = getToolByEnum(tools, CoinGeckoTools.GetTrendingCoins);
const getTrendingPoolsByNetwork = getToolByEnum(tools, CoinGeckoTools.GetTrendingPoolsByNetwork);
const getTopGainersLosers = getToolByEnum(tools, CoinGeckoTools.GetTopGainersLosers);
if (!getHistoricalData || !getOHLCData || !getTrendingCoins || !getTrendingPoolsByNetwork || !getTopGainersLosers) {
throw new Error("[ERROR] Required CoinGecko tools not found.");
}
while (true) {
const { action } = await inquirer.prompt([
{
type: "list",
name: "action",
message: "Select an action:",
choices: [
{ name: "Coin Historical Data", value: "historical" },
{ name: "OHLC Data", value: "ohlc" },
{ name: "Trending Coins", value: "trending" },
{ name: "Trending Pools by Network", value: "pools" },
{ name: "Top Gainers & Losers", value: "gainers_losers" },
{ name: "Exit", value: "exit" }
]
}
]);
if (action === "exit") {
console.log("Goodbye!");
break;
}
try {
switch (action) {
case "historical": {
const { id, date } = await inquirer.prompt<{
id: string;
date: string;
}>([
{ type: "input", name: "id", message: "Coin ID (e.g. bitcoin):", default: "bitcoin" },
{ type: "input", name: "date", message: "Date (DD-MM-YYYY):", default: "30-12-2021" }
]);
const validatedId = validateInput(id, "Coin ID");
const validatedDate = validateInput(date, "Date");
const result = await getHistoricalData.execute({ id: validatedId, date: validatedDate, localization: false });
console.log("\n=== Historical Data ===");
console.dir(result, { depth: null, colors: true });
break;
}
case "ohlc": {
const { id, vsCurrency, days } = await inquirer.prompt<{
id: string;
vsCurrency: string;
days: string;
}>([
{ type: "input", name: "id", message: "Coin ID (e.g. bitcoin):", default: "bitcoin" },
{ type: "input", name: "vsCurrency", message: "VS Currency (e.g. usd):", default: "usd" },
{ type: "input", name: "days", message: "Days (e.g. 7):", default: "7" }
]);
const validatedId = validateInput(id, "Coin ID");
const validatedCurrency = validateInput(vsCurrency, "VS Currency");
const validatedDays = parseInt(days, 10);
if (isNaN(validatedDays) || validatedDays <= 0) {
throw new Error("[ERROR] Days must be a positive number.");
}
const result = await getOHLCData.execute({ id: validatedId, vsCurrency: validatedCurrency, days: validatedDays });
console.log("\n=== OHLC Data ===");
console.dir(result, { depth: null, colors: true });
break;
}
case "trending": {
const result = await getTrendingCoins.execute({});
console.log("\n=== Trending Coins ===");
console.dir(result, { depth: null, colors: true });
break;
}
case "pools": {
const { network } = await inquirer.prompt<{
network: string;
}>([
{ type: "input", name: "network", message: "Network (e.g. eth):", default: "eth" }
]);
const validatedNetwork = validateInput(network, "Network");
const result = await getTrendingPoolsByNetwork.execute({ network: validatedNetwork });
console.log(`\n=== Trending Pools on ${validatedNetwork} ===`);
console.dir(result, { depth: null, colors: true });
break;
}
case "gainers_losers": {
const { vsCurrency, perPage, page } = await inquirer.prompt<{
vsCurrency: string;
perPage: string;
page: string;
}>([
{ type: "input", name: "vsCurrency", message: "VS Currency (e.g. usd):", default: "usd" },
{ type: "input", name: "perPage", message: "Results per page:", default: "10" },
{ type: "input", name: "page", message: "Page number:", default: "1" }
]);
const validatedCurrency = validateInput(vsCurrency, "VS Currency");
const validatedPerPage = parseInt(perPage, 10);
const validatedPage = parseInt(page, 10);
if (isNaN(validatedPerPage) || validatedPerPage <= 0 || isNaN(validatedPage) || validatedPage <= 0) {
throw new Error("[ERROR] Per page and page number must be positive numbers.");
}
const result = await getTopGainersLosers.execute({
vsCurrency: validatedCurrency,
perPage: validatedPerPage,
page: validatedPage,
});
console.log("\n=== Top Gainers & Losers ===");
console.dir(result, { depth: null, colors: true });
break;
}
}
} catch (err: any) {
console.error("\n[!] Error:", err.message);
}
console.log("\n----------------------------------------\n");
}
} catch (err: any) {
console.error("[FATAL] Startup error:", err.message);
process.exit(1);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment