Skip to content

Commit 2b7943f

Browse files
Aliiiuclaude
andcommitted
docs: qualify SDK paths + disambiguate id/protocol_id
Two Gemini round-4 findings on PR #30: - **Fully-qualified SDK paths in instructions.md.** The section references `getProtocolList` / `getAllProtocolsOfSupportedChains` by bare name. The SDK namespaces methods under `debank.chain.*`, `debank.protocol.*`, `debank.user.*`, etc., and an agent reading bare names could plausibly try `debank.getProtocolList(...)`. Updated to `debank.protocol.getProtocolList` and `debank.protocol.getAllProtocolsOfSupportedChains`. `resolveWrappedToken` also gets the `debank.` prefix for consistency — it IS on `debank` directly, but parallel naming helps the agent navigate. - **Disambiguate `id` vs `protocol_id` in the cookbook close.** The catalog entries have an `id` field that's actually the protocol slug. The `getUserProtocol` call also takes `id`, but there it's the wallet address. The previous one-line "pass the ID to getUserProtocol({id, protocol_id})" shorthand let an agent plausibly conflate them. Rewrote to spell out: the slug from `candidate.id` is passed AS `protocol_id`; the `id` parameter is the wallet address. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 3a0efa9 commit 2b7943f

4 files changed

Lines changed: 4 additions & 4 deletions

File tree

src/mcp/instructions/instructions.generated.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ DeBank's \`protocol_id\` slugs are NOT derivable from the human-facing name. Ver
160160
161161
**Before invoking any method that takes a \`protocol_id\` or \`token_id\`, look it up. Don't guess from the user's phrasing.**
162162
163-
For protocols, use \`getProtocolList({chain_id})\` (per-chain) or \`getAllProtocolsOfSupportedChains({chain_ids})\` (cross-chain) and filter the result by \`name\`. For tokens, ask the user for the contract address, or use \`resolveWrappedToken(keyword, chain_id)\` for the wrapped-native special cases. The \`find-protocol-id\` recipe via \`search_docs\` walks through the canonical discovery pattern with concrete examples.
163+
For protocols, use \`debank.protocol.getProtocolList({chain_id})\` (per-chain) or \`debank.protocol.getAllProtocolsOfSupportedChains({chain_ids})\` (cross-chain) and filter the result by \`name\`. For tokens, ask the user for the contract address, or use \`debank.resolveWrappedToken(keyword, chain_id)\` for the wrapped-native special cases. The \`find-protocol-id\` recipe via \`search_docs\` walks through the canonical discovery pattern with concrete examples.
164164
165165
## Wrapped token keywords
166166

src/mcp/instructions/instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ DeBank's `protocol_id` slugs are NOT derivable from the human-facing name. Versi
157157
158158
**Before invoking any method that takes a `protocol_id` or `token_id`, look it up. Don't guess from the user's phrasing.**
159159
160-
For protocols, use `getProtocolList({chain_id})` (per-chain) or `getAllProtocolsOfSupportedChains({chain_ids})` (cross-chain) and filter the result by `name`. For tokens, ask the user for the contract address, or use `resolveWrappedToken(keyword, chain_id)` for the wrapped-native special cases. The `find-protocol-id` recipe via `search_docs` walks through the canonical discovery pattern with concrete examples.
160+
For protocols, use `debank.protocol.getProtocolList({chain_id})` (per-chain) or `debank.protocol.getAllProtocolsOfSupportedChains({chain_ids})` (cross-chain) and filter the result by `name`. For tokens, ask the user for the contract address, or use `debank.resolveWrappedToken(keyword, chain_id)` for the wrapped-native special cases. The `find-protocol-id` recipe via `search_docs` walks through the canonical discovery pattern with concrete examples.
161161
162162
## Wrapped token keywords
163163

src/mcp/search-docs/cookbook/11-find-protocol-id.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ async function run(debank) {
4141
}
4242
```
4343

44-
Once you have the canonical ID from the response, pass it to `debank.user.getUserProtocol({ id, protocol_id })` — see the protocol-positions recipe.
44+
Once you have the canonical protocol slug (the `id` field on the candidate object — keep in mind it's named `id` in the catalog response but it's the protocol identifier, not the wallet), pass it as `protocol_id` to `debank.user.getUserProtocol({ id: "0xWALLET", protocol_id: "<the_slug>" })`. The `id` parameter on that call is the wallet address; don't conflate the two. See the protocol-positions recipe for the full shape.
4545

4646
**Things to know about the slug scheme (without baking in answers):**
4747

