tres-asset-balance-validation
>
git clone --depth 1 https://github.com/anthropics/claude-plugins-community /tmp/tres-asset-balance-validation && cp -r /tmp/tres-asset-balance-validation/tres-finance-plugin/skills/tres-asset-balance-validation ~/.claude/skills/tres-asset-balance-validationSKILL.md
# Tres Finance — Asset Balance Validation
## Overview
This skill validates wallet balances in **Tres Finance** against **DeBank**, providing a clear discrepancy report as both an interactive HTML file and a PDF. It compares per-asset token amounts (including DeFi position underlying tokens) for each EVM wallet and flags matches, minor differences, major discrepancies, missing assets, untracked tokens, and unmatched positions.
> **Scope:** Only EVM-compatible wallets are supported (DeBank limitation). Exchange accounts, non-EVM chains, and empty wallets are skipped.
---
## When to Use
Trigger this skill whenever a user asks to:
- Validate or verify their TRES balances
- Cross-check or audit wallets against external on-chain data
- Compare TRES data to DeBank
- Check if their balances are correct
**Example phrases:**
- *"Validate my balances"*
- *"Check my wallets against DeBank"*
- *"Are my TRES balances correct?"*
- *"Show me any discrepancies between TRES and on-chain data"*
---
## Prerequisites
| Requirement | Details |
|---|---|
| TRES Finance access | Must be authenticated via `get_viewer` |
| DeBank API key | Free key available at [cloud.debank.com](https://cloud.debank.com) |
| EVM wallets | At least one `0x...` wallet tracked in TRES |
---
## Process Overview
### Step 1 — Authenticate with TRES
Call `get_viewer` to confirm the organization name.
### Step 2 — Fetch wallets and balances from TRES
**IMPORTANT — Timeout handling:** The `internalAccount` query with both `balances` and `positions` will timeout for large orgs. Split into two separate queries:
**Query 1: Wallets + Balances only (no positions)**
```graphql
query {
internalAccount {
results {
id
name
identifier
isExchange
platforms
balances {
amount
asset {
symbol
contract { identifier }
}
fiatValue { value unitPrice fiatCurrency }
}
}
}
}
```
> **Note:** The `amount` field is returned as a **string**, not a number. Always `float()` it before arithmetic.
**Wallet classification:**
| Type | Condition | Validated? |
|---|---|---|
| EVM | `0x...` address + EVM platform + `isExchange: false` | ✅ Yes |
| Exchange | `isExchange: true` | ❌ No |
| Non-EVM | Bitcoin, Tezos, Tron, etc. | ❌ No |
| Empty | No asset balances | ❌ No |
**Supported EVM platforms:** Ethereum, Arbitrum, Optimism, Polygon, Base, Avalanche, Binance, Gnosis Chain, zkSync, Fantom, Celo, Berachain, Linea, Scroll, Sonic, HyperEVM.
### Step 3 — Fetch DeFi positions from TRES
**Do NOT use the `positions` sub-field on `internalAccount`** — it returns all historical snapshots (can be 3000+ entries per wallet) and will timeout or exceed token limits.
Instead, use the dedicated `getStatelessWalletsPositions` query which returns **current** positions only:
```graphql
query {
getStatelessWalletsPositions(
walletIdentifiers: ["0x..."],
platform: ETHEREUM,
application: "aave-v3"
) {
walletIdentifier
displayName
positionType
platform
children {
symbol
amount
assetIdentifier
fiatValue
}
fiatValue
id
}
}
```
**Required parameters:**
- `walletIdentifiers`: array of wallet addresses
- `platform`: must be an enum value like `ETHEREUM`, `POLYGON`, `ARBITRUM`, etc.
**Optional but recommended:**
- `application`: filter by protocol (e.g. `"aave-v3"`, `"verse"`, `"lido"`, `"merkl"`, `"uniswap-v4"`, `"sablier"`, `"ethena"`, `"stakewise"`, `"quickswap"`, `"steer"`, `"yieldnest"`, `"morphoblue"`)
**IMPORTANT:** Without the `application` filter, the query returns empty results. Always specify the application.
**Batching strategy:**
1. First, fetch DeBank `all_complex_protocol_list` for each wallet to discover which protocols have positions
2. Map DeBank protocol names to TRES application names (lowercase, hyphenated)
3. Use GraphQL aliases to batch multiple wallet+platform+application combos into a single query:
```graphql
query {
a1: getStatelessWalletsPositions(walletIdentifiers: ["0x..."], platform: ETHEREUM, application: "aave-v3") {
walletIdentifier displayName positionType platform id
children { symbol amount assetIdentifier fiatValue }
}
a2: getStatelessWalletsPositions(walletIdentifiers: ["0x..."], platform: ETHEREUM, application: "verse") {
walletIdentifier displayName positionType platform id
children { symbol amount assetIdentifier fiatValue }
}
}
```
Keep each batched query to ~6 aliases max to avoid timeouts.
### Step 4 — Retrieve DeBank API key
Read `DEBANK_API_KEY` from plugin user config — do **not** ask the user to paste it in chat.
If the key is absent or empty, stop and display:
> "DEBANK_API_KEY is not configured. Please add it via the plugin settings (obtain your key at https://cloud.debank.com)."
### Step 5 — Fetch DeBank data via bash
For each EVM wallet, fetch **two** endpoints:
1. **Token balances:** `all_token_list` — covers all chains without requiring a `chain_id`
2. **DeFi protocol positions:** `all_complex_protocol_list` — returns LP, staking, lending positions with underlying token amounts
Use `--data-urlencode` with `-G` so the wallet address is never shell-interpolated into the URL string:
```bash
# Token balances
curl -s -G \
-H "AccessKey: ${user_config.DEBANK_API_KEY}" \
--data-urlencode "id=$WALLET_ADDR" \
"https://pro-openapi.debank.com/v1/user/all_token_list"
# DeFi positions
curl -s -G \
-H "AccessKey: ${user_config.DEBANK_API_KEY}" \
--data-urlencode "id=$WALLET_ADDR" \
"https://pro-openapi.debank.com/v1/user/all_complex_protocol_list"
```
**Fiat-value filter:** Discard any token where `price < 0.01` — these are excluded from all matching, display, and reporting.
**Rate limiting:** Add a 0.3s delay between wallet requests to avoid 429 errors.
### Step 6 — Match regular assets
Matching must be **chain-aware**. DeBank's `all_token_list` returns a `chain` field per
token (e.g. `"eth"`, `"arb"`,Explain a topic like I'm a 5 year old. Use when the user types /eli5 <topic> or asks for a dead-simple picture explainer of how something works.
Use the `quickdesign` CLI to generate AI media — UGC promo videos, image edits, product creatives, video upscales — through Seedance, Kling, Sora2, Nano Banana, and GPT Image. Invoke this skill whenever the user asks for a talking-avatar video, multi-segment ad / promo / explainer, image edit (object swap, angle change, state change), product photoshoot, or video upscale via QuickDesign.
Use only when the user explicitly asks for a TestDino audit of Playwright automated test code. Routes through the audit tools the TestDino MCP server exposes (get_audit_report + submit_audit_report, or the legacy test_audit). For generic code review or non-Playwright targets, do a normal review instead.
Use when the user wants to check TestDino connection status, validate their PAT, discover available organizations and projects, or find the right projectId. Always call this first when the project context is ambiguous before any other TestDino tool.
Use when the user wants to manage a manual execution run or update case-level results inside a run — listing runs, creating runs for a release, inspecting a run, assigning cases, or marking case results (passed/failed/blocked/skipped/retest/untested). Accepts counter-style IDs like RUN-12 and TC-156.
Use when the user wants to create, update, or browse manual QA test cases and suites in TestDino — not execution runs. Covers list_manual_test_suites, list_manual_test_cases, get_manual_test_case, create_manual_test_case, update_manual_test_case, create_manual_test_suite.
Use when the user wants to browse, inspect, create, or update releases/milestones in a TestDino project. Covers list_releases, get_release, create_release, and update_release. Accepts counter-style IDs like MS-12.
Use when the user wants to inspect automated test runs, list failed or flaky tests, debug a failing testcase with historical context, or filter runs by branch, commit, author, environment, browser, status, or tags. Includes list_testruns, get_run_details, list_testcase, get_testcase_details, and debug_testcase.