tres-asset-balance-validation について
このスキルは、Tres FinanceのEVMウォレット残高をDeBankのデータと照合し、差異レポートをインタラクティブなHTMLとPDFで作成します。Tres Financeの資産残高、トークン、DeFiポジションを確認する用途に向いています。
主な機能
- 01Tres FinanceとDeBankのトークン残高を比較
- 02DeFiポジションと基礎トークンを照合
- 03チェーン別に資産を照合し差異を表示
- 04インタラクティブなHTMLとPDFを生成
- 05残高のあるEVMウォレットのみ処理
活用シーン
- 01Tres Financeで追跡するEVMウォレット残高の監査
- 02オンチェーンデータと記録の差異確認
- 03DeFiポジションの基礎トークン量の検証
MCP 対応
TRES Financeの`get_viewer`、GraphQLクエリ、DeBank APIからウォレットと資産データを取得し、比較してレポートを作成します。READMEには、MCPサービスやMCPクライアントに公開するツールの説明はありません。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ anthropics/ claude-plugins-community --skill tres-asset-balance-validationインストール後、Claude Code で/tres-asset-balance-validationを入力して読み込まれたか確認します。
詳細
Tres Finance — 資産残高の検証
概要
このスキルは、Tres Finance のウォレット残高を DeBank と照合し、インタラクティブな HTML ファイルと PDF の両方で、明確な差異レポートを作成します。各 EVM ウォレットについて、資産ごとのトークン数量(DeFi ポジションの裏付けトークンを含む)を比較し、一致、軽微な差異、大きな不一致、資産の欠落、未追跡トークン、照合できないポジションを示します。
対象範囲: 対応しているのは EVM 互換ウォレットのみです(DeBank の制限によるものです)。取引所アカウント、EVM 非対応チェーン、残高のないウォレットはスキップされます。
使用するタイミング
ユーザーから次のような依頼があった場合に、このスキルを実行します。
- TRES の残高を検証または確認する
- 外部のオンチェーンデータとウォレットを照合または監査する
- TRES のデータを DeBank と比較する
- 残高が正しいか確認する
依頼の例:
- 「残高を検証してください」
- 「ウォレットを DeBank と照合してください」
- 「TRES の残高は正しいですか?」
- 「TRES とオンチェーンデータの差異をすべて表示してください」
前提条件
| 要件 | 詳細 |
|---|---|
| TRES Finance へのアクセス | get_viewer で認証済みである必要があります |
| DeBank API キー | cloud.debank.com で無料キーを取得できます |
| EVM ウォレット | TRES で追跡されている 0x... ウォレットが少なくとも 1 つ必要です |
プロセスの概要
ステップ 1 — TRES で認証する
get_viewer を呼び出して、組織名を確認します。
ステップ 2 — TRES からウォレットと残高を取得する
重要 — タイムアウトへの対処: balances と positions の両方を含む internalAccount クエリは、大規模な組織ではタイムアウトします。次のように 2 つの個別クエリに分けてください。
クエリ 1:ウォレットと残高のみ(ポジションなし)
query {
internalAccount {
results {
id
name
identifier
isExchange
platforms
balances {
amount
asset {
symbol
contract { identifier }
}
fiatValue { value unitPrice fiatCurrency }
}
}
}
}
注:
amountフィールドは数値ではなく文字列として返されます。計算する前に、必ずfloat()で変換してください。
ウォレットの分類:
| 種類 | 条件 | 検証対象 |
|---|---|---|
| EVM | 0x... アドレス、EVM プラットフォーム、isExchange: false | ✅ はい |
| 取引所 | isExchange: true | ❌ いいえ |
| EVM 非対応 | Bitcoin、Tezos、Tron など | ❌ いいえ |
| 空 | 資産残高なし | ❌ いいえ |
対応している EVM プラットフォーム: Ethereum、Arbitrum、Optimism、Polygon、Base、Avalanche、Binance、Gnosis Chain、zkSync、Fantom、Celo、Berachain、Linea、Scroll、Sonic、HyperEVM。
ステップ 3 — TRES から DeFi ポジションを取得する
internalAccount の positions サブフィールドは使用しないでください。 すべての過去のスナップショットが返され(ウォレットあたり 3000 件を超える場合があります)、タイムアウトするか、トークン制限を超える可能性があります。
代わりに、専用の getStatelessWalletsPositions クエリを使用してください。このクエリでは現在のポジションのみが返されます。
query {
getStatelessWalletsPositions(
walletIdentifiers: ["0x..."],
platform: ETHEREUM,
application: "aave-v3"
) {
walletIdentifier
displayName
positionType
platform
children {
symbol
amount
assetIdentifier
fiatValue
}
fiatValue
id
}
}
必須パラメーター:
walletIdentifiers:ウォレットアドレスの配列platform:ETHEREUM、POLYGON、ARBITRUMなどの列挙値を指定する必要があります。
任意ですが、指定を推奨する項目:
application:プロトコルで絞り込みます(例:"aave-v3"、"verse"、"lido"、"merkl"、"uniswap-v4"、"sablier"、"ethena"、"stakewise"、"quickswap"、"steer"、"yieldnest"、"morphoblue")
重要: application フィルターを指定しないと、クエリ結果は空になります。必ず application を指定してください。
バッチ処理の手順:
- まず、各ウォレットについて DeBank の
all_complex_protocol_listを取得し、ポジションがあるプロトコルを確認します - DeBank のプロトコル名を TRES のアプリケーション名(小文字、ハイフン区切り)に対応付けます
- GraphQL エイリアスを使用し、複数のウォレット、プラットフォーム、アプリケーションの組み合わせを 1 つのクエリにまとめます。
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 }
}
}
タイムアウトを避けるため、各バッチクエリのエイリアスは最大で約 6 件にしてください。
ステップ 4 — DeBank API キーを取得する
プラグインのユーザー設定から DEBANK_API_KEY を読み取ります。ユーザーにチャットで貼り付けるよう求めてはいけません。
キーがない場合、または空の場合は処理を中止し、次のメッセージを表示します。
"DEBANK_API_KEY が設定されていません。プラグインの設定から追加してください(キーは https://cloud.debank.com で取得できます)。"
ステップ 5 — bash で DeBank データを取得する
各 EVM ウォレットについて、2 つのエンドポイントを取得します。
- トークン残高:
all_token_list—chain_idを指定せずにすべてのチェーンを対象とします - DeFi プロトコルのポジション:
all_complex_protocol_list— 原資産のトークン数量を含む LP、ステーキング、レンディングのポジションを返します
--data-urlencode を -G と組み合わせて使用し、ウォレットアドレスが URL 文字列にシェル展開されないようにします。
# 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"
法定通貨価値によるフィルター: price < 0.01 のトークンはすべて除外します。これらは照合、表示、レポートの対象外です。
レート制限: 429 エラーを避けるため、ウォレットリクエストの間に 0.3 秒の遅延を入れます。
ステップ 6 — 通常の資産を照合する
照合では、チェーンを考慮する必要があります。DeBank の all_token_list は、トークンごとに chain フィールド(例:"eth"、"arb"、"bsc")を返します。TRES の残高は、ウォレットの platforms 配列、または残高のコンテキストを通じて特定のプラットフォームに紐付けられています。必ずチェーンごとの照合を優先し、その後でクロスチェーン集計にフォールバックしてください。
チェーン ID のマッピング(DeBank の chain → TRES プラットフォーム):
DeBank の chain | TRES プラットフォーム |
|---|---|
eth | ETHEREUM |
arb | ARBITRUM |
op | OPTIMISM |
matic | POLYGON |
base | BASE |
bsc | BNB (Binance) |
avax | AVALANCHE |
ftm | FANTOM |
xdai | GNOSIS |
era | ZKSYNC |
celo | CELO |
linea | LINEA |
scrl | SCROLL |
mnt | MOONBEAM |
照合の順序(具体性の高い順):
- コントラクトとチェーンの照合(最適): 同じチェーン上で、
asset.contract.identifier(小文字)と DeBank のトークンid(小文字)を比較します。最も精度の高い照合方法です。 - シンボルとチェーンの照合: ネイティブトークン(コントラクトなし)の場合、
asset.symbol(大文字と小文字を区別しない)と、その残高行の TRES プラットフォームに一致する DeBank のchainの両方で照合します。これにより、ウォレットが Ethereum と Arbitrum の両方で ETH を保有しているよくあるケースでも、各 TRES 残高行が対応する DeBank のチェーンごとのエントリと正しく照合されます。 - シンボルのみの照合(最後の手段): TRES のネイティブトークン残高を特定の DeBank チェーンエントリに照合できない場合は、シンボルのみでの照合にフォールバックします。TRES または DeBank で異なるチェーンラベルが使われているエッジケースに対応します。
ステップ 7 — DeFi ポジションの原資産トークンを照合する
これは、TRES と DeBank の DeFi ポジションに含まれる原資産トークンを比較する重要なステップです。
7a. ポジション NFT の行を除外する
ポジション NFT トークン(例:UNI-V3-POS、RCL、SAB-LOCKUP、SLP、STEER、UNI-V4-POS)を通常の比較対象から除外します。これらはポジションの原資産トークンの行に置き換えられます。
7b. TRES のポジションを処理する
getStatelessWalletsPositions の結果から、各ポジションについて以下を行います。
- シンボルごとに
childrenを集計します。ポジション内に同じトークンのエントリが複数ある場合(例:QuickSwap または Uniswap V4 の供給分と未請求報酬)、数量を合算します displayNameを使用して、プロトコルとトークンの構成を特定します
# Example: aggregate children for a position
def aggregate_children(children):
agg = {}
for c in children:
sym = c['symbol']
amt = float(c['amount']) if isinstance(c['amount'], str) else c['amount']
if sym not in agg:
agg[sym] = {'amount': 0, 'assetIdentifier': c.get('assetIdentifier', '')}
agg[sym]['amount'] += amt
return agg
7c. DeBank のポジションを処理する
all_complex_protocol_list から、各プロトコルの portfolio_item_list について以下を行います。
- 供給トークンの
asset_token_listと、報酬のreward_token_listを抽出します - プロトコルの
nameとアイテムのname(例:「レンディング」、「流動性プール」)をポジションのラベルとして使用します
7d. ポジションのトークンを比較する
以下の方法で、DeBank のプロトコルポジションを TRES のポジションと照合します。
- プロトコル名の照合(大文字と小文字を区別せず、最初の単語で照合)
- 子要素間でトークンシンボルが重複しているかを確認
照合された各ポジショントークンについて:
- TRES データがある場合: 数量を比較し、差分(%)を計算して、match/minor/major のステータスを割り当てます
- TRES データがない場合:
positionステータス(紫色のバッジ)を割り当てます
ステップ 8 — レポートを作成して表示する
2 つの出力を作成します。
- インタラクティブ HTML ファイル — ダークテーマで、フィルターボタン、折りたたみ可能なウォレットカード、ウォレットごとの専用 DeFi ポジションセクションを備えます
- PDF レポート — reportlab を使用し、横向き A4 で、すべてのウォレットテーブルを展開した状態にします
両方を出力ディレクトリに保存します。
レポートのレイアウト — 重要
DeFi ポジションを視覚的に区別する必要があります
レポート内の各ウォレットカードには、明確に区別された 2 つのセクションが必要です。
-
DeFi ポジションセクション(上部、紫を基調) — 紫色の枠線と暗い紫色の背景(背景色
#1a1033、枠線色#7c3aed)を持つ専用ボックスで、ポジション関連のすべての行を表示します。このセクションは通常のトークンテーブルより前に配置します。 -
通常のトークンテーブル(下部) — 標準的なトークン残高の比較行です。
ポジション資産インジケーター
すべてのポジション資産行では、資産名の横に紫色のドットインジケーター(CSS の円、8px、#a855f7)を表示する必要があります。これにより、ポジションをすぐに見分けられます。
<span style="display:inline-block;width:8px;height:8px;background:#a855f7;border-radius:50%;margin-right:6px;vertical-align:middle;"></span>
絵文字やインライン SVG は使用しないでください — すべてのビューアーで表示されるとは限りません。CSS の図形のみを使用してください。
ポジション行には 2 つのバッジを表示
TRES と照合されるポジション行には、次の 2 つのバッジを表示します。
POSITIONバッジ(紫色)- 照合ステータスバッジ(
MATCH/MINOR/MAJOR)
ポジションがあるウォレットを自動展開
DeFi ポジションを含むウォレットカードは、ポジションがすぐに見えるように自動展開(<details open>)してください。
数値の書式ルール
トークン数量
- すべての数量は小数点以下最大 3 桁
- 数量が 1,000 以上の場合:小数点以下 3 桁で、桁区切りのカンマを使用(例:
846,492.356) - 数量が 1,000 未満の場合:小数点以下 3 桁(例:
0.386) - 非常に小さい数量(< 0.000001):科学表記を使用(例:
3.54e-07) - null/欠損値:ダッシュ
—を表示
function formatAmount(n) {
if (n === null || n === undefined) return '\u2014';
if (Math.abs(n) < 0.000001) return n.toExponential(2);
if (Math.abs(n) >= 1000) return n.toLocaleString('en-US', {minimumFractionDigits: 2, maximumFractionDigits: 3});
return n.toFixed(3);
}
法定通貨の値
- すべてのトークン数量の横に括弧で表示:
846,492.356 ($17,562.21) - すべての差分 % の横に括弧で表示:
5.33% ($81.21) - 書式:
($X,XXX.XX)— 常に小数点以下 2 桁とし、千単位の区切りにカンマを使用 - null/欠損値:完全に省略(空の括弧は表示しない)
法定通貨の値の計算 — 重要
TRES 列と DeBank 列の両方の法定通貨の値を計算するには、単一の価格ソース(DeBank のトークン価格)を使用してください。これにより、次のことが保証されます。
- 数量が一致する場合、法定通貨の差分は $0 になる(価格ソースの違いによって水増しされない)
- 差分 % の横に表示される法定通貨の差分は、数量の不一致による実際の USD 額を示す
# For regular tokens:
price = debank_token['price'] # single source
tres_fiat = tres_amount * price
debank_fiat = debank_amount * price
delta_fiat = abs(tres_amount - debank_amount) * price
# For position tokens — same principle:
price = debank_asset_token['price']
tres_fiat = tres_aggregated_amount * price
debank_fiat = debank_amount * price
delta_fiat = abs(tres_aggregated_amount - debank_amount) * price
TRES 列には TRES の fiatValue を使用し、DeBank 列には DeBank の価格を使用することは避けてください。TRES と DeBank でトークン価格が異なる場合、誤解を招く法定通貨の差分が生じます。
ネイティブトークンの照合(マルチチェーンウォレット)
ネイティブトークン(ETH、BNB など)は、TRES では 1 つのウォレット内の複数のチェーンに表示されることがよくあります(例:Ethereum 上の ETH と Arbitrum 上の ETH)。DeBank の all_token_list は、chain フィールドを持つチェーンごとに個別のエントリーを返し、集計はしません。
ルール:まずチェーンごとに照合し、最後の手段としてのみ集計します。
-
チェーンごとの照合(デフォルト): 各 TRES ネイティブトークン残高について、残高のプラットフォームコンテキストを使い、シンボルとチェーンで対応する DeBank エントリーを見つけます。たとえば、Ethereum 上に 0.00956 ETH、Arbitrum 上に 0.001168 ETH を保有するウォレットでは、2 つの比較行が生成されます。それぞれ DeBank の
chain: "eth"エントリーとchain: "arb"エントリーに照合されます。 -
集計によるフォールバック(まれ): 同じシンボルについて、DeBank が TRES より少ないエントリーを返す場合にのみ、チェーンをまたいで TRES 残高を集計します。これは、DeBank が特定のブリッジ済みトークン残高を統合する場合に発生することがあります。集計する場合は、
"Aggregated: ETH (eth) + ETH (arb)"のような注記を追加します。
重要な理由: 比較前に無条件で集計すると、誤った差異が生じます。Ethereum の ETH が完全に一致していても Arbitrum の ETH に差がある場合、集計によって Ethereum の一致が見えなくなり、誤解を招く単一の差分が生成されます。チェーンごとに照合すれば粒度を保てるため、どのチェーンに不一致があるのかを正確に特定できます。
ステータスバッジ
| バッジ | 色 | 16 進数 | 意味 |
|---|---|---|---|
| 一致 | 緑 | #22c55e | 差分 < 1% |
| 軽微 | オレンジ | #f59e0b | 差分 1–10% |
| 大幅 | 赤 | #ef4444 | 差分 > 10% |
| 欠落 | グレー | #6b7280 | TRES にあるアセットが DeBank で見つからない |
| 未追跡 | 青 | #3b82f6 | DeBank にあるアセットが TRES で追跡されていない |
| ポジション | 紫 | #a855f7 | DeFi ポジショントークン(TRES データの有無を問わない) |
レポートのセクション
レンダリングされたレポート(HTML と PDF の両方)には、次の内容が含まれます。
- サマリーカード — 確認したウォレット数、比較したアセット数、一致、軽微、大幅、欠落、未追跡、ポジション、ならびに一致率(%)
- フィルターバー(HTML のみ)— ステータス別に絞り込むボタン:すべて、一致、軽微、大幅、欠落、未追跡、ポジション
- ウォレットごとのカード。以下を含みます。
- DeFi ポジションボックス(紫色のテーマで最上部)— 紫色のドットインジケーター、プロトコルラベル、2 つのステータスバッジを表示したポジションアセット
- 通常のトークンテーブル — 各アセットのシンボル、チェーン、TRES の数量(+法定通貨換算額)、DeBank の数量(+法定通貨換算額)、差分 %(+法定通貨換算の差分)、ステータスバッジ
- スキップしたウォレット — 検証されなかったウォレットとその理由の一覧
- 注記と注意事項 — 同期の遅延、DeFi ポジションの説明、ネイティブトークンの集約、価格フィルター、欠落/未追跡の説明
重要な注意事項
- 同期の遅延: TRES の残高は最後に同期した時点のものです。最近のオンチェーンアクティビティが差異として表示される場合があります。
- DeFi ポジション: LP、ステーキング、レンディングのポジションに含まれる基盤トークンは、専用の紫色のセクションに個別の行として表示されます。TRES のポジションデータがある場合は、TRES と DeBank の数量を比較します。TRES と DeBank ではスナップショットの時点が異なるため、アクティブな LP ポジションには通常、多少の差異が表示されます。
- ネイティブトークンの照合: ETH、BNB などは、まずチェーンごとに照合されます(DeBank の
chainフィールドを TRES のプラットフォームに対応付けて使用)。同じシンボルについて、DeBank が TRES より少ない件数を返した場合に限り、フォールバックとしてマルチチェーン残高を集約します。 - マルチチェーンの対応範囲: DeBank の
all_token_listはすべてのチェーンを対象とします。TRES で設定されていないチェーン上のトークンは「未追跡」として表示されます。 - 価格フィルター:
price < $0.01(価格ゼロ、null、またはマイクロキャップ)のトークンは、すべてのレポートから除外されます。 - DeBank での欠落: 通常、DeBank が除外するスパムトークンやエアドロップトークン(HEX、ASCZBR など)です。
- TRES での未追跡: TRES で設定されていないチェーン上のトークン、または少額のダスト残高です。
エラー処理
| 状況 | 対応 |
|---|---|
DeBank の 401 エラー | アーティファクトに「API キーが無効です」と表示 |
DeBank の 429 エラー | 「レート制限中 — 60 秒後に再読み込み」と表示 |
| 空ではないウォレットのトークンリストが空 | ウォレットを疑わしいものとしてフラグ付け |
| EVM 以外のウォレット | スキップし、「スキップしたウォレット」セクションに一覧表示 |
internalAccount ポジションのタイムアウト | ウォレット/プラットフォーム/アプリケーションごとに getStatelessWalletsPositions を代わりに使用 |
getStatelessWalletsPositions が空を返す | application パラメーターが指定されていることを確認します。指定がない場合、クエリは空を返します |
| ポジション ID を抽出できない | そのポジションをスキップ(クラッシュさせない) |
amount フィールドが数値ではなく文字列 | 算術演算の前に必ず float() でキャスト |
次のステップ(レポートのレンダリング後)
- 再実行 — いつでも最新データでレポートを再構築できます
- 詳細を確認 — 大幅な差異については、TRES でプラットフォーム間の該当アセットを調べ、同期がずれているチェーンを特定します
- ポジションの差異 — アクティブな LP ポジションにおける軽微な差異は、TRES と DeBank のスナップショット時点が異なるため、想定されるものです