Skip to content

Conversation

@HarshGautam7101
Copy link
Contributor

@HarshGautam7101 HarshGautam7101 commented Sep 23, 2025

WHY

This PR upgrades all Token Metrics API endpoints from v2 to v3 to leverage the latest features and improvements provided by Token Metrics. The v3 API introduces several enhancements:

Key Improvements in v3: 🚀

  • Enhanced Filtering 🔍: New parameters like slug, token_name, and expand for more flexible data retrieval
  • Better Data Structure 📊: Improved response formats with more comprehensive token information
  • Standardized Parameters 🎯: Consistent snake_case parameter naming across all endpoints
  • Future-Proof ⚡: v3 is the current stable version with ongoing support and new feature additions

Technical Benefits: 💪

  • Expanded Token Identification 🏷️: Multiple ways to identify tokens (id, symbol, name, slug)
  • Enhanced Market Data 📈: Access to more detailed market metrics and historical data
  • Improved Performance ⚡: Optimized API responses and better caching
  • Consistent API Design 🎨: Unified parameter structure across all endpoints

Migration Details: 🔧

  • Updated base URL from /v2 to /v3 🌐
  • Added new filtering parameters (slug, expand, token_name, sort_by) ✨
  • Renamed scenario-analysis endpoint to price-prediction 🔄
  • Updated all component versions to 0.1.0 📦
  • Maintained backward compatibility where possible 🤝

This upgrade ensures our Pipedream integration stays current with Token Metrics' latest capabilities and provides users access to the most comprehensive crypto data available! 🎉

Summary by CodeRabbit

  • New Features

    • Introduced Price Prediction action (replacing Scenario Analysis).
    • Added new filters across actions: token name, symbol, slug; plus expand and sort-by options where applicable.
    • Expanded OHLCV, price, trading signals, correlation, grades, AI reports, quantmetrics, and indices endpoints with additional identifiers and filters.
  • Refactor

    • Migrated public API surface to TokenMetrics API v3 and updated documentation links.
  • Chores

    • Bumped action and package versions to 0.1.0; adjusted Hourly Trading Signals tokenId flag.

- Update base URL from v2 to v3
- Add slug parameter for token filtering
- Add expand parameter with exchange_list/category_list options
- Update component version to 0.1.0
- Enhance endpoint description with market data details
- Add slug parameter for token filtering
- Add token_name parameter support
- Fix marketcap parameter name (was market_cap)
- Reorder parameters to match v3 API specification
- Update component version to 0.1.0
- Add token_name, symbol, and slug parameters
- Update endpoint description to match v3 specification
- Update component version to 0.1.0
- Enable enhanced token filtering capabilities
- Add slug parameter to daily and hourly OHLCV endpoints
- Add sort_by parameter to moonshot tokens endpoint
- Reorder parameters to match v3 API specification
- Update all component versions to 0.1.0
- Enable enhanced filtering and sorting capabilities
- Add slug parameter to all three endpoints
- Add token_name parameter to quantmetrics endpoint
- Fix marketcap parameter name in quantmetrics
- Update all component versions to 0.1.0
- Enable enhanced token filtering and identification across endpoints
- Add slug parameter to all four endpoints
- Add token_name and symbol parameters to hourly trading signals
- Add token_name parameter to resistance & support endpoint
- Update all component versions to 0.1.0
- Enable enhanced token filtering and identification across all endpoints
- Remove required constraint from hourly trading signals token_id parameter
…s for v3 API

- Add slug parameter to tm-grades and tm-grades-historical endpoints
- Rename scenario-analysis to price-prediction endpoint
- Update SCENARIO_ANALYSIS constant to PRICE_PREDICTION in constants
- Add token_name and slug parameters to price-prediction endpoint
- Update getPricePrediction method name in token_metrics.app.mjs
- Update market-metrics component version to 0.1.0
- Remove old scenario-analysis directory after migration
- Update all affected component versions to 0.1.0
…ts for v3 API

- Add token_name parameter to ai-reports endpoint
- Add expand parameter to top-market-cap-tokens endpoint
- Update crypto-investors endpoint version
- Update all component versions to 0.1.0
- Enable enhanced filtering and data expansion capabilities
- Add token_name and slug parameters to correlation endpoint
- Update indices, indices-holdings, and indices-performance endpoint versions
- Update component versions to 0.1.0
- Enable enhanced filtering capabilities for correlation analysis
- Remove get-token-metrics-ai component as it's not needed
- Clean up unused TMAI endpoint implementation
- Maintain clean codebase for v3 API migration
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 23, 2025

Walkthrough

Token Metrics integration updated to use API v3, many actions bumped to version 0.1.0, PRICE_PREDICTION replaced SCENARIO_ANALYSIS, app propDefinitions added (slug, expand, sortBy), constants extended with new filters (token_name, slug, expand, sort_by) and several actions gained new public props (tokenName, symbol, slug, expand, sortBy).

Changes

