Skip to content

Track canton chain Fee/Revenue#6345

Merged
treeoflife2 merged 2 commits intomasterfrom
canton-chain
Apr 10, 2026
Merged

Track canton chain Fee/Revenue#6345
treeoflife2 merged 2 commits intomasterfrom
canton-chain

Conversation

@treeoflife2
Copy link
Copy Markdown
Member

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b8309da2-21f5-471e-b563-33c316f6e783

📥 Commits

Reviewing files that changed from the base of the PR and between 540807a and f97511a.

📒 Files selected for processing (1)
  • fees/canton.ts

Summary by CodeRabbit

  • New Features
    • Canton chain is now supported with integrated fee and revenue tracking.
    • Daily permanent token burns are tracked and automatically valued in USD for accurate financial reporting.
    • Daily fees, daily revenue, and holders’ revenue metrics added for Canton.
    • Reporting includes Canton data for comprehensive ecosystem financial visibility.
    • Canton data availability begins 2024-06-26.

Walkthrough

Adds a Canton fees adapter that fetches cached daily burn timeseries from an external API, converts burns to USD using an average amulet price, and returns dailyFees/dailyRevenue/dailyHoldersRevenue. Also adds CANTON to the CHAIN enum.

Changes

Cohort / File(s) Summary
Canton Fees Adapter
fees/canton.ts
New TypeScript module exporting fetch and default adapter. Lazily fetches and caches an external daily timeseries, selects data by options.dateString, converts burn amount to USD (using avg amulet price), constructs dailyFees with a single "Token Burn" line item, and returns revenue/holders data. Includes metadata (version, start date, chain, protocol, methodology).
Chain Enum Extension
helpers/chains.ts
Added enum member CANTON = "canton" to the exported CHAIN enum.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client as Client
participant Adapter as Canton Adapter
participant Cache as CachedPromise<Map<date,DailyData>>
participant API as External Timeseries API
participant Builder as Balances Builder
Client->>Adapter: fetch(options.dateString, options)
Adapter->>Cache: await cachedPromise (lazy-init)
Cache->>API: fetch timeseries (if not cached)
API-->>Cache: timeseries JSON
Cache-->>Adapter: map(date->DailyData)
Adapter->>Adapter: select entry for date
Adapter->>Builder: options.createBalances()
Adapter->>Builder: compute burnUsd = burnAmount * avgAmuletPrice
Builder-->>Adapter: dailyFees (with "Token Burn" USD line)
Adapter-->>Client: { dailyFees, dailyRevenue, dailyHoldersRevenue }

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~18 minutes

Possibly related PRs

Suggested labels

fees

🚥 Pre-merge checks | ❌ 6

