-
Notifications
You must be signed in to change notification settings - Fork 3.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add birdeye plugin #1417
base: develop
Are you sure you want to change the base?
feat: add birdeye plugin #1417
Conversation
I'd love to get input from the team if perhaps these should be actions instead of provider data. |
Actions are like answers to questions/queries providers inject information in all prompts (like making the bot aware of the time) that’s my current understanding. You may want both |
So; tests are all passing, but when I run this locally, I can't get any plugins to work when added to the characterfile array. This issue also occurs on main, so it's probably not an issue with the plugin -- that said, don't want to merge if I can't get it running locally, will leave it for someone else. code looks fine when eyeballing |
I am going to rebase this to work better with the newly merged MR: #1366 I am also going to convert some of these providers to actions and do more testing and validation |
packages/plugin-birdeye/src/providers/defi/price-history-provider.ts
Outdated
Show resolved
Hide resolved
Ok, i have this cleaned up and trimmed down quite a bit. I focused on getting the types in place for all the Birdeye API endpoint even though there are not actions for all of them yet. --- EDIT: sorry still have to deal with a bunch of merge conflicts. will ping after. |
@odilitime @camharris I made a ton of improvements and greatly simplified the scope of this plugin to a core, minimal use case. I also added a video where you can see examples of what it can do. I think this is ready for primetime now. Please let me know what we can do to get this merged! |
Pinging to see if we can try to get a review soon. Thanks all! |
@swizzmagik Great work on this. I'll review this evening 🫡 |
Checking in, I think this is ready to ship |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall I think this looks good. All the included actions are working for me as expected. Great work, this is a cool and exciting start for Birdeye support.
I'm looking forward to using and further contributing
I tested the plugin as well and one error I got was when attempting to read a wallet that doesn't have a symbol attached. Changing 'token-search-address.ts' line 229 - 235 to resolved the issue. if (result.overview?.data) {
output += `\n`;
output += `Token Overview:\n`;
output += `📝 Name: ${result.overview.data.name || "N/A"}\n`;
output += `🔖 Symbol: ${(result.overview.data.symbol || "N/A").toUpperCase()}\n`;
output += `🔗 Address: ${address.address}\n`;
output += `🔢 Decimals: ${result.overview.data.decimals || "N/A"}\n`; |
Hi @camharris checking in here. Are we able to reapprove and get this merged in? I have some folks awaiting this feature. Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Over all I think this looks good and is ready to go. However there are merge conflicts you should resolve
📝 WalkthroughWalkthroughThe pull request introduces a new Birdeye plugin for the agent system, expanding cryptocurrency and blockchain data capabilities. The plugin adds comprehensive functionality for token searches, wallet portfolio tracking, and market analytics through the Birdeye API. Key changes include adding new dependencies, creating multiple TypeScript files for API interactions, defining type interfaces, and implementing utility functions for data extraction and formatting. Changes
Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@camharris this has been rebased and should be good to go now |
@coderabbitai review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🔭 Outside diff range comments (1)
packages/plugin-birdeye/src/types/api/wallet.ts (1)
Line range hint
193-193
: Define specific type for feeInfoThe
feeInfo?: any | null
type is too permissive. Consider creating a dedicated interface for the fee information structure.interface FeeInfo { amount?: number; currency?: string; // Add other relevant fee fields }- feeInfo?: any | null; + feeInfo?: FeeInfo | null;
🧹 Nitpick comments (24)
packages/plugin-birdeye/src/utils.ts (1)
597-605
: Optimize 'convertToStringParams' to improve performanceUsing the spread operator (
...acc
) in the reducer causes O(n²) time complexity due to object copying at each iteration. Refactor to use a mutable accumulator to achieve O(n) performance.Apply this diff to optimize the function:
-export const convertToStringParams = (params: BirdeyeApiParams) => { - return Object.entries(params || {}).reduce( - (acc, [key, value]) => ({ - ...acc, - [key]: value?.toString() || "", - }), - {} as Record<string, string> - ); -}; +export const convertToStringParams = (params: BirdeyeApiParams) => { + const result: Record<string, string> = {}; + for (const [key, value] of Object.entries(params || {})) { + result[key] = value?.toString() || ""; + } + return result; +};🧰 Tools
🪛 Biome (1.9.4)
[error] 603-603: Avoid the use of spread (
...
) syntax on accumulators.Spread syntax should be avoided on accumulators (like those in
.reduce
) because it causes a time complexity ofO(n^2)
.
Consider methods such as .splice or .push instead.(lint/performance/noAccumulatingSpread)
packages/plugin-birdeye/src/types/shared.ts (1)
3-11
: LGTM! Consider adding JSDoc comments.The type hierarchy is well-structured with
BaseAddress
as the parent interface and proper type extraction from constants.Add JSDoc comments to describe valid address formats for each chain:
/** Base interface for all address types supporting multiple chains */ export interface BaseAddress { /** Discriminator for address type */ type?: "wallet" | "token" | "contract"; // ... rest of the interface }packages/plugin-birdeye/src/index.ts (1)
14-14
: Consider exposing test action in development modeThe commented test action could be useful for development and debugging.
- // testAllEndpointsAction, // this action can be used to optionally test all endpoints + ...(process.env.NODE_ENV === 'development' ? [testAllEndpointsAction] : []),packages/plugin-birdeye/src/providers/agent-portfolio-provider.ts (1)
47-50
: Enhance error handling and message formattingThe error handling could be more specific and the portfolio text might need escaping for special characters.
- console.error("Error fetching token data:", error); - return "Unable to fetch token information. Please try again later."; + const errorMessage = error instanceof Error ? error.message : String(error); + console.error("Error fetching token data:", errorMessage); + return `Unable to fetch token information: ${errorMessage}. Please try again later.`;packages/plugin-birdeye/src/types/api/search.ts (1)
20-21
: Fix metric naming inconsistencyThe metric
unique_view_24h_change_percent
seems inconsistent withunique_wallet_24h
. Consider renaming tounique_wallet_24h_change_percent
for consistency.packages/plugin-birdeye/src/types/api/wallet.ts (1)
72-72
: Replace 'any' type with a more specific typeUsing
Record<string, any>
reduces type safety. Consider defining a specific interface for the metadata structure.- metadata?: Record<string, any>; + metadata?: Record<string, string | number | boolean | null>;packages/plugin-birdeye/src/constants.ts (1)
14-71
: Standardize API endpoint versioningThe endpoints mix versioned (v1, v2, v3) and unversioned paths. Consider standardizing the versioning approach across all endpoints for better maintainability.
packages/plugin-birdeye/src/types/api/pair.ts (2)
10-33
: Consider adding runtime safety checks for nullable fields.The
PairTradesResponse
interface contains multiple optional fields that could be undefined at runtime.Consider implementing helper functions with optional chaining and null checks when accessing these fields to prevent runtime errors.
133-199
: Consider adding type guards for response validation.The
PairOverviewSingleResponse
interface has all optional fields, which could make runtime type checking challenging.Consider implementing type guards to validate the response shape at runtime:
function isPairOverviewResponse(response: unknown): response is PairOverviewSingleResponse { return ( typeof response === 'object' && response !== null && 'success' in response && 'data' in response ); }packages/plugin-birdeye/src/actions/wallet-search-address.ts (2)
89-89
: Remove debug console.log statement.Production code should not contain debug logging statements.
-console.log(results);
74-75
: Consider supporting multiple EVM chains.The current implementation assumes ethereum for all EVM chains, which might limit future chain support.
Consider making the chain mapping configurable or supporting multiple EVM chains based on user input.
packages/plugin-birdeye/src/actions/token-search-symbol.ts (2)
101-101
: Update error message to match function name.The error message references "searchTokens" but should reference "tokenSearchSymbol".
-console.error("Error in searchTokens handler:", error.message); +console.error("Error in tokenSearchSymbol handler:", error.message);
88-88
: Consider making the result limit configurable.The hard-coded limit of 5 results might not suit all use cases.
Consider making this a configurable parameter with a reasonable default:
- limit: 5, + limit: options?.resultLimit ?? 5,packages/plugin-birdeye/src/types/api/common.ts (3)
45-82
: Add JSDoc documentation for the BirdeyeApiParams type.Adding documentation would help developers understand the purpose and usage of each parameter type.
/** * Union type representing all possible parameter types for Birdeye API endpoints. * @example * // Using DefiPriceParams * const params: BirdeyeApiParams = { * address: "0x...", * chain: "ethereum" * }; */ export type BirdeyeApiParams = ...
91-114
: Optimize TimeInterval type definition.The type contains duplicate intervals with different casing, which could be simplified.
Consider using a template literal type to handle case variations:
type BaseInterval = "1m" | "3m" | "5m" | "15m" | "30m" | "1H" | "2H" | "4H" | "6H" | "8H" | "12H" | "1D" | "3D" | "1W" | "1M"; export type TimeInterval = BaseInterval | Lowercase<BaseInterval>;
116-301
: Refactor TokenTradeData interface for better maintainability.The interface contains many repeated patterns that could be generated using utility types.
Consider using TypeScript utility types to reduce repetition:
type TimeFrame = "30m" | "1h" | "2h" | "4h" | "8h" | "24h"; type TradeMetrics = { trade: number; trade_history: number; trade_change_percent: number; // ... other common fields }; type TokenTradeData = { address: string; holder: number; // ... base fields } & { [K in TimeFrame as `${K}_metrics`]: TradeMetrics; };packages/plugin-birdeye/src/actions/token-search-address.ts (2)
33-69
: Consider grouping similar similes for better maintainability.The action configuration is comprehensive, but organizing similes into logical groups (e.g., search-related, info-related, analysis-related) would improve maintainability.
similes: [ + // Search operations "SEARCH_TOKEN_ADDRESS", "FIND_TOKEN_ADDRESS", "LOOKUP_TOKEN_ADDRESS", + // Information retrieval "TOKEN_ADDRESS_INFO", "TOKEN_INFO", + // Analysis operations "TOKEN_ANALYSIS", "TOKEN_METRICS", // ... rest of the similes ]
211-289
: Consider breaking down the formatting function.The
formatTokenReport
function is quite long and handles multiple concerns. Consider splitting it into smaller, focused functions for each section (overview, market data, trade data, security).+const formatOverview = (overview: TokenOverviewResponse['data']) => { + let output = ''; + if (overview) { + output += `\nToken Overview:\n`; + output += `📝 Name: ${overview.name}\n`; + // ... rest of overview formatting + } + return output; +}; const formatTokenReport = ( address: BaseAddress, index: number, result: TokenAddressSearchResult ) => { - let output = ``; - if (result.overview?.data) { - // ... overview formatting - } + let output = formatOverview(result.overview?.data); // ... rest of the sections return output; };packages/plugin-birdeye/src/actions/test-all-endpoints.ts (1)
17-382
: Consider restructuring the endpoint tests.The handler function is quite long and could be better organized. Consider:
- Grouping related endpoints into separate test functions
- Creating a test runner utility to handle common operations
+const testEndpointGroup = async ( + provider: BirdeyeProvider, + endpoints: Array<{ + name: string; + fn: () => Promise<any>; + }> +) => { + for (const { name, fn } of endpoints) { + elizaLogger.info(name); + await fn(); + elizaLogger.success(`${name}: SUCCESS!`); + await waitFor(500); + } +}; export const testAllEndpointsAction = { // ... action config handler: async (runtime, message, state, options, callback) => { try { const provider = new BirdeyeProvider(runtime.cacheManager); - // ... many individual endpoint tests + await testEndpointGroup(provider, [ + { + name: "fetchDefiSupportedNetworks", + fn: () => provider.fetchDefiSupportedNetworks() + }, + // ... group other endpoints + ]); } catch (error) { // ... error handling } } };🧰 Tools
🪛 Gitleaks (8.21.2)
33-33: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
50-50: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
packages/plugin-birdeye/README.md (2)
7-8
: Fix typo in section headingThere's a typo in "Provider Featurs".
-### Provider Featurs +### Provider Features
17-17
: Improve action descriptions clarityAdd commas for better readability and consistent structure in action descriptions.
- - This action will search input message for token addresses and when present will query Birdeye for token information + - This action will search input message for token addresses, and when present, will query Birdeye for token information - - This action will search input message for token symbols in the format of `$SYMBOL` and when present will query Birdeye for token information + - This action will search input message for token symbols in the format of `$SYMBOL`, and when present, will query Birdeye for token information - - This action will search input message for wallet addresses and when present will query Birdeye for wallet information + - This action will search input message for wallet addresses, and when present, will query Birdeye for wallet informationAlso applies to: 21-21, 26-26
🧰 Tools
🪛 LanguageTool
[uncategorized] ~17-~17: A comma might be missing here.
Context: ...earch input message for token addresses and when present will query Birdeye for tok...(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
🪛 Markdownlint (0.37.0)
17-17: Expected: 2; Actual: 4
Unordered list indentation(MD007, ul-indent)
packages/plugin-birdeye/src/tests/birdeye.test.ts (3)
272-377
: Consider adding error case tests for multiple pair overview.While the happy path tests are thorough, adding tests for scenarios like invalid pair addresses or API failures would improve coverage.
379-423
: Consider adding pagination and filtering tests.The current test covers basic search functionality. Adding tests for pagination and filtering would ensure robust search capabilities.
466-509
: Consider adding tests for specific error types.While retry logic is well tested, adding tests for specific API error responses (rate limits, validation errors, etc.) would improve coverage.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (27)
agent/package.json
(1 hunks)agent/src/index.ts
(5 hunks)packages/plugin-birdeye/.npmignore
(1 hunks)packages/plugin-birdeye/.nvmrc
(1 hunks)packages/plugin-birdeye/README.md
(1 hunks)packages/plugin-birdeye/eslint.config.mjs
(1 hunks)packages/plugin-birdeye/package.json
(1 hunks)packages/plugin-birdeye/src/actions/test-all-endpoints.ts
(1 hunks)packages/plugin-birdeye/src/actions/token-search-address.ts
(1 hunks)packages/plugin-birdeye/src/actions/token-search-symbol.ts
(1 hunks)packages/plugin-birdeye/src/actions/wallet-search-address.ts
(1 hunks)packages/plugin-birdeye/src/birdeye.ts
(1 hunks)packages/plugin-birdeye/src/constants.ts
(1 hunks)packages/plugin-birdeye/src/index.ts
(1 hunks)packages/plugin-birdeye/src/providers/agent-portfolio-provider.ts
(1 hunks)packages/plugin-birdeye/src/tests/birdeye.test.ts
(1 hunks)packages/plugin-birdeye/src/types/api/common.ts
(1 hunks)packages/plugin-birdeye/src/types/api/defi.ts
(1 hunks)packages/plugin-birdeye/src/types/api/pair.ts
(1 hunks)packages/plugin-birdeye/src/types/api/search.ts
(1 hunks)packages/plugin-birdeye/src/types/api/token.ts
(1 hunks)packages/plugin-birdeye/src/types/api/trader.ts
(1 hunks)packages/plugin-birdeye/src/types/api/wallet.ts
(1 hunks)packages/plugin-birdeye/src/types/shared.ts
(1 hunks)packages/plugin-birdeye/src/utils.ts
(1 hunks)packages/plugin-birdeye/tsconfig.json
(1 hunks)packages/plugin-birdeye/tsup.config.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (5)
- packages/plugin-birdeye/.nvmrc
- packages/plugin-birdeye/eslint.config.mjs
- packages/plugin-birdeye/.npmignore
- packages/plugin-birdeye/tsup.config.ts
- packages/plugin-birdeye/tsconfig.json
🧰 Additional context used
🪛 Gitleaks (8.21.2)
packages/plugin-birdeye/src/actions/test-all-endpoints.ts
33-33: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
50-50: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
🪛 LanguageTool
packages/plugin-birdeye/README.md
[uncategorized] ~17-~17: A comma might be missing here.
Context: ...earch input message for token addresses and when present will query Birdeye for tok...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
[uncategorized] ~21-~21: You might be missing the article “the” here.
Context: ...Symbol** - This action will search input message for token symbols in the format...
(AI_EN_LECTOR_MISSING_DETERMINER_THE)
[uncategorized] ~21-~21: A comma might be missing here.
Context: ...oken symbols in the format of $SYMBOL
and when present will query Birdeye for tok...
(AI_EN_LECTOR_MISSING_PUNCTUATION_COMMA)
🪛 Markdownlint (0.37.0)
packages/plugin-birdeye/README.md
11-11: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
17-17: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
21-21: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
22-22: Expected: 4; Actual: 8
Unordered list indentation
(MD007, ul-indent)
26-26: Expected: 2; Actual: 4
Unordered list indentation
(MD007, ul-indent)
🪛 Biome (1.9.4)
packages/plugin-birdeye/src/utils.ts
[error] 603-603: Avoid the use of spread (...
) syntax on accumulators.
Spread syntax should be avoided on accumulators (like those in .reduce
) because it causes a time complexity of O(n^2)
.
Consider methods such as .splice or .push instead.
(lint/performance/noAccumulatingSpread)
🔇 Additional comments (21)
packages/plugin-birdeye/src/types/api/token.ts (1)
1-634
: Interfaces are well-defined and comprehensiveThe TypeScript interfaces cover all necessary API endpoints and responses effectively. They are structured clearly and should facilitate seamless integration with the Birdeye API.
packages/plugin-birdeye/src/birdeye.ts (1)
1-803
: 'BirdeyeProvider' class implementation is robustThe
BirdeyeProvider
class provides a comprehensive set of methods for interacting with the Birdeye API. The use of caching and retry mechanisms enhances performance and reliability.packages/plugin-birdeye/src/types/api/trader.ts (1)
33-75
: Consider marking required fields as non-optionalSome fields like
tx_hash
andblock_unix_time
are likely required in practice.packages/plugin-birdeye/src/types/api/search.ts (1)
82-82
:⚠️ Potential issueFix typo in field name
The field
amout_quote
contains a typo and should beamount_quote
to maintain consistency withamount_base
.- amout_quote: number; // Note: typo in API response + amount_quote: number;Likely invalid or redundant comment.
packages/plugin-birdeye/src/types/api/pair.ts (2)
35-57
: LGTM! Well-structured OHLCV interfaces.The interfaces are properly typed and follow TypeScript best practices.
59-131
: Great job on the comprehensive interface design!The
PairOverviewData
interface is well-organized with clear grouping of related fields and helpful comments.packages/plugin-birdeye/src/actions/wallet-search-address.ts (2)
14-50
: Excellent coverage of natural language variations!The comprehensive list of similes will help in matching various user query patterns.
151-176
: Clean and effective formatting implementation!The
formatWalletReport
function produces well-structured output using modern JavaScript features.packages/plugin-birdeye/src/actions/token-search-symbol.ts (1)
201-225
: Well-implemented formatting with proper null handling!The
formatTokenSummary
function effectively handles optional fields and produces clean output.packages/plugin-birdeye/src/actions/token-search-address.ts (4)
1-31
: Clean imports and type definitions!The imports are well-organized, and the
TokenAddressSearchResult
type is properly defined with all necessary fields.
92-92
: Document EVM chain limitation in README.The comment about EVM chain limitations is important information that should be documented in the README for better visibility.
166-169
: Validation looks good!The validation function correctly checks for the presence of addresses in the message content.
170-209
: Great example coverage!The examples effectively demonstrate various ways to use the action with different address formats and chains.
packages/plugin-birdeye/src/actions/test-all-endpoints.ts (2)
33-33
: False positive: Sample addresses are not API keys.The static analysis tool incorrectly flagged Solana addresses as potential API keys. These are valid test addresses used for demonstration purposes.
Also applies to: 50-50
🧰 Tools
🪛 Gitleaks (8.21.2)
33-33: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.
(generic-api-key)
383-398
: Appropriate validation for test action!The validation correctly requires an explicit trigger, and the example clearly shows how to invoke the test action.
packages/plugin-birdeye/src/tests/birdeye.test.ts (4)
61-123
: Well-structured test coverage for Defi endpoints!The tests thoroughly cover all Defi endpoints with appropriate mock data and endpoint verification.
125-215
: Comprehensive test coverage for Token endpoints!Particularly impressed with the detailed security checks in the token security test.
217-270
: Good test coverage for Wallet endpoints!Tests effectively validate both portfolio and token balance functionality with realistic mock data.
425-464
: Solid test coverage for caching functionality!Tests effectively verify both cache hit and miss scenarios.
agent/src/index.ts (2)
47-47
: Clean integration of the birdeye plugin!The plugin is properly imported and conditionally added to the runtime based on the API key presence.
Also applies to: 710-710
681-682
: Good API key validation for coingecko plugin!The plugin is properly configured to work with both regular and pro API keys.
this has been rebased and is ready to merge |
Overview
testAllEndpointsAction
that was used to validate that all API endpoints are functional and aligned with the types.Relates to:
Risks
Background
This pull request significantly enhances the Birdeye API integration within the AI agent framework by expanding its capabilities beyond basic query functionality. The proposed tools enable more comprehensive and versatile interactions with the Birdeye API, including data clearing and management features. These improvements provide the AI agents with a broader and more efficient toolkit for handling Birdeye API data, enhancing the overall flexibility and utility of the framework for developers and end-users. By extending the scope of the API integration, this contribution supports more robust and scalable solutions within the project.
What does this PR do?
This PR adds providers that represent all the different API endpoints available in the Birdeye API. By doing so, it ensures that when a user requests a specific type of data, the AI agent has a significantly higher likelihood of accessing and utilizing the relevant data in its response. This enhancement maximizes the agent’s ability to provide accurate and contextually rich answers, leveraging the full scope of the Birdeye API.
What kind of change is this?
This API connection is critical for enabling the agent to perform research and analyze the dynamics of the ecosystem effectively. By integrating comprehensive access to all Birdeye API endpoints, this PR lays the groundwork for future enhancements and features that will further expand the agent's capabilities. This integration not only empowers the agent to deliver more insightful and accurate responses but also positions the framework for scalable growth and the addition of advanced functionalities in the future.
Documentation changes needed?
Testing
Where should a reviewer start?
Screenshots
After
This is the
agentPortfolioProvider
showing portfolio infoThis is a video example showing the new capabilities of search for symbol, search for contract address, and search for wallet
Screen.Recording.2025-01-04.at.7.28.17.AM.mov