Cohort / File(s) Summary of Changes
Core app + constants
components/token_metrics/token_metrics.app.mjs, components/token_metrics/common/constants.mjs
Base URL v2 → v3; add propDefinitions slug, expand, sortBy; rename getScenarioAnalysisgetPricePrediction and endpoint /scenario-analysis/price-prediction; extend endpoint filters (add token_name, slug, expand, sort_by); rename market_capmarketcap; description normalizations.
Price Prediction action
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs
Replace SCENARIO_ANALYSIS with PRICE_PREDICTION; update key, name, description, version0.1.0; add props tokenName, slug; call getPricePrediction internally; update docs link and user-facing text.
Trading signals actions
components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs, components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs
Bump versions to 0.1.0; update docs links to v3; reshape props (add tokenName, symbol, slug, reintroduce startDate/endDate in surface as appropriate); remove explicit optional: false for tokenId in hourly variant.
OHLCV actions
components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs, components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs
Version → 0.1.0; docs → v3; add tokenName prop; change slug to use propDefinition: [ tokenMetrics, "slug" ]; minor description/prop ordering adjustments.
Grades-related actions (incl. historical)
components/token_metrics/actions/get-tm-grades/*.mjs, .../get-fundamental-grades*.mjs, .../get-technology-grades*.mjs
Version → 0.1.0; docs → v3; add slug propDefinition to each action.
Price / Quantmetrics / Correlation / Resistance / AI Reports
components/token_metrics/actions/get-price/get-price.mjs, .../get-quantmetrics/get-quantmetrics.mjs, .../get-correlation/get-correlation.mjs, .../get-resistance-support/get-resistance-support.mjs, .../get-ai-reports/get-ai-reports.mjs
Version → 0.1.0; docs → v3; add combinations of tokenName, symbol, slug per action; AI Reports adds tokenName.
Token listings & rankings
components/token_metrics/actions/get-tokens/get-tokens.mjs, .../get-top-market-cap-tokens/get-top-market-cap-tokens.mjs, .../get-moonshot-tokens/get-moonshot-tokens.mjs
Version → 0.1.0; docs → v3; get-tokens adds slug, expand; top-market-cap adds expand; moonshot-tokens adds sortBy.
Version bumps only
components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs, components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs, components/token_metrics/actions/get-indices/*, components/token_metrics/package.json
Update version fields to 0.1.0 and docs links to v3 where applicable; no runtime logic changes.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Action as Action (Get Price Prediction)
  participant App as TokenMetrics App
  participant API as Token Metrics API (v3)

  User->>Action: invoke(actionProps: tokenId/tokenName/slug, other filters)
  Action->>App: getPricePrediction(filters)
  note right of App: Builds query using new filters\n(slug, token_name, expand, sort_by)
  App->>API: GET /v3/price-prediction?{filters}
  API-->>App: 200 OK (JSON)
  App-->>Action: parsed response
  Action-->>User: return data
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

I’m a rabbit with keys, hopping through code,
Switched v2 to v3 on a bright data road.
Slugs and names snug in tidy arrays,
Moonshots sorted in carrot-lit ways.
Predictions now bloom — hop on, let’s decode!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title Check ✅ Passed The title "Token metrics v3 upgrade" is concise and directly summarizes the primary change in this changeset—upgrading the Token Metrics integration to v3—making it clear and relevant for reviewers scanning history. It avoids noise and accurately reflects the main intent of the PR.
Description Check ✅ Passed The PR description follows the repository's WHY template and clearly documents motivation and migration details, including base URL changes, added filters (slug, token_name, expand, sort_by), the scenario-analysis → price-prediction rename, and version bumps; it provides sufficient context for reviewers to assess scope and impact. The description is on-topic, detailed, and notes backward compatibility considerations.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adolfo-pd adolfo-pd added the User submitted Submitted by a user label Sep 23, 2025
@pipedream-component-development
Copy link
Collaborator

Thank you so much for submitting this! We've added it to our backlog to review, and our team has been notified.

@pipedream-component-development
Copy link
Collaborator

Thanks for submitting this PR! When we review PRs, we follow the Pipedream component guidelines. If you're not familiar, here's a quick checklist:

@vercel
Copy link

vercel bot commented Sep 23, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Sep 24, 2025 2:41pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Sep 24, 2025 2:41pm

- Increment package version to reflect v3 API migration
- Align with Pipedream versioning guidelines for updated components
- All component versions now consistently at 0.1.0
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (14)
components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (2)

15-34: Expose v3 filter props so users can utilize new filters.

If v3 adds filters for this endpoint (e.g., tokenName, slug, symbol, expand, sortBy), consider exposing them as props so buildParams can pass them through.

Assuming these propDefinitions exist in token_metrics.app.mjs, a sketch:

   props: {
     tokenMetrics,
     // Pagination props
     limit: {
       propDefinition: [
         tokenMetrics,
         "limit",
       ],
       description: "Limit the number of items in response. Defaults to 50",
       default: 50,
     },
     page: {
       propDefinition: [
         tokenMetrics,
         "page",
       ],
       min: 1,
       default: 1,
     },
+    // Optional v3 filters (if supported by this endpoint)
+    tokenName: {
+      propDefinition: [
+        tokenMetrics,
+        "tokenName",
+      ],
+      optional: true,
+    },
+    slug: {
+      propDefinition: [
+        tokenMetrics,
+        "slug",
+      ],
+      optional: true,
+    },
+    symbol: {
+      propDefinition: [
+        tokenMetrics,
+        "symbol",
+      ],
+      optional: true,
+    },
+    expand: {
+      propDefinition: [
+        tokenMetrics,
+        "expand",
+      ],
+      optional: true,
+    },
+    sortBy: {
+      propDefinition: [
+        tokenMetrics,
+        "sortBy",
+      ],
+      optional: true,
+    },
   },

If these propDefinitions don’t exist for this endpoint, skip or replace with the supported ones from endpoint.filters.


48-50: Include pagination in the summary (optional).

Small UX improvement to help users see which page/limit produced the result.

-    $.export("$summary", `Successfully retrieved ${dataLength} crypto investors${filterSummary}`);
+    $.export("$summary", `Successfully retrieved ${dataLength} crypto investors (page ${this.page}, limit ${this.limit})${filterSummary}`);
components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (1)

24-29: Prevent conflicting identifiers (tokenId, tokenName, symbol, slug).

Add a lightweight guard so users don’t pass multiple identifiers at once.

Add before building params in run():

const ids = [this.tokenId, this.tokenName, this.symbol, this.slug].filter(Boolean);
if (ids.length > 1) {
  throw new Error("Provide only one of tokenId, tokenName, symbol, or slug");
}

Also confirm endpoint.filters includes tokenName and slug for this endpoint.

Also applies to: 36-41

components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (1)

13-13: Version bump LGTM; add optional date-range validation.

Add before building params:

if (this.startDate && this.endDate && new Date(this.startDate) > new Date(this.endDate)) {
  throw new Error("startDate must be <= endDate");
}
components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (1)

37-42: Guard against multiple token identifiers (tokenId, tokenName, symbol, slug).

Add before building params:

const ids = [this.tokenId, this.tokenName, this.symbol, this.slug].filter(Boolean);
if (ids.length > 1) {
  throw new Error("Provide only one of tokenId, tokenName, symbol, or slug");
}

Ensure endpoint.filters includes slug for this endpoint.

components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (1)

37-42: Guard against multiple token identifiers; add optional date-range check.

Add before building params:

const ids = [this.tokenId, this.tokenName, this.symbol, this.slug].filter(Boolean);
if (ids.length > 1) throw new Error("Provide only one of tokenId, tokenName, symbol, or slug");
if (this.startDate && this.endDate && new Date(this.startDate) > new Date(this.endDate)) {
  throw new Error("startDate must be <= endDate");
}

Confirm slug is supported in endpoint.filters.

components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1)

13-13: Version bump LGTM; consider date-range validation.

Add before building params:

if (this.startDate && this.endDate && new Date(this.startDate) > new Date(this.endDate)) {
  throw new Error("startDate must be <= endDate");
}
components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (1)

25-30: Confirm expand filter semantics and document.

  • Verify expand is listed in ENDPOINTS.TOP_MARKET_CAP_TOKENS.filters and type matches API (boolean vs enum vs CSV).
  • Optional: add a short description to set user expectations on payload size.
components/token_metrics/actions/get-tokens/get-tokens.mjs (3)

54-59: Add a brief description to slug (optional) and verify filter wiring.

Confirm ENDPOINTS.TOKENS.filters includes slug; consider adding a one‑line description like other props.


60-65: Confirm expand mapping and add description (optional).

Ensure expand is supported by the TOKENS endpoint and note expected values/format.


67-79: Align pagination defaults with other actions.

Other actions default limit=50 and page=1. Make this consistent here.

Apply this diff:

     limit: {
       propDefinition: [
         tokenMetrics,
         "limit",
       ],
+      description: "Limit the number of items in response. Defaults to 50",
+      default: 50,
     },
     page: {
       propDefinition: [
         tokenMetrics,
         "page",
       ],
+      min: 1,
+      default: 1,
     },
components/token_metrics/actions/get-price/get-price.mjs (1)

25-42: Validate new filters (tokenName, symbol, slug) and define precedence.

  • Ensure ENDPOINTS.PRICE.filters includes all three so buildParams forwards them.
  • If multiple identifiers are provided, document or enforce precedence to avoid ambiguous queries.
components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (1)

24-29: Confirm sortBy contract and expose choices (optional).

  • Verify ENDPOINTS.MOONSHOT_TOKENS.filters includes sort_by and acceptable values.
  • Optional: expose enum options (or async options) on sortBy for better UX.
components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (1)

61-68: Validate mutually exclusive identifiers (tokenId, tokenName, symbol, slug).

Prevent ambiguous queries by enforcing only one identifier input.

Apply this diff:

   async run({ $ }) {
-    // Build parameters using utility function
-    const params = buildParams(this, endpoint.filters);
+    // Guard: only one identifier filter may be provided
+    const identifiers = [this.tokenId, this.tokenName, this.symbol, this.slug].filter(Boolean);
+    if (identifiers.length > 1) {
+      throw new Error("Provide only one of tokenId, tokenName, symbol, or slug");
+    }
+    // Build parameters using utility function
+    const params = buildParams(this, endpoint.filters);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 946cafd and 376e000.

📒 Files selected for processing (27)
  • components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2 hunks)
  • components/token_metrics/actions/get-correlation/get-correlation.mjs (2 hunks)
  • components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1 hunks)
  • components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2 hunks)
  • components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (1 hunks)
  • components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (1 hunks)
  • components/token_metrics/actions/get-indices/get-indices.mjs (1 hunks)
  • components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1 hunks)
  • components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (4 hunks)
  • components/token_metrics/actions/get-price/get-price.mjs (2 hunks)
  • components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (2 hunks)
  • components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tokens/get-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (2 hunks)
  • components/token_metrics/common/constants.mjs (11 hunks)
  • components/token_metrics/package.json (1 hunks)
  • components/token_metrics/token_metrics.app.mjs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (1)
components/token_metrics/common/constants.mjs (2)
  • ENDPOINTS (2-253)
  • ENDPOINTS (2-253)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (38)
components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1)

13-13: Confirmed — action is wired to v3
ENDPOINTS.CRYPTO_INVESTORS.path = "/crypto-investors" and tokenMetrics._baseUrl() = "https://api.tokenmetrics.com/v3"; getCryptoInvestors calls makeApiCall with "/crypto-investors", so the version bump (0.1.0) is backed by the v3 API.

components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-indices/get-indices.mjs (1)

13-13: Version bump LGTM; confirm indicesType values match API.

If indicesType supports only "active" | "passive", ensure propDefinition enforces those options.

components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (1)

13-13: Approve — v3 wiring for indices-holdings verified

ENDPOINTS.INDICES_HOLDINGS.path is "/indices-holdings" (filters: ["id"]); tokenMetrics.getIndicesHoldings exists and calls that endpoint; the action uses endpoint.filters and exposes the id prop — no changes required.

components/token_metrics/package.json (1)

3-3: Package version bump LGTM — confirm action versions & v3 migration

  • components/token_metrics/package.json: "version": "0.1.0".
  • token_metrics.app.mjs uses base URL "https://api.tokenmetrics.com/v3" (line 201) — v3 is in use.
  • getPricePrediction is implemented and called (components/token_metrics/token_metrics.app.mjs:426; components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs:64). getScenarioAnalysis not found.
  • No package.json files under components/token_metrics/actions — cannot verify per-action version fields; confirm action package versions or that the bump is intended only at the top level.
components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2)

13-13: Version bump LGTM.


37-42: Slug wiring verified; description optional.

ENDPOINTS.TECHNOLOGY_GRADES.filters includes "slug" and token_metrics.app.mjs defines the slug prop; getTechnologyGrades and supporting utils are present.

Optional: add a short description for UX consistency — apply this diff:

     slug: {
       propDefinition: [
         tokenMetrics,
         "slug",
       ],
+      description: "Token slugs (e.g., bitcoin, ethereum) to filter results.",
     },
components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (2)

13-13: Version bump LGTM.


37-42: Confirm slug is supported by this endpoint and utils.

  • Check ENDPOINTS.TM_GRADES_HISTORICAL.filters contains slug so buildParams includes it.
  • If multiple ID/name filters are set simultaneously, define precedence in the app docs.
components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2)

13-13: Version bump LGTM.


25-30: Verify tokenName filter support for AI Reports.

Ensure ENDPOINTS.AI_REPORTS.filters includes tokenName and the backend accepts it with tokenId/symbol. If multiple are provided, clarify precedence.

components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-tokens/get-tokens.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-price/get-price.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (1)

13-13: Version bump LGTM.

components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2)

13-13: Version bump looks good for v3 API upgrade

The version increment to 0.1.0 is appropriate for the API surface changes being introduced.


37-42: slug propDefinition present — no action required

components/token_metrics/token_metrics.app.mjs defines slug in propDefinitions (type: string[], optional: true).

components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (2)

13-13: Version bump is consistent across actions

The version update to 0.1.0 aligns with other actions in this v3 upgrade.


24-29: New filter props follow the established pattern

The addition of tokenName and slug props is consistent with the v3 API expansion across all actions.

Also applies to: 36-41

components/token_metrics/actions/get-correlation/get-correlation.mjs (1)

24-41: Filter props addition is consistent

The new tokenName and slug props follow the same propDefinition pattern as other updated actions.

components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2)

18-24: Good change making tokenId optional

Removing the explicit optional: false makes the prop optional by default, which provides more flexibility for users who might want to filter by other criteria like tokenName or slug.


25-42: Complete set of filter props added

The addition of tokenName, symbol, and slug provides users with multiple ways to identify tokens, which improves the action's usability.

components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2)

24-30: Clear prop description for tokenName

The description with example "Bitcoin" helps users understand the expected format.


37-42: Proper separation of slug prop

The slug prop now correctly references its own propDefinition instead of being tied to tokenName, which improves maintainability.

components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (1)

24-52: Consistent prop additions with date filters

The addition of tokenName, symbol, slug along with startDate and endDate props provides comprehensive filtering options for trading signals.

components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (4)

10-13: Action metadata properly updated for the new endpoint

The key, name, description, and documentation link have all been updated to reflect the price prediction functionality.


74-74: Summary message updated correctly

The export summary properly reflects the new price prediction functionality.


7-7: PRICE_PREDICTION endpoint confirmed in constants
ENDPOINTS.PRICE_PREDICTION is defined in components/token_metrics/common/constants.mjs (around line 208) — no change required.


64-64: Resolved — getPricePrediction exists

Found implementation at components/token_metrics/token_metrics.app.mjs:426; the action's call is valid.

components/token_metrics/token_metrics.app.mjs (2)

113-128: LGTM on expand prop

Values align with API (exchange_list, category_list).


426-433: Scenario Analysis → Price Prediction migration — approved
Endpoint/method rename looks good; repo-wide search found only getPricePrediction (/price-prediction) usages and no occurrences of getScenarioAnalysis or /scenario-analysis.

components/token_metrics/common/constants.mjs (3)

208-217: PRICE_PREDICTION endpoint replacement looks good

New endpoint config aligns with the app method change.


5-5: Copy updates LGTM

Descriptions improved/standardized.

Also applies to: 37-37, 47-47, 59-59


22-24: Camel vs snake case alignment across filters — central normalizer present

buildParams in components/token_metrics/common/utils.mjs maps snake_case endpoint filter keys → camelCase props using toCamelCase and joins array props to CSV; token_metrics actions call buildParams to build params from endpoint.filters.

components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2)

13-13: Semver bump looks appropriate.

Adding a new public prop justifies the 0.1.0 bump.


37-42: slug prop wiring: in-code wiring verified — confirm external API accepts slug

  • propDefinition present in components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs
  • ENDPOINTS.TM_GRADES.filters includes "slug" (components/token_metrics/common/constants.mjs)
  • buildParams uses endpoint.filters (components/token_metrics/common/utils.mjs) and getTmGrades accepts/forwards params (components/token_metrics/token_metrics.app.mjs + actions/get-tm-grades/get-tm-grades.mjs)
  • Action: verify the external /tm-grade API supports slug as a query param

- Update documentation links from /reference/ to /v3/reference/
- Ensure all action components point to correct v3 API documentation
- Maintain consistency across all Token Metrics components
- Updated 23 action components with new v3 documentation URLs
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1)

39-43: CRYPTO_INVESTORS.filters missing — update constants to match v3

token_metrics.app.mjs already targets https://api.tokenmetrics.com/v3 and getCryptoInvestors calls "/crypto-investors", but components/token_metrics/common/constants.mjs defines CRYPTO_INVESTORS.filters = [] — populate this array with the v3-supported filter keys so buildParams/generateFilterSummary expose the correct filter props. Location: components/token_metrics/common/constants.mjs (CRYPTO_INVESTORS.filters). Action using it: components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs.

components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (1)

43-50: Remove incorrect 30‑day constraint from startDate description

Token Metrics v3 daily-ohlcv does not restrict the startDate parameter to the past 30 days — update the description to remove or clarify the 30‑day limitation.

File: components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (startDate property, lines 43–50)

🧹 Nitpick comments (2)
components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1)

15-34: Confirm v3 filter coverage for this action

PR mentions new v3 filters (slug, token_name, expand, sort_by). This action only exposes pagination; verify if additional filters apply to Crypto Investors and, if so, surface them as optional props via propDefinitions.

components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (1)

43-56: Add basic startDate/endDate validation

Guard obvious user input errors before calling the API.

Apply:

   async run({ $ }) {
-    // Build parameters using utility function
+    // Build parameters using utility function
+    if (this.startDate && this.endDate && new Date(this.startDate) > new Date(this.endDate)) {
+      throw new Error("startDate must be on or before endDate");
+    }
     const params = buildParams(this, endpoint.filters);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 946cafd and 376e000.

📒 Files selected for processing (27)
  • components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2 hunks)
  • components/token_metrics/actions/get-correlation/get-correlation.mjs (2 hunks)
  • components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1 hunks)
  • components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2 hunks)
  • components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (1 hunks)
  • components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (1 hunks)
  • components/token_metrics/actions/get-indices/get-indices.mjs (1 hunks)
  • components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1 hunks)
  • components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (4 hunks)
  • components/token_metrics/actions/get-price/get-price.mjs (2 hunks)
  • components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (2 hunks)
  • components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tokens/get-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (2 hunks)
  • components/token_metrics/common/constants.mjs (11 hunks)
  • components/token_metrics/package.json (1 hunks)
  • components/token_metrics/token_metrics.app.mjs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (2)
components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (4)
  • endpoint (7-7)
  • response (54-57)
  • dataLength (63-63)
  • filterSummary (60-60)
components/token_metrics/common/constants.mjs (2)
  • ENDPOINTS (2-253)
  • ENDPOINTS (2-253)
🔇 Additional comments (68)
components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (2)

13-13: Version bump to 0.1.0 — OK

Matches PR intent; no behavioral changes introduced here.


12-12: Update docs URL to v3 guide

Replace the v2 reference link with the v3 docs URL.

-  description: `${endpoint.description}. [See the documentation](https://developers.tokenmetrics.com/reference/crypto-investors)`,
+  description: `${endpoint.description}. [See the documentation](https://developers.tokenmetrics.com/docs/crypto-investors-guide)`,
components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (2)

13-13: Version bump to 0.1.0 is appropriate.


25-30: Confirm expand is wired end-to-end (propDefinition → filters → request).

Sandbox ripgrep returned no matches; I couldn't verify. Manually check:

  • components/token_metrics/token_metrics.app.mjs — propDefinition includes "expand".
  • components/token_metrics/common/constants.mjs — ENDPOINTS.TOP_MARKET_CAP_TOKENS.filters contains "expand".
  • components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (or the shared buildParams) maps and passes "expand" into the request query (use snake_case if the API expects it).

Run locally:
rg -nP '\bexpand\b' components/token_metrics -S
rg -nP 'TOP_MARKET_CAP_TOKENS' components/token_metrics -S
rg -nP '\bbuildParams\b' components/token_metrics -S

components/token_metrics/actions/get-correlation/get-correlation.mjs (2)

13-13: Version bump to 0.1.0 is appropriate.


36-41: Confirm slug filter support in constants and app.

Ensure ENDPOINTS.CORRELATION.filters includes slug, and the app propDefinition exists so buildParams includes it when set.

components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (2)

13-13: Version bump to 0.1.0 is appropriate.


18-25: Keep id as the query parameter for v3 — no change required

Confirmed: Token Metrics v3 "indices-holdings" uses the id query parameter per the official docs.

components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (2)

13-13: Version bump to 0.1.0 is appropriate.


25-38: Resolved — buildParams already maps startDate/endDate to start_date/end_date.

buildParams converts snake_case filter keys to camelCase to read props and assigns params using the original snake_case keys (see components/token_metrics/common/utils.mjs: buildParams/toCamelCase).

  • Optional: include id in the execution summary — e.g. $.export("$summary", Successfully retrieved historical performance data for index ${this.id ?? "N/A"} with ${dataLength} data points${filterSummary});
components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (2)

13-13: Version bump to 0.1.0 is appropriate.


37-42: Approve — slug present in TM_GRADES_HISTORICAL.filters

Verified ENDPOINTS.TM_GRADES_HISTORICAL.filters (components/token_metrics/common/constants.mjs) includes "slug", so buildParams will include it.

components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2)

13-13: Version bump to 0.1.0 is appropriate.


37-42: Slug prop addition aligns with v3 filters.

Confirm constants and mapping support it (same checks as historical).

components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1)

13-13: Approve: bump to 0.1.0 — v3 base URL and getMarketMetrics verified

Confirmed _baseUrl() returns "https://api.tokenmetrics.com/v3" (components/token_metrics/token_metrics.app.mjs:200–216) and getMarketMetrics is defined/bound (components/token_metrics/token_metrics.app.mjs:356) and invoked from actions/get-market-metrics (components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs:54–56).

components/token_metrics/package.json (1)

3-3: Version bump OK — verify action versions & remove legacy scenario-analysis

Confirm all actions in components/token_metrics/actions export version: "0.1.0" and remove/deprecate any v2-only actions (e.g., scenario-analysis). Manual verification required — repository search returned no matches in the sandbox.

components/token_metrics/actions/get-indices/get-indices.mjs (1)

13-13: Version bump looks good.

No functional changes here; aligns with the v3 upgrade sweep.

components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (3)

13-13: Version bump confirmed.

Consistent with package/action updates.


24-29: Confirm token_name filter wiring — OK.

ENDPOINTS.RESISTANCE_SUPPORT.filters includes "token_name"; buildParams uses toCamelCase('token_name') → "tokenName" to read props.tokenName and assigns params["token_name"] (handles arrays) — mapping verified.


36-41: Slug filter supported — no changes required.
RESISTANCE_SUPPORT.filters includes "slug"; buildParams reads props.slug and sets params["slug"] (arrays are joined to a comma string); getResistanceSupport sends those params to /resistance-support.

components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (2)

13-13: Version bump OK.


37-42: Confirmed — 'slug' is a valid filter and is sent to the API
FUNDAMENTAL_GRADES_HISTORICAL.filters includes "slug" (components/token_metrics/common/constants.mjs), buildParams (components/token_metrics/common/utils.mjs) reads the camelCased prop (this.slug) and sets params['slug'] (joins arrays with commas), and token_metrics.app.mjs defines the slug prop.

components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2)

13-13: Version bump OK.


25-30: AI_REPORTS supports token_name; do not add slug (not present).

constants.mjs lists AI_REPORTS.filters including "token_name" and get-ai-reports.mjs already maps tokenName → token_name via the propDefinition; AI_REPORTS does not include "slug", so don’t add a slug prop.

components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (2)

13-13: Version bump OK.


37-42: Slug filter wiring confirmed — no changes needed.
FUNDAMENTAL_GRADES in components/token_metrics/common/constants.mjs includes slug, token_metrics.app.mjs exposes propDefinitions.slug, and get-fundamental-grades references it via propDefinition([tokenMetrics, "slug"]).

components/token_metrics/actions/get-tokens/get-tokens.mjs (1)

13-13: Version bump OK.

components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (2)

13-13: Version bump OK.


24-29: sortBy → sort_by mapping and allowed values validated

buildParams maps the filter key "sort_by" → prop "sortBy" (toCamelCase) and sends the API param "sort_by"; ENDPOINTS.MOONSHOT_TOKENS includes "sort_by"; token_metrics.app.mjs enumerates the supported values (moonshot_at, roi_pct, tm_grade, market_cap_usd); get-moonshot-tokens correctly references tokenMetrics.sortBy.

components/token_metrics/actions/get-price/get-price.mjs (4)

13-13: Version bump OK.


25-30: token_name support for Price endpoint confirmed.
ENDPOINTS.PRICE.filters includes "token_name"; toCamelCase + buildParams map tokenName → token_name (arrays joined); token_metrics.app defines tokenName and get-price uses it — no changes required.


31-36: Symbol prop matches v3 PRICE filter.

Confirmed "symbol" is listed in ENDPOINTS.PRICE.filters and in FILTER_DEFINITIONS (snake_case), and the action uses propDefinition "symbol" — no change required.


37-42: Slug support confirmed for PRICE — no change needed. ENDPOINTS.PRICE.filters contains "slug" and token_metrics.app.mjs defines the slug propDefinition which get-price references.

components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2)

13-13: Version bump aligns with v3 migration — LGTM

No issues with the version update.


25-42: tokenName/symbol/slug propDefinitions and mapping verified

propDefinitions exist in components/token_metrics/token_metrics.app.mjs; buildParams in components/token_metrics/common/utils.mjs converts snake_case keys (from components/token_metrics/common/constants.mjs) to camelCase props and joins arrays into comma-separated API params; getHourlyTradingSignals calls /hourly-trading-signals with those params. If the endpoint requires at least one identifier, add a lightweight validation in components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs before calling the API.

components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2)

13-13: Version bumped — LGTM


37-42: Added slug filter — LGTM

Matches constants and v3 filter set.

components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2)

13-13: Version bumped — LGTM


24-30: tokenName prop addition — LGTM

Description is clear and consistent with other actions.

components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2)

13-13: Version bumped — LGTM


37-42: Added slug filter — LGTM

components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (2)

13-13: Version bumped — LGTM


24-30: Clarify whether multiple token names are supported

Keep description consistent. If comma‑separated lists are supported, say so explicitly; otherwise use a single‑value example.

-      description: "Select crypto asset names to filter results. Example: `Bitcoin,Ethereum`",
+      description: "Select crypto asset names to filter results. Example: `Bitcoin`",
components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (1)

13-13: Version bumped — LGTM

components/token_metrics/token_metrics.app.mjs (6)

113-128: LGTM on expand prop and options

Options match the documented values: exchange_list, category_list.


201-201: Confirm v3 base URL and endpoint availability before merging

The switch to v3 impacts all actions. Please verify the base URL and any renamed paths (e.g., /price-prediction) are valid in v3.

Token Metrics API v3 base URL and endpoints: What is the official base URL for Token Metrics API v3? Does the v3 API document the `/price-prediction`, `/tm-grade`, `/hourly-ohlcv`, and `/daily-ohlcv` endpoints?

Recommended hardening (optional): make the base URL configurable or add a brief comment with a link to v3 docs.


426-433: Verify /price-prediction path (formerly scenario-analysis)

Double-check that /price-prediction exists on v3; otherwise provide a backward-compatible alias or gate behind a flag.

Optional alias to keep compatibility if needed (outside this range):

// Add alongside getPricePrediction for BC
async getScenarioAnalysis({ $ = this, params = {} }) {
  return this.makeApiCall({ $, endpoint: "/scenario-analysis", params });
}

200-234: Add centralized param normalization (arrays → CSV, camelCase → snake_case)

Many props are camelCase (tokenId, tokenName, topK, sortBy, marketCap) while endpoints list snake_case (token_id, token_name, top_k, sort_by, and v3 uses marketcap). Arrays currently serialize as repeated params; v3 expects CSV. Normalize once in the app before requests.

Add these helpers under methods and use them in makeApiCall:

// Inside methods:
_toSnake(k) {
  return k.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
},
_normalizeParams(params = {}) {
  const map = {
    tokenId: "token_id",
    tokenName: "token_name",
    topK: "top_k",
    sortBy: "sort_by",
    marketCap: "marketcap", // v3 field
  };
  const out = {};
  for (const [k, v] of Object.entries(params)) {
    if (v == null || v === "") continue;
    const key = map[k] || this._toSnake(k);
    out[key] = Array.isArray(v) ? v.join(",") : v;
  }
  return out;
},

// In makeApiCall before passing params to _makeRequest:
params = this._normalizeParams(params);

107-112: Fix type/description mismatch for slug and ensure array → CSV serialization

Prop is string[] but description says “Comma separated...”. Keep the array UX, but update copy and normalize arrays to CSV in requests.

Apply this diff to adjust the description:

-      description: "Comma separated token slugs. Example: `bitcoin,ethereum`",
+      description: "Select one or more token slugs. Example: `bitcoin`, `ethereum`",

Add a param normalizer in the app (see methods section comment) so arrays serialize as CSV and camelCase props map to snake_case params the API expects.


152-175: sortBy will not be honored; API expects sort_by

Without mapping, requests won’t send the expected param. Either add a normalizer (recommended) or rename the prop key to sort_by.

Minimal fix (if you don’t add a normalizer now):

-    sortBy: {
+    sort_by: {
       type: "string",
       label: "Sort By",
       description: "Field to sort results by. Supported values: moonshot_at, roi_pct, tm_grade, market_cap_usd",
       optional: true,
       options: [

Recommended: keep the current prop name for UX but map sortBysort_by before sending (see methods comment).

components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (3)

13-13: Version bump acknowledged

0.1.0 is appropriate for the v3 migration.


42-53: Map startDate/endDate to start_date/end_date

Confirm buildParams converts these to snake_case; otherwise date filters won’t be sent correctly.


24-41: Ensure snake_case mapping and CSV serialization for new identifier filters

Props are camelCase (tokenName, symbol, slug) but endpoint filters are token_name, symbol, slug. Also slug is an array in the app. Confirm that buildParams maps camelCase → snake_case and joins arrays as CSV; otherwise these filters won’t apply.

You can rely on the app-level normalizer suggested in token_metrics.app.mjs or confirm buildParams already handles it. To verify:

#!/bin/bash
# Inspect buildParams to confirm key mapping and array CSV handling
fd utils.mjs | xargs -I{} sh -c 'echo "---- {} ----"; nl -ba "{}" | sed -n "1,200p"'
components/token_metrics/common/constants.mjs (15)

5-15: LGTM: Added slug and expand to TOKENS filters

Matches the v3 additions described in the PR summary.


37-44: LGTM: PRICE filters expanded (token_name, symbol, slug)

Consistent with v3 identifier flexibility.


47-55: LGTM: HOURLY_OHLCV filter set clarified

Adds symbol and slug; description improved.


59-67: LGTM: DAILY_OHLCV filter set clarified

Adds symbol and slug; description improved.


81-85: LGTM: Added slug to TM grade endpoints

Aligns with v3 identifier support.


155-158: LGTM: AI_REPORTS gains token_name

No issues spotted.


177-181: LGTM: RESISTANCE_SUPPORT adds token_name and slug

Good.


187-191: LGTM: HOURLY_TRADING_SIGNALS adds token_name, symbol, slug

Good.


208-217: New PRICE_PREDICTION endpoint: verify availability

Confirm /price-prediction exists on v3. If it’s a rename of scenario-analysis, note the change in the README and consider a temporary alias for BC.


222-229: LGTM: CORRELATION adds token_name and slug

Good.


255-389: Add missing FILTER_DEFINITIONS for new v3 filters

slug, expand, sort_by, and marketcap are referenced by endpoints but missing here; this breaks prop generation/validation and docs.

Apply the diffs provided above to insert these entries into FILTER_DEFINITIONS.


21-33: Add missing filter definitions and confirm marketcap rename

You reference slug, expand, and marketcap here, but they’re not defined in FILTER_DEFINITIONS. Also, marketcap (no underscore) deviates from prior market_cap. If v3 truly uses marketcap, add that key to definitions; if not, revert to market_cap.

Apply this diff in FILTER_DEFINITIONS (around lines 255+):

   symbol: {
     type: "string",
     label: "Symbol",
     description: "Comma Separated Token Symbols. Example: BTC,ETH",
     optional: true,
   },
+  slug: {
+    type: "string",
+    label: "Slug",
+    description: "Comma separated token slugs. Example: bitcoin,ethereum",
+    optional: true,
+  },
+  expand: {
+    type: "string",
+    label: "Expand",
+    description: "Expand exchange_list or category_list to return full object",
+    optional: true,
+    options: [
+      { label: "Exchange List", value: "exchange_list" },
+      { label: "Category List", value: "category_list" },
+    ],
+  },
   category: {

And add entries for sorting and v3 market cap:

   market_cap: {
     type: "string",
     label: "Market Cap",
     description: "Minimum Market cap in $. Example: 100000000",
     optional: true,
   },
+  marketcap: {
+    type: "string",
+    label: "Market Cap",
+    description: "Minimum market cap in $. Example: 100000000",
+    optional: true,
+  },
+  sort_by: {
+    type: "string",
+    label: "Sort By",
+    description: "Field to sort results by. Supported values: moonshot_at, roi_pct, tm_grade, market_cap_usd",
+    optional: true,
+    options: [
+      { label: "Moonshot At", value: "moonshot_at" },
+      { label: "ROI Percentage", value: "roi_pct" },
+      { label: "TM Grade", value: "tm_grade" },
+      { label: "Market Cap USD", value: "market_cap_usd" },
+    ],
+  },

73-75: Remember to define sort_by

Endpoint now filters by sort_by; ensure it exists in FILTER_DEFINITIONS (see suggested diff).


169-171: Ensure expand is defined

TOP_MARKET_CAP_TOKENS uses expand; add its definition (see suggested diff).


197-206: Confirm marketcap vs market_cap and add definition

QUANTMETRICS now uses marketcap. Add its definition and ensure app-level mapping (marketCapmarketcap).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (1)

44-49: Remove incorrect 30‑day limit note from daily OHLCV description

Daily OHLCV v3 does not enforce a 30‑day startDate cap; remove the misleading note and keep the example.

File: components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (lines 44–49)

-      description: "Start Date accepts date as a string - `YYYY-MM-DD` format. Note: The Start Date cannot be earlier than the past 30 days from the current date. Example: `2025-01-01`",
+      description: "Start Date accepts date as a string - `YYYY-MM-DD` format. Example: `2025-01-01`",
🧹 Nitpick comments (10)
components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (1)

40-55: Optional: add an allPages flag to auto-paginate.

Pipedream guidelines encourage handling pagination. Consider an opt-in boolean to fetch all pages.

Apply minimal diffs:

   limit: {
@@
   page: {
@@
   },
+  allPages: {
+    type: "boolean",
+    label: "Fetch All Pages",
+    description: "If true, fetches all pages and returns a combined result.",
+    optional: true,
+    default: false,
+  },

And in run:

-    const response = await this.tokenMetrics.getIndicesPerformance({
-      $,
-      params,
-    });
+    let response;
+    if (this.allPages) {
+      const all = [];
+      let page = params.page ?? 1;
+      while (true) {
+        const res = await this.tokenMetrics.getIndicesPerformance({ $, params: { ...params, page } });
+        const items = res.data ?? [];
+        all.push(...items);
+        if (!items.length) break;
+        page += 1;
+      }
+      response = { data: all };
+    } else {
+      response = await this.tokenMetrics.getIndicesPerformance({ $, params });
+    }
components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2)

18-24: Token identifier became optional — add a runtime guard to avoid unscoped queries.

If none of tokenId/tokenName/symbol/slug is provided, this may fetch broad results or cause API errors. Require at least one.

Add this check near the start of run():

if (!this.tokenId && !this.tokenName && !this.symbol && !this.slug) {
  throw new Error("Provide at least one of: tokenId, tokenName, symbol, or slug");
}

61-64: Enforce at least one identifier before building params.

Prevents accidental broad queries and aligns with v3’s multi-identifier model.

   async run({ $ }) {
-    // Build parameters using utility function
-    const params = buildParams(this, endpoint.filters);
+    // Require at least one identifier to avoid broad queries
+    if (!this.tokenId && !this.tokenName && !this.symbol && !this.slug) {
+      throw new Error("Provide at least one of: tokenId, tokenName, symbol, or slug");
+    }
+    // Build parameters using utility function
+    const params = buildParams(this, endpoint.filters);
components/token_metrics/actions/get-correlation/get-correlation.mjs (1)

24-29: Confirm tokenName and slug are wired through constants.
Ensure ENDPOINTS.CORRELATION.filters lists tokenName and slug; otherwise buildParams drops them.

Optional: Provide async options for category/exchange if available to improve UX.

Also applies to: 36-41

components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (1)

37-42: Confirm slug presence in TM_GRADES_HISTORICAL filters.
Otherwise the new prop won’t be sent.

Consider validating date range before calling the API:

   async run({ $ }) {
-    // Build parameters using utility function
-    const params = buildParams(this, endpoint.filters);
+    // Optional: basic date validation
+    if (this.startDate && this.endDate) {
+      const s = new Date(this.startDate);
+      const e = new Date(this.endDate);
+      if (!Number.isFinite(s.valueOf()) || !Number.isFinite(e.valueOf())) {
+        throw new Error("startDate/endDate must be valid dates (YYYY-MM-DD).");
+      }
+      if (s > e) {
+        throw new Error("startDate must be less than or equal to endDate.");
+      }
+    }
+    // Build parameters using utility function
+    const params = buildParams(this, endpoint.filters);
components/token_metrics/actions/get-price/get-price.mjs (1)

43-55: Align pagination defaults with other actions.

Other actions default limit=50, page=1. Consider doing the same for consistency.

     limit: {
       propDefinition: [
         tokenMetrics,
         "limit",
       ],
+      default: 50,
     },
     page: {
       propDefinition: [
         tokenMetrics,
         "page",
       ],
+      default: 1,
     },
components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (1)

44-49: Avoid static example that can violate the 30‑day constraint.

Keep the note, but drop the dated example or make it generic.

-      description: "Start Date accepts date as a string - `YYYY-MM-DD` format. Note: The Start Date cannot be earlier than the past 30 days from the current date. Example: `2025-03-01`",
+      description: "Start Date accepts date as a string - `YYYY-MM-DD` format. Note: The Start Date cannot be earlier than the past 30 days from the current date.",
components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (1)

91-102: Optional: add pagination defaults for consistency.

Other actions default to limit=50, page=1.

     limit: {
       propDefinition: [
         tokenMetrics,
         "limit",
       ],
+      default: 50,
     },
     page: {
       propDefinition: [
         tokenMetrics,
         "page",
       ],
+      default: 1,
     },
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (1)

72-75: Make $summary robust to non-array responses

Price prediction might return an object. Compute count defensively.

Apply this diff:

-    const dataLength = response.data?.length || 0;
-    $.export("$summary", `Successfully retrieved price prediction for ${dataLength} tokens${filterSummary}`);
+    const d = response?.data;
+    const count = Array.isArray(d) ? d.length : (d ? 1 : 0);
+    $.export("$summary", `Successfully retrieved price prediction${count ? ` for ${count} tokens` : ""}${filterSummary}`);
components/token_metrics/token_metrics.app.mjs (1)

107-112: Drop “Comma separated” from slug description (type is string[])

Description conflicts with the UX. Keep the example but remove CSV wording.

-      description: "Comma separated token slugs. Example: `bitcoin,ethereum`",
+      description: "Select one or more token slugs to filter results. Example: `bitcoin,ethereum`",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 946cafd and 376e000.

📒 Files selected for processing (27)
  • components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2 hunks)
  • components/token_metrics/actions/get-correlation/get-correlation.mjs (2 hunks)
  • components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1 hunks)
  • components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2 hunks)
  • components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (1 hunks)
  • components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (1 hunks)
  • components/token_metrics/actions/get-indices/get-indices.mjs (1 hunks)
  • components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1 hunks)
  • components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (4 hunks)
  • components/token_metrics/actions/get-price/get-price.mjs (2 hunks)
  • components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (2 hunks)
  • components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tokens/get-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (2 hunks)
  • components/token_metrics/common/constants.mjs (11 hunks)
  • components/token_metrics/package.json (1 hunks)
  • components/token_metrics/token_metrics.app.mjs (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (1)
components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (4)
  • endpoint (7-7)
  • response (54-57)
  • dataLength (63-63)
  • filterSummary (60-60)
🔇 Additional comments (52)
components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (3)

13-13: Version bump LGTM.

Consistent with the PR-wide v3 upgrade.


12-12: Update docs URL to v3 guide.

Link still points to the old v2 “reference” path. Use the v3 guide URL.

-  description: `${endpoint.description}. [See the documentation](https://developers.tokenmetrics.com/reference/crypto-investors)`,
+  description: `${endpoint.description}. [See the documentation](https://developers.tokenmetrics.com/docs/crypto-investors-guide)`,

15-34: No v3 filters for CRYPTO_INVESTORS — nothing to expose.

components/token_metrics/common/constants.mjs shows CRYPTO_INVESTORS.filters = [] and getCryptoInvestors exists in token_metrics.app.mjs, so there are no v3 filter propDefinitions to add.

components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (3)

69-73: Confirm response shape for summary.

response.data?.length assumes data is an array. If v3 returns an object or wraps results differently, the summary will be misleading.

If needed, adjust to reflect the correct array path (e.g., response.data.items?.length).


13-13: Version bump LGTM — all Token Metrics actions are at "0.1.0".

Update changelog/release notes if applicable.


12-12: Confirm the docs link targets v3.
components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs:12 links to https://developers.tokenmetrics.com/reference/indices-performance; neither that page nor the guide explicitly indicate "v3" — update to the explicit v3 docs URL if one exists, or confirm this reference is the correct v3 endpoint.

components/token_metrics/actions/get-indices/get-indices.mjs (3)

13-13: Version bump looks good.

No functional changes introduced here; safe metadata update.


7-8: Resolved — INDICES has indices_type + pagination and the API base is v3.

ENDPOINTS.INDICES includes "indices_type" (components/token_metrics/common/constants.mjs); buildParams maps snake_case filters to props and adds limit/page (components/token_metrics/common/utils.mjs); get-indices action exposes indicesType, limit, page props (components/token_metrics/actions/get-indices/get-indices.mjs); token_metrics._baseUrl() returns https://api.tokenmetrics.com/v3 (components/token_metrics/token_metrics.app.mjs).


56-59: Verify v3 response envelope before using response.data?.length in the summary.

getIndices returns the raw axios response (via makeApiCall/_makeRequest) and _baseUrl() points to v3 — confirm the v3 /indices endpoint returns an array at response.data; if it instead wraps results (e.g. { data: [...] } or { result: [...] }) change the summary to extract/guard the correct array (Array.isArray checks or response.data.data?.length).
Location: components/token_metrics/actions/get-indices/get-indices.mjs (lines ~56–59)

components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2)

13-13: Version bump to 0.1.0 looks good.

Aligned with the v3 migration scope.


25-42: New filters (tokenName, symbol, slug) look correct — verify app and endpoint wiring.

Confirm:

  • propDefinitions exist in token_metrics.app.mjs
  • ENDPOINTS.HOURLY_TRADING_SIGNALS.filters includes these keys so buildParams/generateFilterSummary pick them up

Run:

components/token_metrics/package.json (1)

3-3: Version bump to 0.1.0 looks good.
Aligns with the v3 upgrade intent.

components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (2)

13-13: Action version bump LGTM.
Matches package version update.


24-29: Resolved — buildParams maps sortBy → sort_by
buildParams uses toCamelCase to read props[propKey] and assigns params[key] (snake_case), so the sortBy prop will be mapped to and sent as sort_by.

components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (2)

13-13: Action version bump LGTM.
Consistent with package version.


37-42: Missing FILTER_DEFINITIONS.slug entry blocks prop generation/validation.
You added slug here and across endpoints, but constants.mjs lacks a slug definition; utils that rely on FILTER_DEFINITIONS may break.

See suggested additions in constants.mjs comment.

components/token_metrics/common/constants.mjs (6)

5-15: Add FILTER_DEFINITIONS for new filters used here (slug, expand).
TOKENS now references slug and expand, but FILTER_DEFINITIONS lacks both.

Apply these additions within FILTER_DEFINITIONS:

   symbol: {
     type: "string",
     label: "Symbol",
     description: "Comma Separated Token Symbols. Example: BTC,ETH",
     optional: true,
   },
+  slug: {
+    type: "string",
+    label: "Slug",
+    description: "Comma Separated token slugs. Example: bitcoin,ethereum",
+    optional: true,
+  },
+  expand: {
+    type: "string",
+    label: "Expand",
+    description: "Expand exchange_list or category_list to return full object",
+    optional: true,
+    options: [
+      { label: "Exchange List", value: "exchange_list" },
+      { label: "Category List", value: "category_list" },
+    ],
+  },

69-75: sort_by filter lacks FILTER_DEFINITIONS entry.
Needed for validation and for utilities to render labels/options.

Add:

   type: {
     type: "string",
     label: "Type",
     description: "Accepts 'active' or 'past' to fetch respective moonshots. Defaults to 'active' if not provided",
     optional: true,
     options: [
       { label: "Active", value: "active" },
       { label: "Past", value: "past" },
     ],
     default: "active",
   },
+  sort_by: {
+    type: "string",
+    label: "Sort By",
+    description: "Field to sort results by. Supported values: moonshot_at, roi_pct, tm_grade, market_cap_usd",
+    optional: true,
+    options: [
+      { label: "Moonshot At", value: "moonshot_at" },
+      { label: "ROI Percentage", value: "roi_pct" },
+      { label: "TM Grade", value: "tm_grade" },
+      { label: "Market Cap USD", value: "market_cap_usd" },
+    ],
+  },

166-171: expand filter used but not defined.
Same missing definition as noted above; add expand to FILTER_DEFINITIONS.

(See earlier diff for expand.)


21-33: marketcap filter has no definition (only market_cap exists).
Endpoints use marketcap (no underscore), but FILTER_DEFINITIONS only defines market_cap.

Add marketcap (keep market_cap for backward compatibility):

   end_date: {
     type: "string",
     label: "End Date",
     description: "End Date accepts date as a string - YYYY-MM-DD format. Example: 2023-10-10",
     optional: true,
   },
   market_cap: {
     type: "string",
     label: "Market Cap",
     description: "Minimum Market cap in $. Example: 100000000",
     optional: true,
   },
+  marketcap: {
+    type: "string",
+    label: "Market Cap",
+    description: "Minimum market cap in $. Example: 100000000",
+    optional: true,
+  },

197-206: QUANTMETRICS uses marketcap without definition.
Add FILTER_DEFINITIONS.marketcap to match this endpoint (keep market_cap too).

(See earlier diff for marketcap.)


208-216: Endpoint rename to PRICE_PREDICTION — confirm no stale references.
Ensure app methods, actions, docs, tests and API specs migrated from "scenario-analysis" to "price-prediction". The ripgrep run returned no matches in the sandbox; verify locally with:
rg -n -C2 -P 'scenario[-_ ]analysis|/scenario-analysis|scenario_analysis|SCENARIO_ANALYSIS|getScenarioAnalysis|scenarioAnalysis'
rg -n -C2 --hidden 'price-prediction'
Fix any remaining matches (code, OpenAPI, docs, tests, analytics/events).

components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2)

13-13: Action version bump LGTM.
Consistent with the package / v3 migration.


37-42: slug prop depends on missing FILTER_DEFINITIONS.slug.
Until slug is defined in constants, validation/summary may break.

(See constants.mjs diff to add slug.)

components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (1)

13-13: Semver bump to 0.1.0 looks good.
No runtime / API surface change here. Safe.

components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (2)

13-13: Version bump is appropriate for the public prop additions.
Matches semver for added filters.


24-29: No action required — RESISTANCE_SUPPORT filters include token_name and slug.
Verified ENDPOINTS.RESISTANCE_SUPPORT.filters contains "token_name" and "slug"; base URL uses /v3.

components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1)

13-13: LGTM on version bump.
No functional changes; props and run path unchanged.

components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2)

13-13: Version bump is correct.
Aligns with wider v3 migration.


37-42: Confirm constants expose slug for this endpoint.
If ENDPOINTS.TECHNOLOGY_GRADES.filters doesn’t include slug, it won’t be forwarded.

components/token_metrics/actions/get-correlation/get-correlation.mjs (1)

13-13: Good on version bump.
Public API extended; semver matches.

components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2)

13-13: Semver bump approved.
Matches added slug prop.


37-42: Verify slug is included in endpoint.filters.
Needed for buildParams to forward it.

components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (1)

13-13: Version bump is appropriate.
Public API expanded.

components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2)

13-13: LGTM on version.
Consistent with suite-wide updates.


25-30: Validate app-level propDefinition for tokenName exists.
PropDefinition references require token_metrics.app.mjs to export tokenName; please confirm.

components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (1)

37-42: LGTM on adding slug.

Consistent with other actions and v3 identifier support. No further changes needed here.

components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (1)

24-30: Clarify whether multiple token names are supported (CSV vs single).

Example shows "Bitcoin,Ethereum" but wording says "names". Either explicitly say “comma‑separated list” or show a single example.

-      description: "Select crypto asset names to filter results. Example: `Bitcoin,Ethereum`",
+      description: "Select crypto asset names to filter results (comma-separated). Example: `Bitcoin,Ethereum`",

Or, if only single is supported:

-      description: "Select crypto asset names to filter results. Example: `Bitcoin,Ethereum`",
+      description: "Select crypto asset names to filter results. Example: `Bitcoin`",
components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (2)

24-29: LGTM on adding tokenName.

Matches v3 identifier support and aligns with other actions.


36-41: LGTM on adding slug.

Consistent with the v3 migration pattern.

components/token_metrics/actions/get-tokens/get-tokens.mjs (2)

60-65: expand is a valid filter for TOKENS — no change required

components/token_metrics/common/constants.mjs lists "expand" under TOKENS.filters, so the propDefinition is correct.


54-65: Don't add sortBy — Token Metrics v3 "tokens" endpoint doesn't support sort_by or expand.

API docs list only token filters; do not add the sortBy propDefinition. Confirm or remove the existing "expand" prop in components/token_metrics/actions/get-tokens/get-tokens.mjs if it's undocumented.

Likely an incorrect or invalid review comment.

components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2)

37-42: Confirm slug is wired in constants to match the new prop.

Same reasoning as tokenName—verify "slug" is present in the endpoint’s filters list.


24-30: Ensure endpoint.filters includes tokenName to avoid dropping the param.

If ENDPOINTS.DAILY_OHLCV.filters wasn’t updated with "tokenName", buildParams will omit it.

components/token_metrics/actions/get-price/get-price.mjs (1)

25-42: Confirmed: ENDPOINTS.PRICE.filters contains token_name, symbol, slug — no change needed.

buildParams maps snake_case filter keys to camelCase prop names, so tokenName / symbol / slug props will be included in requests.

components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (1)

42-53: Confirmed: startDate/endDate are valid filters for Trading Signals

TRADING_SIGNALS.filters includes "start_date" and "end_date" in components/token_metrics/common/constants.mjs, so the startDate/endDate props correspond to supported filters and will be included by buildParams.

components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (4)

7-7: Good: endpoint constant updated to PRICE_PREDICTION

Aligns with the constants and PR intent.


24-29: Ensure snake_case mapping: tokenName → token_name

If params aren’t normalized centrally, this prop won’t be sent as token_name and the filter won’t apply.

Please confirm the app implements a camelCase→snake_case normalizer (and CSV join for arrays). If not, see my normalization suggestion in token_metrics.app.mjs.


36-41: Array serialization to CSV for slug

slug is string[]. Verify it’s serialized as a comma‑separated list per v3 expectations.

Same concern previously raised for array props. Confirm normalization joins arrays to CSV.


64-67: Call site looks correct (method renamed)

getPricePrediction usage matches the app method.

Given the base URL change to v3, please verify the /price-prediction path exists in v3 (see related app comment).

components/token_metrics/token_metrics.app.mjs (2)

113-128: Confirm expand param support across endpoints

If expand is not supported universally, document scope or restrict where exposed.

Which endpoints in v3 accept expand=exchange_list|category_list? Consider noting supported endpoints in the description.


152-175: sortBy must be sent as sort_by; add central param normalizer

Without normalization, the API will ignore sortBy. Also fixes all camelCase→snake_case and CSV array serialization.

Apply this diff to add normalization and use it in requests:

   methods: {
     _baseUrl() {
       return "https://api.tokenmetrics.com/v3";
     },
     _headers() {
       return {
         "x-api-key": this.$auth.api_key,
         "Content-Type": "application/json",
       };
     },
+    // Convert camelCase keys to snake_case
+    _toSnake(k) {
+      return k.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
+    },
+    // Normalize params: map known keys and join arrays to CSV per API spec
+    _normalizeParams(params = {}) {
+      const map = {
+        tokenId: "token_id",
+        tokenName: "token_name",
+        topK: "top_k",
+        sortBy: "sort_by",
+        startDate: "start_date",
+        endDate: "end_date",
+        marketCap: "market_cap",
+        blockchainAddress: "blockchain_address",
+        indicesType: "indices_type",
+      };
+      const out = {};
+      for (const [k, v] of Object.entries(params)) {
+        if (v == null || v === "" || (Array.isArray(v) && v.length === 0)) continue;
+        const key = map[k] || this._toSnake(k);
+        out[key] = Array.isArray(v) ? v.join(",") : v;
+      }
+      return out;
+    },
     async _makeRequest({
       $ = this,
       path,
       ...args
     }) {
       const config = {
         url: `${this._baseUrl()}${path}`,
         headers: this._headers(),
         ...args,
       };
 
       return await axios($, config);
     },
     // Generic method for any endpoint
     async makeApiCall({
       $ = this,
       endpoint,
       params = {},
     }) {
-      return this._makeRequest({
+      // Normalize query params before sending
+      const normalized = this._normalizeParams(params);
+      return this._makeRequest({
         $,
         path: endpoint,
         method: "GET",
-        params,
+        params: normalized,
       });
     },

- Simplify example from 'Bitcoin,Ethereum' to 'Bitcoin' for clarity
- Maintain consistency with other component descriptions
- Change expand prop type from 'string' to 'string[]'
- Allow users to select both exchange_list and category_list simultaneously
- Update description to clarify comma-separated sending behavior
- Improve flexibility for data expansion options

Addresses coderabbitai suggestion for enhanced user experience
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (9)
components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (2)

15-25: Expose optional v3 filters if supported by this endpoint (expand, sortBy)

If v3 supports these on indices holdings, surface them so users can leverage v3 features.

   props: {
     tokenMetrics,
     // Filter props based on endpoint configuration and API documentation
     id: {
       propDefinition: [
         tokenMetrics,
         "id",
       ],
       description: "ID of the index. Example: `1`",
     },
+    // Optional: expose v3 filters if supported by this endpoint
+    expand: {
+      propDefinition: [
+        tokenMetrics,
+        "expand",
+      ],
+    },
+    sortBy: {
+      propDefinition: [
+        tokenMetrics,
+        "sortBy",
+      ],
+    },
   },

39-41: Validate response shape for accurate summary length

If v3 wraps holdings differently (e.g., data.items or data.holdings), this may report 0. Make the summary resilient or confirm the shape.

-    const dataLength = response.data?.length || 0;
-    $.export("$summary", `Successfully retrieved holdings for index with ${dataLength} tokens${filterSummary}`);
+    const payload = response?.data ?? response?.results ?? response;
+    const items =
+      Array.isArray(payload)
+        ? payload
+        : payload?.items ?? payload?.holdings ?? payload?.data ?? [];
+    const dataLength = Array.isArray(items) ? items.length : 0;
+    $.export("$summary", `Successfully retrieved holdings for index ${this.id} with ${dataLength} tokens${filterSummary}`);
components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (1)

37-41: Slug prop switch LGTM—clarify behavior when multiple identifiers are provided.

If users set tokenId, symbol, tokenName, and slug together, define precedence or validate only one to avoid ambiguous requests.

components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1)

15-49: Consider exposing v3 filters (expand/sortBy) if supported by Market Metrics.

If v3 supports these on this endpoint, add them so users can access the new capabilities.

Apply if supported by the endpoint:

   props: {
     tokenMetrics,
     // Filter props based on endpoint configuration and API documentation
     startDate: {
       propDefinition: [
         tokenMetrics,
         "startDate",
       ],
       description: "Start Date accepts date as a string - `YYYY-MM-DD` format. Example: `2023-10-01`",
     },
     endDate: {
       propDefinition: [
         tokenMetrics,
         "endDate",
       ],
       description: "End Date accepts date as a string - `YYYY-MM-DD` format. Example: `2023-10-10`",
     },
+    // v3 enhancements (if supported by this endpoint)
+    expand: {
+      propDefinition: [
+        tokenMetrics,
+        "expand",
+      ],
+    },
+    sortBy: {
+      propDefinition: [
+        tokenMetrics,
+        "sortBy",
+      ],
+    },
     // Pagination props
     limit: {
       propDefinition: [
         tokenMetrics,
         "limit",
       ],
       description: "Limit the number of items in response. Defaults to 50",
       default: 50,
     },
components/token_metrics/token_metrics.app.mjs (1)

199-234: Centralize param normalization + add a sane timeout

Avoid per-action drift: map camelCase → snake_case and join arrays to CSV once in the app. Also add a request timeout.

Apply:

   methods: {
+    _toSnake(k) {
+      return k.replace(/[A-Z]/g, (m) => `_${m.toLowerCase()}`);
+    },
+    _normalizeParams(params = {}) {
+      const map = {
+        tokenId: "token_id",
+        tokenName: "token_name",
+        topK: "top_k",
+        sortBy: "sort_by",
+        startDate: "start_date",
+        endDate: "end_date",
+        marketCap: "market_cap",
+        blockchainAddress: "blockchain_address",
+        indicesType: "indices_type",
+      };
+      const out = {};
+      for (const [k, v] of Object.entries(params)) {
+        if (v == null || v === "") continue;
+        const key = map[k] || this._toSnake(k);
+        out[key] = Array.isArray(v) ? v.join(",") : v;
+      }
+      return out;
+    },
     _baseUrl() {
       return "https://api.tokenmetrics.com/v3";
     },
     _headers() {
       return {
         "x-api-key": this.$auth.api_key,
         "Content-Type": "application/json",
       };
     },
     async _makeRequest({
       $ = this,
       path,
       ...args
     }) {
       const config = {
         url: `${this._baseUrl()}${path}`,
         headers: this._headers(),
+        timeout: 30000,
         ...args,
       };
 
       return await axios($, config);
     },
     // Generic method for any endpoint
     async makeApiCall({
       $ = this,
       endpoint,
       params = {},
     }) {
       return this._makeRequest({
         $,
         path: endpoint,
         method: "GET",
-        params,
+        params: this._normalizeParams(params),
       });
     },
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (2)

64-67: Harden against unknown endpoint errors

Since the upstream app hits /price-prediction, consider catching 404 to provide a helpful message.

Apply:

-    const response = await this.tokenMetrics.getPricePrediction({
-      $,
-      params,
-    });
+    let response;
+    try {
+      response = await this.tokenMetrics.getPricePrediction({ $, params });
+    } catch (err) {
+      if (err?.response?.status === 404) {
+        throw new Error("Price prediction endpoint not available. Verify Token Metrics API supports /price-prediction or switch to the Scenario Analysis/Price endpoints.");
+      }
+      throw err;
+    }

74-74: Summary robustness

Response may not be an array. Consider deriving count defensively.

Apply:

-    const dataLength = response.data?.length || 0;
+    const data = response.data;
+    const dataLength = Array.isArray(data) ? data.length : (data ? 1 : 0);
components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (1)

42-53: Validate date range before issuing the request.

Prevent avoidable 4xxs by enforcing startDate <= endDate when both are provided.

   async run({ $ }) {
+    // Validate date range
+    if (this.startDate && this.endDate) {
+      if (new Date(this.startDate) > new Date(this.endDate)) {
+        throw new Error("startDate must be before or equal to endDate");
+      }
+    }
components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (1)

36-41: Confirm: slug is supported; don't add expand/sortBy (endpoint doesn't expose them); consider documenting/validating token-filter precedence

  • Verified: components/token_metrics/token_metrics.app.mjs exposes slug (and has global expand/sortBy props); ENDPOINTS.RESISTANCE_SUPPORT.filters include "slug" but NOT "expand"/"sort_by".
  • Action: do not add expand/sortBy props to this action unless the endpoint.filters are updated to include them.
  • Optional: enforce or document that only one of tokenId/tokenName/symbol/slug may be provided (components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs).
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 376e000 and 17c1487.

📒 Files selected for processing (25)
  • components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2 hunks)
  • components/token_metrics/actions/get-correlation/get-correlation.mjs (2 hunks)
  • components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs (1 hunks)
  • components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (2 hunks)
  • components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs (2 hunks)
  • components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (1 hunks)
  • components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs (1 hunks)
  • components/token_metrics/actions/get-indices/get-indices.mjs (1 hunks)
  • components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (1 hunks)
  • components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (4 hunks)
  • components/token_metrics/actions/get-price/get-price.mjs (2 hunks)
  • components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs (2 hunks)
  • components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs (2 hunks)
  • components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs (2 hunks)
  • components/token_metrics/actions/get-tokens/get-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs (2 hunks)
  • components/token_metrics/actions/get-trading-signals/get-trading-signals.mjs (2 hunks)
  • components/token_metrics/token_metrics.app.mjs (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (16)
  • components/token_metrics/actions/get-indices-performance/get-indices-performance.mjs
  • components/token_metrics/actions/get-top-market-cap-tokens/get-top-market-cap-tokens.mjs
  • components/token_metrics/actions/get-price/get-price.mjs
  • components/token_metrics/actions/get-indices/get-indices.mjs
  • components/token_metrics/actions/get-fundamental-grades/get-fundamental-grades.mjs
  • components/token_metrics/actions/get-fundamental-grades-historical/get-fundamental-grades-historical.mjs
  • components/token_metrics/actions/get-tm-grades-historical/get-tm-grades-historical.mjs
  • components/token_metrics/actions/get-technology-grades-historical/get-technology-grades-historical.mjs
  • components/token_metrics/actions/get-correlation/get-correlation.mjs
  • components/token_metrics/actions/get-quantmetrics/get-quantmetrics.mjs
  • components/token_metrics/actions/get-tokens/get-tokens.mjs
  • components/token_metrics/actions/get-technology-grades/get-technology-grades.mjs
  • components/token_metrics/actions/get-tm-grades/get-tm-grades.mjs
  • components/token_metrics/actions/get-hourly-trading-signals/get-hourly-trading-signals.mjs
  • components/token_metrics/actions/get-moonshot-tokens/get-moonshot-tokens.mjs
  • components/token_metrics/actions/get-crypto-investors/get-crypto-investors.mjs
🧰 Additional context used
🧬 Code graph analysis (1)
components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (1)
components/token_metrics/common/constants.mjs (2)
  • ENDPOINTS (2-253)
  • ENDPOINTS (2-253)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Lint Code Base
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
🔇 Additional comments (19)
components/token_metrics/actions/get-indices-holdings/get-indices-holdings.mjs (2)

28-33: No change required — id is sent as a query param and pagination is supported via params

getIndicesHoldings accepts a params object and calls endpoint "/indices-holdings"; buildParams(this, endpoint.filters) includes 'id' and will add limit/page when present (components/token_metrics/token_metrics.app.mjs, components/token_metrics/common/utils.mjs).


12-13: Doc link + version bump look good; verify repo-wide v3 migration consistency

Nice update. Please scan for any lingering v2 references, old action versions, or unrenamed endpoints.

Run:

components/token_metrics/actions/get-daily-ohlcv/get-daily-ohlcv.mjs (2)

12-13: Approve — v3 docs URL resolves and app base set to /v3

Confirmed: https://developers.tokenmetrics.com/v3/reference/daily-ohlcv resolves; components/token_metrics/token_metrics.app.mjs _baseUrl() returns https://api.tokenmetrics.com/v3.


24-30: tokenName prop mapping & filters verified — no changes needed

  • buildParams (components/token_metrics/common/utils.mjs) maps snake_case filter keys to camelCase props via toCamelCase, so the tokenName prop will be sent as token_name.
  • ENDPOINTS.DAILY_OHLCV.filters (components/token_metrics/common/constants.mjs) includes "token_name"; DAILY_OHLCV has no expand/sort_by in constants — expose them only if the API/docs require it.
components/token_metrics/actions/get-market-metrics/get-market-metrics.mjs (2)

12-13: Doc link + version bump verified — approve.

Confirmed https://developers.tokenmetrics.com/v3/reference/market-metrics is the v3 Market Metrics reference. Supported query params: START_DATE, END_DATE. No pagination, expand, or sort documented.


54-57: Confirmed — targets v3 and parameter mapping is correct.

components/token_metrics/token_metrics.app.mjs sets _baseUrl() to "https://api.tokenmetrics.com/v3", getMarketMetrics uses the "/market-metrics" endpoint, and components/token_metrics/common/utils.mjs buildParams maps camelCase props (e.g., startDate/endDate) to snake_case params (start_date/end_date).

components/token_metrics/token_metrics.app.mjs (4)

107-128: Array props UX vs wire format: align descriptions and ensure CSV normalization

These are typed as string[] but descriptions imply CSV. Either:

  • Keep string[] UX and normalize arrays to CSV before requests, or
  • Change descriptions to remove “Comma separated”.

Recommend centralizing normalization in the app (see separate comment with diff).


152-175: sortBy must be sent as sort_by (or normalized)

API expects snake_case. If you don’t rename the prop to sort_by, ensure you map sortBy → sort_by before making requests.

Run this to confirm mapping exists in buildParams:

#!/bin/bash
rg -n -C2 'buildParams|sort_by|sortBy|token_name|tokenName' components/token_metrics/common/utils.mjs

201-201: Confirm v3 base URL is valid and public

Please verify https://api.tokenmetrics.com/v3 is officially supported; public docs typically show /v2.

What is the official Token Metrics API base URL as of 2025, and is https://api.tokenmetrics.com/v3 documented for public use?

426-433: /price-prediction endpoint likely not public — gate or fallback

Docs don’t list GET /price-prediction. Prefer gating behind a flag or fallback to /price until confirmed.

Option (fallback to /price) in the app method:

-        endpoint: "/price-prediction",
+        endpoint: "/price",
components/token_metrics/actions/get-hourly-ohlcv/get-hourly-ohlcv.mjs (2)

37-41: LGTM on slug propDefinition

Consistent with app propDefinition.


24-30: LGTM — buildParams maps tokenName → token_name and joins arrays

Confirmed in components/token_metrics/common/utils.mjs: buildParams uses toCamelCase(key) to read props.tokenName and sets params[key] = props[propKey].join(",") for array values.

components/token_metrics/actions/get-price-prediction/get-price-prediction.mjs (3)

24-29: Prop additions look good

tokenName propDefinition is present in the app. No issues.


36-41: LGTM on slug propDefinition

Aligned with app prop.


10-13: Fix invalid docs link

Replace with an official page (e.g., Scenario Analysis guide or Price guide).

Apply:

-  description: `${endpoint.description}. [See the documentation](https://developers.tokenmetrics.com/v3/reference/price-prediction)`,
+  description: `${endpoint.description}. See: https://developers.tokenmetrics.com/docs/scenario-analysis-guide`,
components/token_metrics/actions/get-resistance-support/get-resistance-support.mjs (2)

12-13: Verified v3 wiring — ready to approve.

App base URL is "https://api.tokenmetrics.com/v3" (components/token_metrics/token_metrics.app.mjs:201); RESISTANCE_SUPPORT path is "/resistance-support" (components/token_metrics/common/constants.mjs:174); getResistanceSupport method exists (components/token_metrics/token_metrics.app.mjs:396–399).


24-29: tokenName propDefinition exists and correctly maps to token_name

propDefinitions.tokenName is defined (components/token_metrics/token_metrics.app.mjs), ENDPOINTS include "token_name" (components/token_metrics/common/constants.mjs), and buildParams (components/token_metrics/common/utils.mjs) uses toCamelCase to read props.tokenName and assigns params[key] (i.e., the snake_case "token_name") — mapping is correct.

components/token_metrics/actions/get-ai-reports/get-ai-reports.mjs (2)

25-30: Add a brief description for tokenName and verify mapping to API param token_name.

UI consistency: other props include descriptions. Also confirm propDefinition exists in the app and buildParams maps camelCase prop tokenName to snake_case token_name in endpoint.filters.

Apply this diff to add the description:

     tokenName: {
       propDefinition: [
         tokenMetrics,
         "tokenName",
       ],
+      description: "Filter by token name(s). Comma-separated. Example: `Solana,Ethereum`",
     },

Run this script to verify the wiring:

If AI Reports supports slug/expand/sort_by per v3, consider exposing slug, expand, and sortBy props (using app propDefinitions) for parity with other actions.


12-13: Approved — docs link and v3 path verified.
Docs URL returns 200 and tokenMetrics.getAiReports calls makeApiCall with endpoint "/ai-reports" using base URL "https://api.tokenmetrics.com/v3".

Copy link
Collaborator

@GTFalcao GTFalcao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Thanks for the contribution @HarshGautam7101 ! I will move it forward to QA

@vunguyenhung vunguyenhung moved this from Ready for QA to Ready for Release in Component (Source and Action) Backlog Sep 25, 2025
@vunguyenhung
Copy link
Collaborator

Hi everyone, all test cases are passed! Ready for release!

Test report
https://vunguyenhung.notion.site/Token-metrics-v3-upgrade-278bf548bb5e812c91a7fa0af2b7521c

@vunguyenhung vunguyenhung merged commit 9d24fec into PipedreamHQ:master Sep 25, 2025
10 checks passed
@github-project-automation github-project-automation bot moved this from Ready for Release to Done in Component (Source and Action) Backlog Sep 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

User submitted Submitted by a user

Development

Successfully merging this pull request may close these issues.

5 participants