❌ Failed checks (6 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning Title does not follow the specified format [type] protocol-name - description and lacks a type prefix. Reformat title to follow [type] protocol-name - description format, e.g., [feat] canton - track canton chain fee and revenue.
Description check ⚠️ Warning No pull request description was provided; the required template information is missing. Add a pull request description explaining the changes, implementation details, and relevant context for the Canton fees adapter addition.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 50.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Breakdown Methodology Check ⚠️ Warning canton.ts adapter fails breakdown methodology check because it lacks entries for Revenue and HoldersRevenue categories that use TokenBurn label. Add missing Revenue and HoldersRevenue entries to breakdownMethodology object with TokenBurn label documentation.
Income Statement Compliance ⚠️ Warning Canton adapter omits dailySupplySideRevenue entirely and violates the relationship dailyRevenue = dailyFees - dailySupplySideRevenue by allocating burned amount identically to both components. Restructure adapter to populate dailyFees with total burned amount, dailySupplySideRevenue with burned amount, dailyRevenue to zero or protocol-kept portion, and return all four balance components with proper income statement separation.
Version 2 Required ⚠️ Warning New adapter fees/canton.ts uses version 1 instead of required version 2 for new adapters. Update adapter to version 2 and refactor fetch function signature to accept only options: FetchOptions parameter.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch canton-chain

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.

@llamabutler
Copy link
Copy Markdown

The canton.ts adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts fees canton.ts

🦙 Running CANTON.TS adapter 🦙
---------------------------------------------------
Start Date:	Sun, 05 Apr 2026 00:00:00 GMT
End Date:	Mon, 06 Apr 2026 00:00:00 GMT
---------------------------------------------------

CANTON 👇
Backfill start time: 26/6/2024
Daily fees: 2.00 M
Daily revenue: 2.00 M
Daily holders revenue: 2.00 M

Copy link
Copy Markdown
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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@fees/canton.ts`:
- Line 34: The fetch function currently declares unused placeholder parameters
(_a: any, _b: any, options: FetchOptions); either remove the unused parameters
and change the signature to fetch(options: FetchOptions) if the adapter can use
the Version 2 pattern, or if the V1 adapter signature must be preserved, add a
concise inline comment above or next to the fetch declaration explaining that _a
and _b are required placeholders for the V1 adapter signature and intentionally
unused; update the function signature or comment in the fetch declaration
accordingly (refer to the fetch function and its parameters _a, _b, options:
FetchOptions).
- Line 48: The return currently reuses the same Balances object for dailyRevenue
and dailyHoldersRevenue which causes shared-reference bugs; create a distinct
Balances instance for dailyHoldersRevenue instead of reusing dailyRevenue (e.g.,
construct/clone a new object with the same numeric fields), and return {
dailyFees, dailyRevenue, dailyHoldersRevenue: <new cloned Balances> } so
downstream mutations to one do not affect the other.
- Around line 67-71: The breakdownMethodology currently documents only Fees but
dailyRevenue and dailyHoldersRevenue also use LABELS.TokenBurn; update the
breakdownMethodology object to add entries for Revenue and HoldersRevenue
(mirroring the Fees entry) so every label used in .add() calls is
documented—specifically add breakdownMethodology.Revenue and
breakdownMethodology.HoldersRevenue with a TokenBurn description matching the
Fees one and ensure LABELS.TokenBurn is referenced in those new entries.
- Around line 15-28: The module-level cached promise (cachedData) in getDataMap
has no invalidation so stale/erroneous API responses persist; modify the cache
to include a TTL by storing alongside the Promise a timestamp/expiry and check
it in getDataMap before returning cachedData, and when expired re-fetch via
fetchURL(API_URL) to replace cachedData; ensure you reference and update the
same cachedData variable (and any new expiry field) and keep the existing
mapping logic that turns res.data into Record<string, DailyData>.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: eee71bf8-7193-4a78-a8e1-b26f62bff594

📥 Commits

Reviewing files that changed from the base of the PR and between 142c5d8 and 540807a.

📒 Files selected for processing (2)
  • fees/canton.ts
  • helpers/chains.ts

Comment on lines +15 to +28
let cachedData: Promise<Record<string, DailyData>> | null = null;

function getDataMap(): Promise<Record<string, DailyData>> {
if (!cachedData) {
cachedData = fetchURL(API_URL).then((res: { data: DailyData[] }) => {
const map: Record<string, DailyData> = {};
res.data.forEach((entry) => {
map[entry.date] = entry;
});
return map;
});
}
return cachedData;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Module-level cache lacks invalidation mechanism.

The cached promise persists indefinitely across all adapter invocations. If the API returns stale or erroneous data, subsequent calls will continue using the bad cache until the process restarts. Consider adding a TTL or allowing the cache to refresh periodically, especially since historical data may be updated upstream.

♻️ Optional: Add TTL-based cache invalidation
-let cachedData: Promise<Record<string, DailyData>> | null = null;
+let cachedData: Promise<Record<string, DailyData>> | null = null;
+let cacheTimestamp = 0;
+const CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour

 function getDataMap(): Promise<Record<string, DailyData>> {
-  if (!cachedData) {
+  const now = Date.now();
+  if (!cachedData || (now - cacheTimestamp) > CACHE_TTL_MS) {
+    cacheTimestamp = now;
     cachedData = fetchURL(API_URL).then((res: { data: DailyData[] }) => {
       const map: Record<string, DailyData> = {};
       res.data.forEach((entry) => {
         map[entry.date] = entry;
       });
       return map;
     });
   }
   return cachedData;
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/canton.ts` around lines 15 - 28, The module-level cached promise
(cachedData) in getDataMap has no invalidation so stale/erroneous API responses
persist; modify the cache to include a TTL by storing alongside the Promise a
timestamp/expiry and check it in getDataMap before returning cachedData, and
when expired re-fetch via fetchURL(API_URL) to replace cachedData; ensure you
reference and update the same cachedData variable (and any new expiry field) and
keep the existing mapping logic that turns res.data into Record<string,
DailyData>.

TokenBurn: "Token Burn",
};

export const fetch = async (_a: any, _b: any, options: FetchOptions) => {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Clarify or remove the unused function parameters.

The signature (_a: any, _b: any, options: FetchOptions) uses placeholder parameters that are not utilized. While this may be required for the Version 1 adapter signature, consider adding a brief comment explaining why these parameters exist, or verify if Version 2 adapter pattern (which uses just options: FetchOptions) would be more appropriate.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@fees/canton.ts` at line 34, The fetch function currently declares unused
placeholder parameters (_a: any, _b: any, options: FetchOptions); either remove
the unused parameters and change the signature to fetch(options: FetchOptions)
if the adapter can use the Version 2 pattern, or if the V1 adapter signature
must be preserved, add a concise inline comment above or next to the fetch
declaration explaining that _a and _b are required placeholders for the V1
adapter signature and intentionally unused; update the function signature or
comment in the fetch declaration accordingly (refer to the fetch function and
its parameters _a, _b, options: FetchOptions).

@treeoflife2 treeoflife2 merged commit c4e02fc into master Apr 10, 2026
2 checks passed
@treeoflife2 treeoflife2 deleted the canton-chain branch April 10, 2026 12:13
@llamabutler
Copy link
Copy Markdown

The canton.ts adapter exports:

> adapters@1.0.0 test
> ts-node --transpile-only cli/testAdapter.ts fees canton.ts

🦙 Running CANTON.TS adapter 🦙
---------------------------------------------------
Start Date:	Thu, 09 Apr 2026 00:00:00 GMT
End Date:	Fri, 10 Apr 2026 00:00:00 GMT
---------------------------------------------------

CANTON 👇
Backfill start time: 26/6/2024
Daily fees: 2.46 M
Daily revenue: 2.46 M
Daily holders revenue: 2.46 M

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants