How to Validate a TRES Finance Dashboard Ledger URL: The Complete 10-Step Checklist

To generate a working TRES Finance dashboard link, you must validate the /ledger path, enforce dateType consistency with custom ranges, omit false boolean flags, comma-join multi-select values, respect enum casing rules, and handle special logic for spam flags and transaction hash overrides.

Generating a valid TRES Finance dashboard ledger URL requires strict adherence to the validation checklist defined in the anthropics/claude-plugins-community repository. The plugin skill located at tres-finance-plugin/skills/tres-ledger-link/SKILL.md specifies ten critical rules that prevent malformed query strings, 404 errors, and incorrect filter applications. Following this checklist ensures the generated link accurately reflects user-requested filters and renders the Transactions tab correctly.

The 10-Step Validation Checklist

According to the specification in tres-finance-plugin/skills/tres-ledger-link/SKILL.md, apply the following rules before returning any ledger URL:

  1. Path correctness: The URL path must be exactly /ledger with no extra suffixes or fragment identifiers (lines 38-39). The dashboard only renders the Transactions tab at this fixed path; any deviation leads to a 404 or incorrect view.

  2. Date & dateType consistency: The fromDate and toDate parameters may only appear together with dateType=Custom%20date (or when dateType is omitted). They must not be combined with preset modes like Last 30 days or All time, as the dashboard interprets custom ranges only under the "Custom date" mode (lines 39-40).

  3. Boolean parameters: Include a boolean filter only when its value is true. Never emit =false, as false is the default and unnecessary parameters clutter the query string and can break downstream parsing (line 41).

  4. Multi-select formatting: For filters accepting multiple IDs (e.g., platforms, internalAccounts), join values with commas inside a single query key. Use platforms=ethereum,bsc instead of repeating the key (platforms=ethereum&platforms=bsc), as the dashboard expects a single comma-delimited string (lines 42-44).

  5. Enum case sensitivity: Enum-type values must match the schema exactly. The platforms enum requires lower-cased values (ethereum), while other enums like activities and actions require UPPER-CASE values (SPAM, SEND). The backend validates enums case-sensitively (lines 45-46).

  6. amountBetween syntax: The value must always contain a single comma, even for open-ended ranges. Acceptable formats include 100,500, 100,, and ,500. Missing the comma causes the dashboard to throw a parsing error (lines 46-47).

  7. Implicit spam flag: If activities includes SPAM, automatically add showSpam=true to the query string. Without this flag, SPAM transactions remain hidden despite the activity filter requesting them (line 48).

  8. Transaction hash overrides dates: When transactionHash is present, the dashboard ignores all date filters. If a user supplies both, warn them that the dates will have no effect, as the UI prioritizes hash lookups (lines 49-50).

  9. URL-encode spaces: Replace spaces with %20 (e.g., Custom date becomes Custom%20date). Unencoded spaces break the query string and cause the dashboard to reject the URL (line 51).

  10. Include only requested filters: Do not add parameters the user did not explicitly request. Extra parameters add noise, can unintentionally filter out data, and make the link harder to audit (line 52).

Implementing the Validation Checklist in Python

The following implementation demonstrates how to apply these rules when constructing ledger URLs, referencing the validation logic specified in SKILL.md.

URL-Encoding Helper

import urllib.parse

def encode_param(value: str) -> str:
    """Encode a query value, preserving commas for multi‑select lists."""
    return urllib.parse.quote(value, safe=",")

Building the URL with Validation Logic

def build_ledger_url(subdomain: str, filters: dict) -> str:
    """
    Construct a TRES Finance ledger URL, enforcing the validation checklist.
    `filters` keys correspond to the query parameters described in the skill.
    """
    base = f"https://{subdomain}.tres.finance/ledger"
    query_parts = []

    # 1. Path already correct (base ends with /ledger)

    # 2. Date handling

    date_type = filters.get("dateType")
    from_date = filters.get("fromDate")
    to_date = filters.get("toDate")
    if date_type and date_type != "Last 30 days":
        if date_type == "Custom date":
            if not (from_date and to_date):
                raise ValueError("Custom date requires both fromDate and toDate")
            query_parts.append(f"dateType={encode_param(date_type)}")
            query_parts.append(f"fromDate={from_date}")
            query_parts.append(f"toDate={to_date}")
        elif date_type == "All time":
            query_parts.append(f"dateType={encode_param(date_type)}")
            # omit from/to dates (rule 3)

        else:
            query_parts.append(f"dateType={encode_param(date_type)}")
    # If dateType omitted, defaults to Last 30 days – no date params needed.

    # 3. Booleans – only include when true

    for bool_key in [
        "showSpam", "missingFiat", "failedTransactions",
        "nonTaxableType", "missingCostBasis",
        "internalTransactions", "ignoreFee"
    ]:
        if filters.get(bool_key) is True:
            query_parts.append(f"{bool_key}=true")

    # 4. Multi‑select arrays – comma‑join

    multi_keys = [
        "internalAccounts", "tags", "thirdPartyAccounts", "customNameLabelTags",
        "addresses", "assetClasses", "assets", "activities", "automations",
        "platforms", "actions", "functions", "applications", "protocols",
        "methodIds", "transactionHash"
    ]
    for key in multi_keys:
        vals = filters.get(key)
        if vals:
            # Ensure proper case for enums

            if key == "platforms":
                vals = [v.lower() for v in vals]
            elif key in {"activities", "actions"}:
                vals = [v.upper() for v in vals]
            joined = ",".join(vals)
            query_parts.append(f"{key}={encode_param(joined)}")

    # 5. amountBetween – must contain a single comma

    if "amountBetween" in filters:
        val = filters["amountBetween"]
        if val.count(",") != 1:
            raise ValueError("amountBetween must contain exactly one comma")
        query_parts.append(f"amountBetween={encode_param(val)}")
        if filters.get("amountAsset"):
            query_parts.append(f"amountAsset={filters['amountAsset']}")

    # 6. Implicit spam flag

    if "activities" in filters and "SPAM" in [a.upper() for a in filters["activities"]]:
        query_parts.append("showSpam=true")

    # 7. TransactionHash overrides dates – warn if dates also supplied

    if "transactionHash" in filters and (from_date or to_date):
        print("⚠️  Note: date filters are ignored when transactionHash is used.")

    # Assemble final URL

    query = "&".join(query_parts)
    return f"{base}?{query}" if query else base

Example Usage

url = build_ledger_url(
    subdomain="exampleorg",
    filters={
        "dateType": "Custom date",
        "fromDate": "2024-01-01",
        "toDate": "2024-01-31",
        "platforms": ["ethereum"],
        "activities": ["SPAM"],
        "showSpam": True,
    },
)
print(url)

# → https://exampleorg.tres.finance/ledger?dateType=Custom%20date&fromDate=2024-01-01&toDate=2024-01-31&platforms=ethereum&activities=SPAM&showSpam=true

Key Source Files

The validation rules are implemented across the following files in the anthropics/claude-plugins-community repository:

Summary

  • Validate that the path is exactly /ledger to avoid 404 errors.
  • Only pair fromDate/toDate with dateType=Custom%20date, never with preset modes.
  • Omit boolean parameters when false; include only when explicitly true.
  • Join multi-select values with commas within a single query key.
  • Respect enum casing: lowercase for platforms, uppercase for activities and actions.
  • Ensure amountBetween contains exactly one comma.
  • Automatically append showSpam=true when the SPAM activity is selected.
  • Warn users that transactionHash filters override date ranges.
  • URL-encode spaces as %20 and include only explicitly requested parameters.

Frequently Asked Questions

What happens if I use dateType=Last 30 days with specific from and to dates?

The dashboard will likely ignore the custom dates or produce empty results. According to the source code in SKILL.md (lines 39-40), custom date ranges must use dateType=Custom%20date to render correctly. Mixing preset modes with explicit dates violates the validation checklist and leads to incorrect filtering.

Why must boolean flags be excluded when set to false?

The TRES Finance dashboard treats false as the default state for all boolean filters. Including =false in the query string adds unnecessary noise and can interfere with downstream parsing logic. The validation checklist explicitly requires omitting these parameters entirely when the value is not true (line 41).

How should I format the amountBetween parameter for open-ended ranges?

Always include a single comma, even if one side of the range is open. For amounts greater than 100, use 100,. For amounts less than 500, use ,500. The dashboard parser requires this comma to split the range correctly; omitting it results in a parsing error (lines 46-47).

Are platform names case-sensitive in the ledger URL?

Yes. The platforms parameter requires lower-cased values such as ethereum or bsc, while activities and actions require UPPER-CASE values like SPAM or SEND. The backend validates these enums case-sensitively, and mismatched casing will cause the filter to be ignored entirely (lines 45-46).

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →