-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* refactor: migrate coinmarketcap plugin to use @tool decorator Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * refactor: remove tools.ts after migration to @tool decorator Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * feat: implement coinmarketcap plugin with @tool decorator and integration tests Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: address lint formatting issues Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: add explicit type annotations to parameter classes Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: use createToolParameters correctly for parameter classes Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: format parameter class declarations Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: export parameter schemas directly without createToolParameters Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: add explicit type declarations to parameter classes Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: simplify parameter classes to match ERC20 plugin implementation Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: add static schema properties and separate schema definitions Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: cast zod objects to ZodSchema type Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * fix: update package.json and fix parameter formatting Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * chore: remove tests as requested Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * style: fix type assertions, import sorting and tool descriptions Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * style: apply biome formatting to coinmarketcap plugin Co-Authored-By: Alfonso Gomez Jordana Manas <[email protected]> * Fix PR * Fix pnpm lock file * Fix pnpm lock file * Add changeset --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Alfonso Gomez Jordana Manas <[email protected]> Co-authored-by: Agustin Armellini Fischer <[email protected]>
- Loading branch information
1 parent
50180d4
commit b31d3ce
Showing
12 changed files
with
589 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"@goat-sdk/plugin-coinmarketcap": patch | ||
--- | ||
|
||
Create plugin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"name": "@goat-sdk/plugin-coinmarketcap", | ||
"version": "0.1.0", | ||
"files": ["dist/**/*", "README.md", "package.json"], | ||
"scripts": { | ||
"build": "tsup", | ||
"clean": "rm -rf dist", | ||
"test": "vitest run --passWithNoTests" | ||
}, | ||
"sideEffects": false, | ||
"main": "./dist/index.js", | ||
"module": "./dist/index.mjs", | ||
"types": "./dist/index.d.ts", | ||
"dependencies": { | ||
"@goat-sdk/core": "workspace:*", | ||
"zod": "catalog:" | ||
}, | ||
"peerDependencies": { | ||
"@goat-sdk/core": "workspace:*" | ||
}, | ||
"homepage": "https://ohmygoat.dev", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/goat-sdk/goat.git" | ||
}, | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/goat-sdk/goat/issues" | ||
}, | ||
"keywords": ["ai", "agents", "web3"] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
export class CoinmarketcapApi { | ||
private readonly BASE_URL = "https://pro-api.coinmarketcap.com/"; | ||
|
||
constructor(private readonly apiKey: string) {} | ||
|
||
async makeRequest<T>(endpoint: string, params: T) { | ||
const queryString = new URLSearchParams( | ||
Object.entries(params || {}).reduce( | ||
(acc, [key, value]) => { | ||
if (value !== undefined) { | ||
acc[key] = String(value); | ||
} | ||
return acc; | ||
}, | ||
{} as Record<string, string>, | ||
), | ||
).toString(); | ||
|
||
const url = `${this.BASE_URL}${endpoint}${queryString ? `?${queryString}` : ""}`; | ||
|
||
try { | ||
const response = await fetch(url, { | ||
method: "GET", | ||
headers: { | ||
"X-CMC_PRO_API_KEY": this.apiKey, | ||
Accept: "application/json", | ||
}, | ||
}); | ||
|
||
if (!response.ok) { | ||
const errorData = await response.json(); | ||
throw new Error( | ||
`Coinmarketcap API Error: ${response.status} - ${ | ||
errorData?.status?.error_message || response.statusText | ||
}`, | ||
); | ||
} | ||
|
||
return (await response.json()).data; | ||
} catch (error) { | ||
if (error instanceof Error) { | ||
throw error; | ||
} | ||
throw new Error("An unknown error occurred while fetching data"); | ||
} | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
typescript/packages/plugins/coinmarketcap/src/coinmarketcap.plugin.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { type Chain, PluginBase } from "@goat-sdk/core"; | ||
import { CoinmarketcapService } from "./coinmarketcap.service"; | ||
|
||
export interface CoinmarketcapOptions { | ||
apiKey: string; | ||
} | ||
|
||
export class CoinmarketcapPlugin extends PluginBase { | ||
constructor(private readonly options: CoinmarketcapOptions) { | ||
super("coinmarketcap", [new CoinmarketcapService(options.apiKey)]); | ||
} | ||
|
||
supportsChain(_chain: Chain): boolean { | ||
// This plugin doesn't require specific chain support as it's an API wrapper | ||
return true; | ||
} | ||
} | ||
|
||
export function coinmarketcap(options: CoinmarketcapOptions) { | ||
return new CoinmarketcapPlugin(options); | ||
} |
209 changes: 209 additions & 0 deletions
209
typescript/packages/plugins/coinmarketcap/src/coinmarketcap.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
import { Tool } from "@goat-sdk/core"; | ||
|
||
import { | ||
ContentLatestParameters, | ||
CryptocurrencyListingsParameters, | ||
CryptocurrencyMapParameters, | ||
CryptocurrencyOHLCVLatestParameters, | ||
CryptocurrencyQuotesLatestParameters, | ||
CryptocurrencyTrendingGainersLosersParameters, | ||
CryptocurrencyTrendingLatestParameters, | ||
CryptocurrencyTrendingMostVisitedParameters, | ||
ExchangeListingsParameters, | ||
ExchangeQuotesLatestParameters, | ||
} from "./parameters"; | ||
|
||
import { CoinmarketcapApi } from "./api"; | ||
|
||
export class CoinmarketcapService { | ||
private readonly api: CoinmarketcapApi; | ||
|
||
constructor(apiKey: string) { | ||
this.api = new CoinmarketcapApi(apiKey); | ||
} | ||
|
||
@Tool({ | ||
description: | ||
"Fetch the latest cryptocurrency listings with market data including price, market cap, volume, and other key metrics", | ||
}) | ||
async getCryptocurrencyListings(parameters: CryptocurrencyListingsParameters) { | ||
try { | ||
return await this.api.makeRequest("/v1/cryptocurrency/listings/latest", { | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
sort: parameters.sort, | ||
sort_dir: parameters.sort_dir, | ||
cryptocurrency_type: parameters.cryptocurrency_type, | ||
tag: parameters.tag, | ||
aux: parameters.aux?.join(","), | ||
convert: parameters.convert, | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch cryptocurrency listings: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: | ||
"Get the latest market quotes for one or more cryptocurrencies, including price, market cap, and volume in any supported currency", | ||
}) | ||
async getCryptocurrencyQuotes(parameters: CryptocurrencyQuotesLatestParameters) { | ||
try { | ||
return await this.api.makeRequest("/v2/cryptocurrency/quotes/latest", { | ||
id: parameters.id?.join(","), | ||
symbol: parameters.symbol?.join(","), | ||
convert: parameters.convert, | ||
aux: parameters.aux?.join(","), | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch cryptocurrency quotes: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: | ||
"Fetch the latest cryptocurrency exchange listings with market data including trading volume, number of markets, and liquidity metrics", | ||
}) | ||
async getExchangeListings(parameters: ExchangeListingsParameters) { | ||
try { | ||
return await this.api.makeRequest("/v1/exchange/listings/latest", { | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
sort: parameters.sort, | ||
sort_dir: parameters.sort_dir, | ||
market_type: parameters.market_type, | ||
aux: parameters.aux?.join(","), | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch exchange listings: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: | ||
"Get the latest market data for one or more exchanges including trading volume, number of markets, and other exchange-specific metrics", | ||
}) | ||
async getExchangeQuotes(parameters: ExchangeQuotesLatestParameters) { | ||
try { | ||
return await this.api.makeRequest("/v1/exchange/quotes/latest", { | ||
id: parameters.id?.join(","), | ||
slug: parameters.slug?.join(","), | ||
convert: parameters.convert, | ||
aux: parameters.aux?.join(","), | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch exchange quotes: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: "Fetch the latest cryptocurrency news, articles, and market analysis content from trusted sources", | ||
}) | ||
async getContent(parameters: ContentLatestParameters) { | ||
try { | ||
return await this.api.makeRequest("/v1/content/latest", { | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
id: parameters.id?.join(","), | ||
slug: parameters.slug?.join(","), | ||
symbol: parameters.symbol?.join(","), | ||
news_type: parameters.news_type, | ||
content_type: parameters.content_type, | ||
category: parameters.category, | ||
language: parameters.language, | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch content: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: | ||
"Get a mapping of all cryptocurrencies with unique CoinMarketCap IDs, including active and inactive assets", | ||
}) | ||
async getCryptocurrencyMap(parameters: CryptocurrencyMapParameters) { | ||
try { | ||
return await this.api.makeRequest("/v1/cryptocurrency/map", { | ||
listing_status: parameters.listing_status, | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
sort: parameters.sort, | ||
symbol: parameters.symbol?.join(","), | ||
aux: parameters.aux?.join(","), | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch cryptocurrency map: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: "Get the latest OHLCV (Open, High, Low, Close, Volume) values for cryptocurrencies", | ||
}) | ||
async getCryptocurrencyOHLCV(parameters: CryptocurrencyOHLCVLatestParameters) { | ||
try { | ||
return await this.api.makeRequest("/v2/cryptocurrency/ohlcv/latest", { | ||
id: parameters.id?.join(","), | ||
symbol: parameters.symbol?.join(","), | ||
convert: parameters.convert, | ||
convert_id: parameters.convert_id, | ||
skip_invalid: parameters.skip_invalid, | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch cryptocurrency OHLCV data: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: "Get the latest trending cryptocurrencies based on CoinMarketCap user activity", | ||
}) | ||
async getCryptocurrencyTrending(parameters: CryptocurrencyTrendingLatestParameters) { | ||
try { | ||
return await this.api.makeRequest("/cryptocurrency/trending/latest", { | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
time_period: parameters.time_period, | ||
convert: parameters.convert, | ||
convert_id: parameters.convert_id, | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch trending cryptocurrencies: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: "Get the most visited cryptocurrencies on CoinMarketCap over a specified time period", | ||
}) | ||
async getCryptocurrencyMostVisited(parameters: CryptocurrencyTrendingMostVisitedParameters) { | ||
try { | ||
return await this.api.makeRequest("/cryptocurrency/trending/most-visited", { | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
time_period: parameters.time_period, | ||
convert: parameters.convert, | ||
convert_id: parameters.convert_id, | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch most visited cryptocurrencies: ${error}`); | ||
} | ||
} | ||
|
||
@Tool({ | ||
description: | ||
"Get the top gaining and losing cryptocurrencies based on price changes over different time periods", | ||
}) | ||
async getCryptocurrencyGainersLosers(parameters: CryptocurrencyTrendingGainersLosersParameters) { | ||
try { | ||
return await this.api.makeRequest("/cryptocurrency/trending/gainers-losers", { | ||
start: parameters.start, | ||
limit: parameters.limit, | ||
time_period: parameters.time_period, | ||
convert: parameters.convert, | ||
convert_id: parameters.convert_id, | ||
sort: parameters.sort, | ||
sort_dir: parameters.sort_dir, | ||
}); | ||
} catch (error) { | ||
throw new Error(`Failed to fetch cryptocurrency gainers and losers: ${error}`); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./coinmarketcap.plugin"; |
Oops, something went wrong.