src/mcp/search-docs/embedded-index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1010,6 +1010,6 @@ export const ENTRIES: IndexEntry[] = [
10101010
id: "cookbook:11-find-protocol-id.md",
10111011
title: "Find a protocol's DeBank ID",
10121012
content:
1013-
'# Find a protocol\'s DeBank ID\n\nDeBank\'s `protocol_id` doesn\'t follow a single convention — versions, separators, and chain prefixes vary unpredictably between protocols, so guessing wastes calls and budget. The fix is always the same shape: enumerate the catalog and filter by `name`.\n\n```js\nasync function run(debank) {\n // Per-chain catalog returns every protocol on that chain — the\n // comprehensive, ungapped source. Prefer this when you know the chain.\n const protocols = await debank.protocol.getProtocolList({ chain_id: "eth" });\n\n // Case-insensitive name filter using whatever the user typed (the keyword\n // is the input, not the answer). The `name` field is the human-readable\n // label DeBank shows in the UI.\n const candidates = (protocols || [])\n .filter(p => p && p.name && p.name.toLowerCase().includes("aave"))\n .map(p => ({ id: p.id, name: p.name }));\n\n // Shape returned: `[{id: "<slug>", name: "<label>"}, ...]` — one entry per\n // match. Pick the slug whose `name` matches the version the user asked for.\n // DON\'T hardcode the slug values; read them off the response.\n return candidates;\n}\n```\n\nCross-chain catalog (when the user names the protocol but not the chain):\n\n```js\nasync function run(debank) {\n // Comprehensive multi-chain catalog — no top-N cap, includes\n // less-popular protocols on smaller chains. Each entry carries its\n // `chain` field for disambiguation. Use this when the user says\n // something like "Aave on Avalanche" and you need to pick the right\n // chain variant.\n const protocols = await debank.protocol.getAllProtocolsOfSupportedChains({\n chain_ids: "eth,arb,avax,matic,base",\n });\n\n return (protocols || [])\n .filter(p => p && p.name && p.name.toLowerCase().includes("aave"))\n .map(p => ({ id: p.id, chain: p.chain, name: p.name }));\n}\n```\n\nOnce you have the canonical ID from the response, pass it to `debank.user.getUserProtocol({ id, protocol_id })` — see the protocol-positions recipe.\n\n**Things to know about the slug scheme (without baking in answers):**\n\n- The slug is not derivable from the human-facing name. Don\'t try to construct it by replacing spaces, lowercasing, inserting `_v`, or any other transform — those forms generally don\'t exist in the catalog.\n- A protocol with multiple deployed versions has a separate slug per version. The `name` field disambiguates ("Foo V2" vs "Foo V3").\n- Per-chain deployments often use a `<chain>_<base>` prefix convention on non-Ethereum chains; Ethereum deployments are usually unprefixed. The actual catalog is authoritative — don\'t infer the prefix without checking.\n- Cross-chain "app-protocols" (dApps that wrap multiple per-chain deployments) live in a separate catalog under `getAppProtocolList` with their own slugs.\n',
1013+
'# Find a protocol\'s DeBank ID\n\nDeBank\'s `protocol_id` doesn\'t follow a single convention — versions, separators, and chain prefixes vary unpredictably between protocols, so guessing wastes calls and budget. The fix is always the same shape: enumerate the catalog and filter by `name`.\n\n```js\nasync function run(debank) {\n // Per-chain catalog returns every protocol on that chain — the\n // comprehensive, ungapped source. Prefer this when you know the chain.\n const protocols = await debank.protocol.getProtocolList({ chain_id: "eth" });\n\n // Case-insensitive name filter using whatever the user typed (the keyword\n // is the input, not the answer). The `name` field is the human-readable\n // label DeBank shows in the UI.\n const candidates = (protocols || [])\n .filter(p => p && p.name && p.name.toLowerCase().includes("aave"))\n .map(p => ({ id: p.id, name: p.name }));\n\n // Shape returned: `[{id: "<slug>", name: "<label>"}, ...]` — one entry per\n // match. Pick the slug whose `name` matches the version the user asked for.\n // DON\'T hardcode the slug values; read them off the response.\n return candidates;\n}\n```\n\nCross-chain catalog (when the user names the protocol but not the chain):\n\n```js\nasync function run(debank) {\n // Comprehensive multi-chain catalog — no top-N cap, includes\n // less-popular protocols on smaller chains. Each entry carries its\n // `chain` field for disambiguation. Use this when the user says\n // something like "Aave on Avalanche" and you need to pick the right\n // chain variant.\n const protocols = await debank.protocol.getAllProtocolsOfSupportedChains({\n chain_ids: "eth,arb,avax,matic,base",\n });\n\n return (protocols || [])\n .filter(p => p && p.name && p.name.toLowerCase().includes("aave"))\n .map(p => ({ id: p.id, chain: p.chain, name: p.name }));\n}\n```\n\nOnce you have the canonical protocol slug (the `id` field on the candidate object — keep in mind it\'s named `id` in the catalog response but it\'s the protocol identifier, not the wallet), pass it as `protocol_id` to `debank.user.getUserProtocol({ id: "0xWALLET", protocol_id: "<the_slug>" })`. The `id` parameter on that call is the wallet address; don\'t conflate the two. See the protocol-positions recipe for the full shape.\n\n**Things to know about the slug scheme (without baking in answers):**\n\n- The slug is not derivable from the human-facing name. Don\'t try to construct it by replacing spaces, lowercasing, inserting `_v`, or any other transform — those forms generally don\'t exist in the catalog.\n- A protocol with multiple deployed versions has a separate slug per version. The `name` field disambiguates ("Foo V2" vs "Foo V3").\n- Per-chain deployments often use a `<chain>_<base>` prefix convention on non-Ethereum chains; Ethereum deployments are usually unprefixed. The actual catalog is authoritative — don\'t infer the prefix without checking.\n- Cross-chain "app-protocols" (dApps that wrap multiple per-chain deployments) live in a separate catalog under `getAppProtocolList` with their own slugs.\n',
10141014
},
10151015
];

0 commit comments

Comments
 (0)