From 5af6e87d9ee1ebd424e6bb2601d747f452dff67a Mon Sep 17 00:00:00 2001 From: leon Date: Fri, 30 Oct 2026 15:18:54 +0800 Subject: [PATCH 1/5] docs: fix multi-sig sendTrx args, AGENTS.txt site links, Skills Node version - TL-034: pass fromAddress as the 3rd sendTrx argument and options as the 4th in multi-sign examples (dapp/multi-sign-transfer, plugin-wallet/ active-requests, en/zh incl. legacy snippets). TronWeb 6 rejects an options object in the 3rd slot with "Invalid origin address provided". - TL-E04: rewrite docs/AGENTS.txt links to published docs.tronlink.org URLs; the repo-relative docs/... paths 404 on the deployed site. - TL-E06: tronlink-skills default branch pins Node.js 24.22.1 exactly (.nvmrc, engines, install.sh hard check); update en/zh Skills page. - Regenerate llms-full / llms stamps. Co-Authored-By: Claude Opus 5.5 --- docs/AGENTS.txt | 26 ++++++++++++------------ docs/ai-support/tronlink-skills.en.md | 6 +++--- docs/ai-support/tronlink-skills.zh.md | 6 +++--- docs/dapp/multi-sign-transfer.en.md | 7 ++++--- docs/dapp/multi-sign-transfer.zh.md | 7 ++++--- docs/llms-full.en.txt | 25 +++++++++++++---------- docs/llms-full.txt | 25 +++++++++++++---------- docs/llms-full.zh.txt | 25 +++++++++++++---------- docs/llms.txt | 2 +- docs/llms.zh.txt | 2 +- docs/plugin-wallet/active-requests.en.md | 6 ++++-- docs/plugin-wallet/active-requests.zh.md | 6 ++++-- 12 files changed, 79 insertions(+), 64 deletions(-) diff --git a/docs/AGENTS.txt b/docs/AGENTS.txt index b429c40..b2c47c6 100644 --- a/docs/AGENTS.txt +++ b/docs/AGENTS.txt @@ -6,28 +6,28 @@ If you are an AI coding agent or an autonomous tool reading this for orientation ## Entry points for AI agents -- **Curated index:** [docs/llms.txt](docs/llms.txt) — short, link-only map of the documentation, following [llmstxt.org](https://llmstxt.org/). Use this first. -- **Single-fetch full text:** [docs/llms-full.txt](docs/llms-full.txt) — every English page concatenated for one-shot ingestion. The header records the generating commit SHA, UTC timestamp, page count, and a rough token estimate; check those before relying on the content. +- **Curated index:** [docs.tronlink.org/llms.txt](https://docs.tronlink.org/llms.txt) — short, link-only map of the documentation, following [llmstxt.org](https://llmstxt.org/). Use this first. +- **Single-fetch full text:** [docs.tronlink.org/llms-full.txt](https://docs.tronlink.org/llms-full.txt) — every English page concatenated for one-shot ingestion. The header records the generating commit SHA, UTC timestamp, page count, and a rough token estimate; check those before relying on the content. - **Human-readable site:** [https://docs.tronlink.org/](https://docs.tronlink.org/) ## Topic map | Surface | Doc | | --- | --- | -| DApp integration in the browser (TIP-6963 / `eth_requestAccounts` / `tronWeb`) | [docs/dapp/getting-started.en.md](docs/dapp/getting-started.en.md) + [docs/plugin-wallet/*](docs/plugin-wallet/) | -| Mobile DeepLink (`tronlinkoutside://`) | [docs/mobile/deeplink.en.md](docs/mobile/deeplink.en.md) | -| AI-agent tooling overview | [docs/ai-support/ai-llms.en.md](docs/ai-support/ai-llms.en.md) | -| MCP server (production) | [docs/ai-support/mcp-server-tronlink.en.md](docs/ai-support/mcp-server-tronlink.en.md) | -| MCP framework / SSOT error codes | [docs/ai-support/tronlink-mcp-core.en.md](docs/ai-support/tronlink-mcp-core.en.md) | -| MCP signer wrapper (HITL signing) | [docs/ai-support/mcp-tronlink-signer.en.md](docs/ai-support/mcp-tronlink-signer.en.md) | -| Signer SDK (browser-approval signing) | [docs/ai-support/tronlink-signer.en.md](docs/ai-support/tronlink-signer.en.md) | -| Read-only Skills package | [docs/ai-support/tronlink-skills.en.md](docs/ai-support/tronlink-skills.en.md) | -| CLI (transactions via browser approval) | [docs/ai-support/tronlink-cli.en.md](docs/ai-support/tronlink-cli.en.md) | -| Networks, addresses, glossary, FAQ | [docs/reference/](docs/reference/) | +| DApp integration in the browser (TIP-6963 / `eth_requestAccounts` / `tronWeb`) | [docs.tronlink.org/dapp/getting-started/](https://docs.tronlink.org/dapp/getting-started/) + [docs.tronlink.org/plugin-wallet/*](https://docs.tronlink.org/plugin-wallet/active-requests/) | +| Mobile DeepLink (`tronlinkoutside://`) | [docs.tronlink.org/mobile/deeplink/](https://docs.tronlink.org/mobile/deeplink/) | +| AI-agent tooling overview | [docs.tronlink.org/ai-support/ai-llms/](https://docs.tronlink.org/ai-support/ai-llms/) | +| MCP server (production) | [docs.tronlink.org/ai-support/mcp-server-tronlink/](https://docs.tronlink.org/ai-support/mcp-server-tronlink/) | +| MCP framework / SSOT error codes | [docs.tronlink.org/ai-support/tronlink-mcp-core/](https://docs.tronlink.org/ai-support/tronlink-mcp-core/) | +| MCP signer wrapper (HITL signing) | [docs.tronlink.org/ai-support/mcp-tronlink-signer/](https://docs.tronlink.org/ai-support/mcp-tronlink-signer/) | +| Signer SDK (browser-approval signing) | [docs.tronlink.org/ai-support/tronlink-signer/](https://docs.tronlink.org/ai-support/tronlink-signer/) | +| Read-only Skills package | [docs.tronlink.org/ai-support/tronlink-skills/](https://docs.tronlink.org/ai-support/tronlink-skills/) | +| CLI (transactions via browser approval) | [docs.tronlink.org/ai-support/tronlink-cli/](https://docs.tronlink.org/ai-support/tronlink-cli/) | +| Networks, addresses, glossary, FAQ | [docs.tronlink.org/reference/*](https://docs.tronlink.org/reference/networks/) | ## Source-of-truth boundaries -- **Error codes & retry semantics:** the SSOT is [docs/ai-support/tronlink-mcp-core.en.md#error-codes](docs/ai-support/tronlink-mcp-core.en.md#error-codes). Downstream docs link into it; do not duplicate the table. +- **Error codes & retry semantics:** the SSOT is [docs.tronlink.org/ai-support/tronlink-mcp-core/#error-codes](https://docs.tronlink.org/ai-support/tronlink-mcp-core/#error-codes). Downstream docs link into it; do not duplicate the table. - **Per-tool input schemas:** the SSOT is the running MCP server's `list_tools` (returns `inputSchema` per tool). Doc tables are a summary, not a contract. - **Versions:** each AI-support page ends with `Version & License` keyed to the corresponding upstream `package.json`. diff --git a/docs/ai-support/tronlink-skills.en.md b/docs/ai-support/tronlink-skills.en.md index 326b695..c578972 100644 --- a/docs/ai-support/tronlink-skills.en.md +++ b/docs/ai-support/tronlink-skills.en.md @@ -8,7 +8,7 @@ **Key Highlights:** - **6 skills, 33 commands** covering wallet, token research, market data, swaps, resources, and staking -- **Zero npm dependencies** — uses native Node.js 18+ `fetch` and `crypto`, no `npm install` needed +- **Zero npm dependencies** — uses native Node.js `fetch` and `crypto` (requires exactly Node.js 24.22.1 — see [Dependencies](#dependencies)), no `npm install` needed - **TRON-specific domain knowledge** — dedicated handling of Energy + Bandwidth resource model - **Multi-platform support** — Claude Code, Cursor, OpenCode, Codex CLI, LangChain/CrewAI - **Read-only & safe** — all commands are query-only, no private keys or signing involved @@ -39,7 +39,7 @@ Natural Language Input AI Agent (Claude Code / Cursor / OpenCode / Custom) | v -tron_api.mjs (Node.js 18+, native fetch, zero dependencies) +tron_api.mjs (Node.js 24.22.1, native fetch, zero dependencies) ├── Zero npm dependencies ├── TronGrid HTTP API (public or with API key) └── Tronscan API for token metadata @@ -481,7 +481,7 @@ tronlink-skills/ | Dependency | Required? | Purpose | |------------|-----------|---------| -| Node.js >= 18 | Yes | Runtime (native fetch, crypto) | +| Node.js 24.22.1 (exact) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | | npm install | Not needed | All operations work without any npm dependencies | --- diff --git a/docs/ai-support/tronlink-skills.zh.md b/docs/ai-support/tronlink-skills.zh.md index f02b423..61c101f 100644 --- a/docs/ai-support/tronlink-skills.zh.md +++ b/docs/ai-support/tronlink-skills.zh.md @@ -8,7 +8,7 @@ **核心亮点:** - **6 大技能,33 个命令**,涵盖钱包、代币研究、市场数据、兑换、资源和质押 -- **零 npm 依赖**:使用原生 Node.js 18+ `fetch` 和 `crypto`,无需 `npm install` +- **零 npm 依赖**:使用原生 Node.js `fetch` 和 `crypto`(要求精确版本 Node.js 24.22.1,见下方「依赖项」),无需 `npm install` - **TRON 专属领域知识** — 专门处理能量 + 带宽资源模型 - **多平台支持** — Claude Code、Cursor、OpenCode、Codex CLI、LangChain/CrewAI - **纯只读安全设计**:所有命令均为查询操作,不涉及私钥或签名 @@ -39,7 +39,7 @@ TronLink Skills 以深度 TRON 领域知识填补了这一空白。 AI 代理 (Claude Code / Cursor / OpenCode / 自定义) | v -tron_api.mjs (Node.js 18+, 原生 fetch, 零依赖) +tron_api.mjs (Node.js 24.22.1, 原生 fetch, 零依赖) ├── 零 npm 依赖 ├── TronGrid HTTP API(公共或带 API Key) └── Tronscan API 用于代币元数据 @@ -483,7 +483,7 @@ tronlink-skills/ | 依赖 | 是否必需? | 用途 | |------|-----------|------| -| Node.js >= 18 | 是 | 运行时(原生 fetch、crypto) | +| Node.js 24.22.1(精确版本) | 是 | 运行时(原生 fetch、crypto)。默认分支通过 `.nvmrc` 与 `package.json` 的 `engines` 固定该版本;`install.sh` 检测到其他版本会直接报错退出。安装前先执行 `nvm install 24.22.1 && nvm use 24.22.1`。 | | npm install | 不需要 | 所有操作均无需安装任何 npm 依赖 | --- diff --git a/docs/dapp/multi-sign-transfer.en.md b/docs/dapp/multi-sign-transfer.en.md index f95238b..3893c36 100644 --- a/docs/dapp/multi-sign-transfer.en.md +++ b/docs/dapp/multi-sign-transfer.en.md @@ -28,9 +28,10 @@ Use the resulting `id` as `permissionId` below. ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(...).active_permission +const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(fromAddress).active_permission const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId } ); // Step 1 try { @@ -50,7 +51,7 @@ Note that the broadcast only collects one signature in this call — a fully sig | Code | Meaning | Where it comes from | Retryable? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'` (string) | User clicked **Reject** in the signing popup | `tronWeb.trx.multiSign(...)` | No — user declined | -| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx({permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | +| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | | (thrown) | Signature weight below `threshold` after broadcast | `sendRawTransaction` | No — collect more signatures (one `multiSign` call per co-signer) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | Broadcast succeeded but execution failed on-chain | `getTransactionInfo(txid)` | **No — the tx is final; never auto-retry** | diff --git a/docs/dapp/multi-sign-transfer.zh.md b/docs/dapp/multi-sign-transfer.zh.md index ab8567a..b9baeb1 100644 --- a/docs/dapp/multi-sign-transfer.zh.md +++ b/docs/dapp/multi-sign-transfer.zh.md @@ -28,9 +28,10 @@ console.log(activePermissions.map(p => ({ id: p.id, name: p.permission_name, thr ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const activePermissionId = 2; // 通过 tronWeb.trx.getAccount(...).active_permission 查出 +const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 +const activePermissionId = 2; // 通过 tronWeb.trx.getAccount(fromAddress).active_permission 查出 const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId } ); // 步骤1 try { @@ -52,7 +53,7 @@ try { | 码 | 含义 | 来源 | 可重试? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'`(字符串) | 用户在签名弹窗里点【拒绝】 | `tronWeb.trx.multiSign(...)` | 否——用户拒绝 | -| (抛出) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx({permissionId})`——权限不存在或被撤销 | 否——重新 `getAccount(...).active_permission` 查 | +| (抛出) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})`——权限不存在或被撤销 | 否——重新 `getAccount(...).active_permission` 查 | | (抛出) | 签名权重广播后仍低于 `threshold` | `sendRawTransaction` | 否——再凑签名(每个 co-signer 一次 `multiSign`) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | 广播成功但链上执行失败 | `getTransactionInfo(txid)` | **否——交易已 final,永远不要自动重试** | diff --git a/docs/llms-full.en.txt b/docs/llms-full.en.txt index 0be7616..d3a3524 100644 --- a/docs/llms-full.en.txt +++ b/docs/llms-full.en.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-10-14T09:58:10Z -- Commit: 75c4f979dccf +- Generated: 2026-10-30T07:18:33Z +- Commit: 49ac6515992c - Language: en - Pages: 23 -- Token estimate: ~59,242 (chars / 4) +- Token estimate: ~59,416 (chars / 4) --- @@ -929,10 +929,11 @@ Refer to **Normal Transfer** above. ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; +const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); @@ -1462,10 +1463,11 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; + const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); @@ -3508,7 +3510,7 @@ This package is **the SSOT** for tool schemas, error codes, and `meta.schemaVers **Key Highlights:** - **6 skills, 33 commands** covering wallet, token research, market data, swaps, resources, and staking -- **Zero npm dependencies** — uses native Node.js 18+ `fetch` and `crypto`, no `npm install` needed +- **Zero npm dependencies** — uses native Node.js `fetch` and `crypto` (requires exactly Node.js 24.22.1 — see [Dependencies](#dependencies)), no `npm install` needed - **TRON-specific domain knowledge** — dedicated handling of Energy + Bandwidth resource model - **Multi-platform support** — Claude Code, Cursor, OpenCode, Codex CLI, LangChain/CrewAI - **Read-only & safe** — all commands are query-only, no private keys or signing involved @@ -3539,7 +3541,7 @@ Natural Language Input AI Agent (Claude Code / Cursor / OpenCode / Custom) | v -tron_api.mjs (Node.js 18+, native fetch, zero dependencies) +tron_api.mjs (Node.js 24.22.1, native fetch, zero dependencies) ├── Zero npm dependencies ├── TronGrid HTTP API (public or with API key) └── Tronscan API for token metadata @@ -3981,7 +3983,7 @@ tronlink-skills/ | Dependency | Required? | Purpose | |------------|-----------|---------| -| Node.js >= 18 | Yes | Runtime (native fetch, crypto) | +| Node.js 24.22.1 (exact) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | | npm install | Not needed | All operations work without any npm dependencies | --- @@ -5175,9 +5177,10 @@ Use the resulting `id` as `permissionId` below. ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(...).active_permission +const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(fromAddress).active_permission const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId } ); // Step 1 try { @@ -5197,7 +5200,7 @@ Note that the broadcast only collects one signature in this call — a fully sig | Code | Meaning | Where it comes from | Retryable? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'` (string) | User clicked **Reject** in the signing popup | `tronWeb.trx.multiSign(...)` | No — user declined | -| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx({permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | +| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | | (thrown) | Signature weight below `threshold` after broadcast | `sendRawTransaction` | No — collect more signatures (one `multiSign` call per co-signer) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | Broadcast succeeded but execution failed on-chain | `getTransactionInfo(txid)` | **No — the tx is final; never auto-retry** | diff --git a/docs/llms-full.txt b/docs/llms-full.txt index 0be7616..d3a3524 100644 --- a/docs/llms-full.txt +++ b/docs/llms-full.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-10-14T09:58:10Z -- Commit: 75c4f979dccf +- Generated: 2026-10-30T07:18:33Z +- Commit: 49ac6515992c - Language: en - Pages: 23 -- Token estimate: ~59,242 (chars / 4) +- Token estimate: ~59,416 (chars / 4) --- @@ -929,10 +929,11 @@ Refer to **Normal Transfer** above. ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; +const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); @@ -1462,10 +1463,11 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; + const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); @@ -3508,7 +3510,7 @@ This package is **the SSOT** for tool schemas, error codes, and `meta.schemaVers **Key Highlights:** - **6 skills, 33 commands** covering wallet, token research, market data, swaps, resources, and staking -- **Zero npm dependencies** — uses native Node.js 18+ `fetch` and `crypto`, no `npm install` needed +- **Zero npm dependencies** — uses native Node.js `fetch` and `crypto` (requires exactly Node.js 24.22.1 — see [Dependencies](#dependencies)), no `npm install` needed - **TRON-specific domain knowledge** — dedicated handling of Energy + Bandwidth resource model - **Multi-platform support** — Claude Code, Cursor, OpenCode, Codex CLI, LangChain/CrewAI - **Read-only & safe** — all commands are query-only, no private keys or signing involved @@ -3539,7 +3541,7 @@ Natural Language Input AI Agent (Claude Code / Cursor / OpenCode / Custom) | v -tron_api.mjs (Node.js 18+, native fetch, zero dependencies) +tron_api.mjs (Node.js 24.22.1, native fetch, zero dependencies) ├── Zero npm dependencies ├── TronGrid HTTP API (public or with API key) └── Tronscan API for token metadata @@ -3981,7 +3983,7 @@ tronlink-skills/ | Dependency | Required? | Purpose | |------------|-----------|---------| -| Node.js >= 18 | Yes | Runtime (native fetch, crypto) | +| Node.js 24.22.1 (exact) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | | npm install | Not needed | All operations work without any npm dependencies | --- @@ -5175,9 +5177,10 @@ Use the resulting `id` as `permissionId` below. ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(...).active_permission +const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(fromAddress).active_permission const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId } ); // Step 1 try { @@ -5197,7 +5200,7 @@ Note that the broadcast only collects one signature in this call — a fully sig | Code | Meaning | Where it comes from | Retryable? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'` (string) | User clicked **Reject** in the signing popup | `tronWeb.trx.multiSign(...)` | No — user declined | -| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx({permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | +| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | | (thrown) | Signature weight below `threshold` after broadcast | `sendRawTransaction` | No — collect more signatures (one `multiSign` call per co-signer) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | Broadcast succeeded but execution failed on-chain | `getTransactionInfo(txid)` | **No — the tx is final; never auto-retry** | diff --git a/docs/llms-full.zh.txt b/docs/llms-full.zh.txt index c729d8b..72b89ef 100644 --- a/docs/llms-full.zh.txt +++ b/docs/llms-full.zh.txt @@ -2,11 +2,11 @@ > 中文文档全文拼接,适合 LLM 一次性 ingest。由 scripts/gen_llms_full.py 生成。索引见 ../llms.txt 的 Localized 段。 -- Generated: 2026-10-14T09:58:10Z -- Commit: 75c4f979dccf +- Generated: 2026-10-30T07:18:33Z +- Commit: 49ac6515992c - Language: zh - Pages: 23 -- Token estimate: ~40,931 (chars / 4) +- Token estimate: ~41,046 (chars / 4) --- @@ -913,9 +913,10 @@ try { ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; +const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); // 步骤1 try { @@ -1428,9 +1429,10 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; + const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); // 步骤1 try { @@ -3400,7 +3402,7 @@ npm run clean # 删除 dist/ **核心亮点:** - **6 大技能,33 个命令**,涵盖钱包、代币研究、市场数据、兑换、资源和质押 -- **零 npm 依赖**:使用原生 Node.js 18+ `fetch` 和 `crypto`,无需 `npm install` +- **零 npm 依赖**:使用原生 Node.js `fetch` 和 `crypto`(要求精确版本 Node.js 24.22.1,见下方「依赖项」),无需 `npm install` - **TRON 专属领域知识** — 专门处理能量 + 带宽资源模型 - **多平台支持** — Claude Code、Cursor、OpenCode、Codex CLI、LangChain/CrewAI - **纯只读安全设计**:所有命令均为查询操作,不涉及私钥或签名 @@ -3431,7 +3433,7 @@ TronLink Skills 以深度 TRON 领域知识填补了这一空白。 AI 代理 (Claude Code / Cursor / OpenCode / 自定义) | v -tron_api.mjs (Node.js 18+, 原生 fetch, 零依赖) +tron_api.mjs (Node.js 24.22.1, 原生 fetch, 零依赖) ├── 零 npm 依赖 ├── TronGrid HTTP API(公共或带 API Key) └── Tronscan API 用于代币元数据 @@ -3875,7 +3877,7 @@ tronlink-skills/ | 依赖 | 是否必需? | 用途 | |------|-----------|------| -| Node.js >= 18 | 是 | 运行时(原生 fetch、crypto) | +| Node.js 24.22.1(精确版本) | 是 | 运行时(原生 fetch、crypto)。默认分支通过 `.nvmrc` 与 `package.json` 的 `engines` 固定该版本;`install.sh` 检测到其他版本会直接报错退出。安装前先执行 `nvm install 24.22.1 && nvm use 24.22.1`。 | | npm install | 不需要 | 所有操作均无需安装任何 npm 依赖 | --- @@ -5073,9 +5075,10 @@ console.log(activePermissions.map(p => ({ id: p.id, name: p.permission_name, thr ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const activePermissionId = 2; // 通过 tronWeb.trx.getAccount(...).active_permission 查出 +const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 +const activePermissionId = 2; // 通过 tronWeb.trx.getAccount(fromAddress).active_permission 查出 const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId } ); // 步骤1 try { @@ -5097,7 +5100,7 @@ try { | 码 | 含义 | 来源 | 可重试? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'`(字符串) | 用户在签名弹窗里点【拒绝】 | `tronWeb.trx.multiSign(...)` | 否——用户拒绝 | -| (抛出) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx({permissionId})`——权限不存在或被撤销 | 否——重新 `getAccount(...).active_permission` 查 | +| (抛出) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})`——权限不存在或被撤销 | 否——重新 `getAccount(...).active_permission` 查 | | (抛出) | 签名权重广播后仍低于 `threshold` | `sendRawTransaction` | 否——再凑签名(每个 co-signer 一次 `multiSign`) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | 广播成功但链上执行失败 | `getTransactionInfo(txid)` | **否——交易已 final,永远不要自动重试** | diff --git a/docs/llms.txt b/docs/llms.txt index d9d5946..76201b0 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -2,7 +2,7 @@ > TronLink is a decentralized wallet for the TRON ecosystem, available as a browser extension and a mobile app. This documentation covers integrating DApps with TronLink across the browser extension, the mobile app (via DeepLink), and AI/agent tooling (MCP servers, CLI, signer SDK). -> Updated: 2026-10-14T09:58:10Z · Commit: 75c4f979dccf +> Updated: 2026-10-30T07:18:33Z · Commit: 49ac6515992c How integration works: TronLink injects a `window.tron` provider into every page, exposing a `tronWeb` instance, a `request` method, and `on` / `removeListener` for events. A DApp detects the wallet via TIP-6963, requests authorization via `eth_requestAccounts` (TIP-1102), then builds, signs, and broadcasts transactions through `tronWeb`. Account/network changes arrive as passive `accountsChanged` / `chainChanged` events. diff --git a/docs/llms.zh.txt b/docs/llms.zh.txt index 001021a..811ca6b 100644 --- a/docs/llms.zh.txt +++ b/docs/llms.zh.txt @@ -2,7 +2,7 @@ > TronLink 是 TRON 生态的去中心化钱包,提供浏览器扩展和移动 App。本文档涵盖 DApp 通过浏览器扩展、移动端(DeepLink)以及 AI/智能体工具链(MCP 服务、CLI、签名 SDK)与 TronLink 集成。 -> Updated: 2026-10-14T09:58:10Z · Commit: 75c4f979dccf +> Updated: 2026-10-30T07:18:33Z · Commit: 49ac6515992c 集成原理:TronLink 向页面注入 `window.tron` provider,暴露 `tronWeb` 实例、`request` 方法以及 `on` / `removeListener` 事件订阅。DApp 通过 TIP-6963 检测钱包,用 `eth_requestAccounts`(TIP-1102)请求授权,再经 `tronWeb` 构建、签名并广播交易。账户/网络变化以 `accountsChanged` / `chainChanged` 被动事件送达。 diff --git a/docs/plugin-wallet/active-requests.en.md b/docs/plugin-wallet/active-requests.en.md index 66a86d7..1ce92a3 100644 --- a/docs/plugin-wallet/active-requests.en.md +++ b/docs/plugin-wallet/active-requests.en.md @@ -171,10 +171,11 @@ Refer to **Normal Transfer** above. ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; +const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); @@ -704,10 +705,11 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; + const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); diff --git a/docs/plugin-wallet/active-requests.zh.md b/docs/plugin-wallet/active-requests.zh.md index 3131a4f..b0ab384 100644 --- a/docs/plugin-wallet/active-requests.zh.md +++ b/docs/plugin-wallet/active-requests.zh.md @@ -155,9 +155,10 @@ try { ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; +const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); // 步骤1 try { @@ -670,9 +671,10 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; + const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( - toAddress, 10, + toAddress, 10, fromAddress, { permissionId: activePermissionId} ); // 步骤1 try { From 7c37b1ce958c70600d85be02ebf3ac6683b8cc69 Mon Sep 17 00:00:00 2001 From: leon Date: Wed, 4 Nov 2026 15:53:06 +0800 Subject: [PATCH 2/5] docs: scope Skills page versions, fix multi-sig error sources, generate AGENTS.txt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Skills (en/zh): state that the command tables describe v1.0.x while the default branch (v1.1.0, 7d2d58cb) adds 7 read-only commands and pins Node.js 24.22.1; detail the differences under Version & License. - Multi-sig (en/zh): permission errors are not thrown by sendTrx — the node rejects at broadcast and sendRawTransaction returns code SIGERROR with a hex message ("permission isn't exit", verified on Nile). Check the result in the example, document toUtf8 decoding and getSignWeight pre-check; clarify fromAddress is the tx owner, not necessarily the connected co-signer. - Replace personal-fork links (xueyuanying/docs) with TronLink/docs. - gen_llms_full.py now rebuilds docs/AGENTS.txt from AGENTS.md with site-absolute links, so the published copy cannot drift back to repo-relative paths (TL-E04). Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 2 +- docs/AGENTS.txt | 2 +- docs/ai-support/mcp-server-tronlink.en.md | 2 +- docs/ai-support/mcp-server-tronlink.zh.md | 2 +- docs/ai-support/tronlink-skills.en.md | 9 ++++- docs/ai-support/tronlink-skills.zh.md | 9 ++++- docs/dapp/multi-sign-transfer.en.md | 17 ++++++-- docs/dapp/multi-sign-transfer.zh.md | 17 ++++++-- docs/llms-full.en.txt | 38 ++++++++++++------ docs/llms-full.txt | 38 ++++++++++++------ docs/llms-full.zh.txt | 38 ++++++++++++------ docs/llms.txt | 2 +- docs/llms.zh.txt | 2 +- docs/plugin-wallet/active-requests.en.md | 4 +- docs/plugin-wallet/active-requests.zh.md | 4 +- scripts/gen_llms_full.py | 49 +++++++++++++++++++++++ 16 files changed, 177 insertions(+), 58 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index b429c40..a37738b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,4 +47,4 @@ If you need to change runtime behavior (tool schemas, error codes, transaction l python3 scripts/gen_llms_full.py ``` -This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate. Run it after any change under `docs/`. +This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate, and rebuilds the published `docs/AGENTS.txt` from this file with site-absolute links. Run it after any change under `docs/` or to this file; do not edit `docs/AGENTS.txt` by hand. diff --git a/docs/AGENTS.txt b/docs/AGENTS.txt index b2c47c6..931e630 100644 --- a/docs/AGENTS.txt +++ b/docs/AGENTS.txt @@ -47,4 +47,4 @@ If you need to change runtime behavior (tool schemas, error codes, transaction l python3 scripts/gen_llms_full.py ``` -This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate. Run it after any change under `docs/`. +This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate, and rebuilds the published `docs/AGENTS.txt` from this file with site-absolute links. Run it after any change under `docs/` or to this file; do not edit `docs/AGENTS.txt` by hand. diff --git a/docs/ai-support/mcp-server-tronlink.en.md b/docs/ai-support/mcp-server-tronlink.en.md index c70f599..e4f18bf 100644 --- a/docs/ai-support/mcp-server-tronlink.en.md +++ b/docs/ai-support/mcp-server-tronlink.en.md @@ -448,7 +448,7 @@ Pinned to the `package.json` of `mcp-server-tronlink@0.1.1`. Re-verify when bump These are **docs-side mirrors** of the most critical tool inputs — useful when an agent is writing a tool-call call site without an MCP session open. Runtime `list_tools` remains the authoritative source: the schemas there carry full Zod metadata (descriptions, `default`, etc.) plus `meta.schemaVersion`. Fields below are derived from `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts` and follow JSON Schema Draft 7. The full set of 52 tool schemas is **not** reproduced here — see core for the SSOT. -> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/xueyuanying/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. +> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. #### `tl_chain_send` — **Remote Write** diff --git a/docs/ai-support/mcp-server-tronlink.zh.md b/docs/ai-support/mcp-server-tronlink.zh.md index 4e23359..3d4e6f6 100644 --- a/docs/ai-support/mcp-server-tronlink.zh.md +++ b/docs/ai-support/mcp-server-tronlink.zh.md @@ -442,7 +442,7 @@ mcp-server-tronlink/ 以下是最关键工具输入的**文档侧镜像**——当 agent 需要在没有打开 MCP 会话的情况下写工具调用站点时使用。运行时 `list_tools` 仍是权威源:那里有完整的 Zod 元信息(描述、`default` 等)以及 `meta.schemaVersion`。下方字段抄自 `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts`,遵循 JSON Schema Draft 7。**未**镜像全部 52 个工具——以 core 仓库为 SSOT。 -> **平价由 CI 强制。** `scripts/check_doc_schema_parity.py`(在 push、PR 及每日定时通过 [`check-doc-schema-parity.yml`](https://github.com/xueyuanying/docs/blob/main/.github/workflows/check-doc-schema-parity.yml) 触发)会对下方每个块的顶层字段集 + required 标记与上游 `schemas.ts` 做 diff——上游改名或 required ↔ optional 漂移都会让 CI 失败。 +> **平价由 CI 强制。** `scripts/check_doc_schema_parity.py`(在 push、PR 及每日定时通过 [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml) 触发)会对下方每个块的顶层字段集 + required 标记与上游 `schemas.ts` 做 diff——上游改名或 required ↔ optional 漂移都会让 CI 失败。 #### `tl_chain_send` —— **Remote Write** diff --git a/docs/ai-support/tronlink-skills.en.md b/docs/ai-support/tronlink-skills.en.md index c578972..26e468e 100644 --- a/docs/ai-support/tronlink-skills.en.md +++ b/docs/ai-support/tronlink-skills.en.md @@ -4,6 +4,8 @@ **GitHub**: [https://github.com/TronLink/tronlink-skills](https://github.com/TronLink/tronlink-skills) +> **Version scope.** The command reference on this page (6 skills, 33 commands) was written for **v1.0.x**. The default branch — what `git clone` and `install.sh` install — is now **v1.1.0** (commit `7d2d58cb`): it adds 7 read-only commands (40 in total) and requires exactly **Node.js 24.22.1**. See [Version & License](#version-license); treat `tron_api.mjs --help` / MCP `tools/list` from your installed copy as authoritative. + **TronLink Wallet Skills** is an AI Agent skill set that provides complete TRON blockchain wallet and DeFi functionality through natural language. Designed for Claude Code, Cursor, OpenCode, Codex CLI, and other AI agents. **Key Highlights:** @@ -481,7 +483,7 @@ tronlink-skills/ | Dependency | Required? | Purpose | |------------|-----------|---------| -| Node.js 24.22.1 (exact) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | +| Node.js 24.22.1 (exact; default branch v1.1.0) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | | npm install | Not needed | All operations work without any npm dependencies | --- @@ -543,7 +545,10 @@ node scripts/tron_api.mjs optimize-cost --address TAddress... ## Version & License -- **Package:** `tronlink-skills` v1.0.1 +- **Package:** `tronlink-skills` v1.0.1 — the version the command tables on this page describe. +- **Default branch:** v1.1.0 (commit `7d2d58cb`, `package.json` `version: 1.1.0`), installed by `git clone` / `install.sh`. Differences from v1.0.1 that affect agents: + - 7 additional read-only commands, also exposed as `tron_` MCP tools: `wallet-approvals`, `wallet-overview`, `token-overview`, `bandwidth-price`, `tx-cost`, `chain-params`, `health-check`. 40 commands in total; all remain Network Read. + - Node.js is pinned to exactly 24.22.1 (`.nvmrc`, `engines`); `install.sh` exits on any other version. - **License:** MIT — `SPDX-License-Identifier: MIT` - **Changelog / releases:** [https://github.com/TronLink/tronlink-skills/releases](https://github.com/TronLink/tronlink-skills/releases) — no GitHub-tagged releases yet for v1.0.x; track changes by commit until the first tag. diff --git a/docs/ai-support/tronlink-skills.zh.md b/docs/ai-support/tronlink-skills.zh.md index 61c101f..3834cb9 100644 --- a/docs/ai-support/tronlink-skills.zh.md +++ b/docs/ai-support/tronlink-skills.zh.md @@ -4,6 +4,8 @@ **GitHub**: [https://github.com/TronLink/tronlink-skills](https://github.com/TronLink/tronlink-skills) +> **版本范围。** 本页的命令说明(6 大技能、33 个命令)基于 **v1.0.x** 编写。默认分支(即 `git clone` 和 `install.sh` 安装的版本)现为 **v1.1.0**(commit `7d2d58cb`):新增 7 个只读命令(共 40 个),并要求精确版本 **Node.js 24.22.1**。详见文末「版本与许可证」;以你本地安装版本的 `tron_api.mjs --help` / MCP `tools/list` 为准。 + **TronLink Wallet Skills** 是一套 AI Agent 技能集,通过自然语言提供完整的 TRON 区块链钱包和 DeFi 功能。专为 Claude Code、Cursor、OpenCode、Codex CLI 及其他 AI 代理设计。 **核心亮点:** @@ -483,7 +485,7 @@ tronlink-skills/ | 依赖 | 是否必需? | 用途 | |------|-----------|------| -| Node.js 24.22.1(精确版本) | 是 | 运行时(原生 fetch、crypto)。默认分支通过 `.nvmrc` 与 `package.json` 的 `engines` 固定该版本;`install.sh` 检测到其他版本会直接报错退出。安装前先执行 `nvm install 24.22.1 && nvm use 24.22.1`。 | +| Node.js 24.22.1(精确版本;默认分支 v1.1.0) | 是 | 运行时(原生 fetch、crypto)。默认分支通过 `.nvmrc` 与 `package.json` 的 `engines` 固定该版本;`install.sh` 检测到其他版本会直接报错退出。安装前先执行 `nvm install 24.22.1 && nvm use 24.22.1`。 | | npm install | 不需要 | 所有操作均无需安装任何 npm 依赖 | --- @@ -545,7 +547,10 @@ node scripts/tron_api.mjs optimize-cost --address T地址... ## 版本与许可证 -- **包:** `tronlink-skills` v1.0.1 +- **包:** `tronlink-skills` v1.0.1——本页命令表所描述的版本。 +- **默认分支:** v1.1.0(commit `7d2d58cb`,`package.json` 中 `version: 1.1.0`),`git clone` / `install.sh` 安装的就是该版本。与 v1.0.1 相比,影响 agent 的差异: + - 新增 7 个只读命令(同时以 `tron_` 形式暴露为 MCP 工具):`wallet-approvals`, `wallet-overview`, `token-overview`, `bandwidth-price`, `tx-cost`, `chain-params`, `health-check`。共 40 个命令,仍全部为 Network Read。 + - Node.js 固定为精确版本 24.22.1(`.nvmrc`、`engines`);`install.sh` 检测到其他版本会直接退出。 - **许可证:** MIT —— `SPDX-License-Identifier: MIT` - **变更记录 / 发布:** [https://github.com/TronLink/tronlink-skills/releases](https://github.com/TronLink/tronlink-skills/releases) —— 截至当前 v1.0.x 尚无 GitHub tag 发布;打 tag 之前请直接看 commit 历史。 diff --git a/docs/dapp/multi-sign-transfer.en.md b/docs/dapp/multi-sign-transfer.en.md index 3893c36..7628b6b 100644 --- a/docs/dapp/multi-sign-transfer.en.md +++ b/docs/dapp/multi-sign-transfer.en.md @@ -28,7 +28,10 @@ Use the resulting `id` as `permissionId` below. ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +// fromAddress = the account whose active permission controls the funds (the tx owner). +// It is not necessarily the connected signer: if the connected account is only a +// co-signer listed in that permission's keys[], set fromAddress to the controlled account. +const fromAddress = tronweb.defaultAddress.base58; const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(fromAddress).active_permission const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -36,7 +39,11 @@ const tx = await tronweb.transactionBuilder.sendTrx( ); // Step 1 try { const signedTx = await tronweb.trx.multiSign(tx, undefined, activePermissionId); // Step 2 - await tronweb.trx.sendRawTransaction(signedTx); // Step 3 + const res = await tronweb.trx.sendRawTransaction(signedTx); // Step 3 + if (!res.result) { + // Node rejections are returned, not thrown — see Errors below. + console.error(res.code, tronweb.toUtf8(res.message)); + } } catch (e) {} ``` @@ -51,8 +58,10 @@ Note that the broadcast only collects one signature in this call — a fully sig | Code | Meaning | Where it comes from | Retryable? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'` (string) | User clicked **Reject** in the signing popup | `tronWeb.trx.multiSign(...)` | No — user declined | -| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | -| (thrown) | Signature weight below `threshold` after broadcast | `sendRawTransaction` | No — collect more signatures (one `multiSign` call per co-signer) | +| `code: 'SIGERROR'`, `message` decodes to `Validate signature error: permission isn't exit` | `permissionId` does not exist on `fromAddress` (wrong or revoked). `sendTrx` does **not** validate the permission — the node rejects at broadcast | Return value of `sendRawTransaction(...)` (not thrown) | No — re-query `getAccount(fromAddress).active_permission` and rebuild the transaction | +| `code: 'SIGERROR'`, other `Validate signature error: …` messages | Signatures do not satisfy the permission — e.g. total weight below `threshold`, or a signer that is not in its `keys[]` | Return value of `sendRawTransaction(...)` (not thrown) | No — collect the missing signatures (one `multiSign` call per co-signer) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | Broadcast succeeded but execution failed on-chain | `getTransactionInfo(txid)` | **No — the tx is final; never auto-retry** | +`message` in a `sendRawTransaction` result is hex-encoded; decode it with `tronweb.toUtf8(res.message)`. To check before broadcasting, call `tronweb.trx.getSignWeight(signedTx)`: `result.code` is `PERMISSION_ERROR` when the permission does not exist and `NOT_ENOUGH_PERMISSION` while the signatures are still below `threshold`. + For cross-surface translation see the [Error Code Map](../reference/error-code-map.md). diff --git a/docs/dapp/multi-sign-transfer.zh.md b/docs/dapp/multi-sign-transfer.zh.md index b9baeb1..8502030 100644 --- a/docs/dapp/multi-sign-transfer.zh.md +++ b/docs/dapp/multi-sign-transfer.zh.md @@ -28,7 +28,10 @@ console.log(activePermissions.map(p => ({ id: p.id, name: p.permission_name, thr ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 +// fromAddress = 资金所在、由该 active 权限控制的账户(交易 owner)。 +// 它不一定是当前连接的签名账户:若当前账户只是该权限 keys[] 里的共同签名人, +// 请把 fromAddress 改成被控制的账户地址。 +const fromAddress = tronweb.defaultAddress.base58; const activePermissionId = 2; // 通过 tronWeb.trx.getAccount(fromAddress).active_permission 查出 const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -36,7 +39,11 @@ const tx = await tronweb.transactionBuilder.sendTrx( ); // 步骤1 try { const signedTx = await tronweb.trx.multiSign(tx, undefined, activePermissionId); // 步骤2 - await tronweb.trx.sendRawTransaction(signedTx); // 步骤3 + const res = await tronweb.trx.sendRawTransaction(signedTx); // 步骤3 + if (!res.result) { + // 节点拒绝以返回值给出,不会抛异常——见下方错误码。 + console.error(res.code, tronweb.toUtf8(res.message)); + } } catch (e) {} ``` @@ -53,8 +60,10 @@ try { | 码 | 含义 | 来源 | 可重试? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'`(字符串) | 用户在签名弹窗里点【拒绝】 | `tronWeb.trx.multiSign(...)` | 否——用户拒绝 | -| (抛出) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})`——权限不存在或被撤销 | 否——重新 `getAccount(...).active_permission` 查 | -| (抛出) | 签名权重广播后仍低于 `threshold` | `sendRawTransaction` | 否——再凑签名(每个 co-signer 一次 `multiSign`) | +| `code: 'SIGERROR'`,`message` 解码为 `Validate signature error: permission isn't exit` | `fromAddress` 上不存在该 `permissionId`(填错或已撤销)。`sendTrx` **不会**校验权限,由节点在广播时拒绝 | `sendRawTransaction(...)` 的返回值(不抛异常) | 否——重新查 `getAccount(fromAddress).active_permission` 后重建交易 | +| `code: 'SIGERROR'`,其他 `Validate signature error: …` 信息 | 签名不满足该权限——如总权重低于 `threshold`,或签名人不在其 `keys[]` 中 | `sendRawTransaction(...)` 的返回值(不抛异常) | 否——补齐缺少的签名(每个 co-signer 一次 `multiSign`) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | 广播成功但链上执行失败 | `getTransactionInfo(txid)` | **否——交易已 final,永远不要自动重试** | +`sendRawTransaction` 返回结果里的 `message` 是 hex 编码,用 `tronweb.toUtf8(res.message)` 解码。若要在广播前检查,可调用 `tronweb.trx.getSignWeight(signedTx)`:权限不存在时 `result.code` 为 `PERMISSION_ERROR`,签名权重仍低于 `threshold` 时为 `NOT_ENOUGH_PERMISSION`。 + 跨 surface 的码对照见[错误码对照表](../reference/error-code-map.md)。 diff --git a/docs/llms-full.en.txt b/docs/llms-full.en.txt index d3a3524..5714e3c 100644 --- a/docs/llms-full.en.txt +++ b/docs/llms-full.en.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-10-30T07:18:33Z -- Commit: 49ac6515992c +- Generated: 2026-11-04T07:52:55Z +- Commit: 5af6e87d9ee1 - Language: en - Pages: 23 -- Token estimate: ~59,416 (chars / 4) +- Token estimate: ~59,956 (chars / 4) --- @@ -929,7 +929,7 @@ Refer to **Normal Transfer** above. ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; -const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +const fromAddress = tronweb.defaultAddress.base58; // tx owner: the account this active permission controls; set it explicitly if the connected account is only a co-signer const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( @@ -1463,7 +1463,7 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; - const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different + const fromAddress = tronweb.defaultAddress.base58; // tx owner: the account this active permission controls; set it explicitly if the connected account is only a co-signer const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( @@ -2538,7 +2538,7 @@ Pinned to the `package.json` of `mcp-server-tronlink@0.1.1`. Re-verify when bump These are **docs-side mirrors** of the most critical tool inputs — useful when an agent is writing a tool-call call site without an MCP session open. Runtime `list_tools` remains the authoritative source: the schemas there carry full Zod metadata (descriptions, `default`, etc.) plus `meta.schemaVersion`. Fields below are derived from `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts` and follow JSON Schema Draft 7. The full set of 52 tool schemas is **not** reproduced here — see core for the SSOT. -> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/xueyuanying/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. +> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. #### `tl_chain_send` — **Remote Write** @@ -3506,6 +3506,8 @@ This package is **the SSOT** for tool schemas, error codes, and `meta.schemaVers **GitHub**: [https://github.com/TronLink/tronlink-skills](https://github.com/TronLink/tronlink-skills) +> **Version scope.** The command reference on this page (6 skills, 33 commands) was written for **v1.0.x**. The default branch — what `git clone` and `install.sh` install — is now **v1.1.0** (commit `7d2d58cb`): it adds 7 read-only commands (40 in total) and requires exactly **Node.js 24.22.1**. See [Version & License](#version-license); treat `tron_api.mjs --help` / MCP `tools/list` from your installed copy as authoritative. + **TronLink Wallet Skills** is an AI Agent skill set that provides complete TRON blockchain wallet and DeFi functionality through natural language. Designed for Claude Code, Cursor, OpenCode, Codex CLI, and other AI agents. **Key Highlights:** @@ -3983,7 +3985,7 @@ tronlink-skills/ | Dependency | Required? | Purpose | |------------|-----------|---------| -| Node.js 24.22.1 (exact) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | +| Node.js 24.22.1 (exact; default branch v1.1.0) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | | npm install | Not needed | All operations work without any npm dependencies | --- @@ -4045,7 +4047,10 @@ node scripts/tron_api.mjs optimize-cost --address TAddress... ## Version & License -- **Package:** `tronlink-skills` v1.0.1 +- **Package:** `tronlink-skills` v1.0.1 — the version the command tables on this page describe. +- **Default branch:** v1.1.0 (commit `7d2d58cb`, `package.json` `version: 1.1.0`), installed by `git clone` / `install.sh`. Differences from v1.0.1 that affect agents: + - 7 additional read-only commands, also exposed as `tron_` MCP tools: `wallet-approvals`, `wallet-overview`, `token-overview`, `bandwidth-price`, `tx-cost`, `chain-params`, `health-check`. 40 commands in total; all remain Network Read. + - Node.js is pinned to exactly 24.22.1 (`.nvmrc`, `engines`); `install.sh` exits on any other version. - **License:** MIT — `SPDX-License-Identifier: MIT` - **Changelog / releases:** [https://github.com/TronLink/tronlink-skills/releases](https://github.com/TronLink/tronlink-skills/releases) — no GitHub-tagged releases yet for v1.0.x; track changes by commit until the first tag. @@ -5177,7 +5182,10 @@ Use the resulting `id` as `permissionId` below. ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +// fromAddress = the account whose active permission controls the funds (the tx owner). +// It is not necessarily the connected signer: if the connected account is only a +// co-signer listed in that permission's keys[], set fromAddress to the controlled account. +const fromAddress = tronweb.defaultAddress.base58; const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(fromAddress).active_permission const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -5185,7 +5193,11 @@ const tx = await tronweb.transactionBuilder.sendTrx( ); // Step 1 try { const signedTx = await tronweb.trx.multiSign(tx, undefined, activePermissionId); // Step 2 - await tronweb.trx.sendRawTransaction(signedTx); // Step 3 + const res = await tronweb.trx.sendRawTransaction(signedTx); // Step 3 + if (!res.result) { + // Node rejections are returned, not thrown — see Errors below. + console.error(res.code, tronweb.toUtf8(res.message)); + } } catch (e) {} ``` @@ -5200,10 +5212,12 @@ Note that the broadcast only collects one signature in this call — a fully sig | Code | Meaning | Where it comes from | Retryable? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'` (string) | User clicked **Reject** in the signing popup | `tronWeb.trx.multiSign(...)` | No — user declined | -| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | -| (thrown) | Signature weight below `threshold` after broadcast | `sendRawTransaction` | No — collect more signatures (one `multiSign` call per co-signer) | +| `code: 'SIGERROR'`, `message` decodes to `Validate signature error: permission isn't exit` | `permissionId` does not exist on `fromAddress` (wrong or revoked). `sendTrx` does **not** validate the permission — the node rejects at broadcast | Return value of `sendRawTransaction(...)` (not thrown) | No — re-query `getAccount(fromAddress).active_permission` and rebuild the transaction | +| `code: 'SIGERROR'`, other `Validate signature error: …` messages | Signatures do not satisfy the permission — e.g. total weight below `threshold`, or a signer that is not in its `keys[]` | Return value of `sendRawTransaction(...)` (not thrown) | No — collect the missing signatures (one `multiSign` call per co-signer) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | Broadcast succeeded but execution failed on-chain | `getTransactionInfo(txid)` | **No — the tx is final; never auto-retry** | +`message` in a `sendRawTransaction` result is hex-encoded; decode it with `tronweb.toUtf8(res.message)`. To check before broadcasting, call `tronweb.trx.getSignWeight(signedTx)`: `result.code` is `PERMISSION_ERROR` when the permission does not exist and `NOT_ENOUGH_PERMISSION` while the signatures are still below `threshold`. + For cross-surface translation see the [Error Code Map](../reference/error-code-map.md). --- diff --git a/docs/llms-full.txt b/docs/llms-full.txt index d3a3524..5714e3c 100644 --- a/docs/llms-full.txt +++ b/docs/llms-full.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-10-30T07:18:33Z -- Commit: 49ac6515992c +- Generated: 2026-11-04T07:52:55Z +- Commit: 5af6e87d9ee1 - Language: en - Pages: 23 -- Token estimate: ~59,416 (chars / 4) +- Token estimate: ~59,956 (chars / 4) --- @@ -929,7 +929,7 @@ Refer to **Normal Transfer** above. ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; -const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +const fromAddress = tronweb.defaultAddress.base58; // tx owner: the account this active permission controls; set it explicitly if the connected account is only a co-signer const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( @@ -1463,7 +1463,7 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; - const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different + const fromAddress = tronweb.defaultAddress.base58; // tx owner: the account this active permission controls; set it explicitly if the connected account is only a co-signer const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( @@ -2538,7 +2538,7 @@ Pinned to the `package.json` of `mcp-server-tronlink@0.1.1`. Re-verify when bump These are **docs-side mirrors** of the most critical tool inputs — useful when an agent is writing a tool-call call site without an MCP session open. Runtime `list_tools` remains the authoritative source: the schemas there carry full Zod metadata (descriptions, `default`, etc.) plus `meta.schemaVersion`. Fields below are derived from `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts` and follow JSON Schema Draft 7. The full set of 52 tool schemas is **not** reproduced here — see core for the SSOT. -> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/xueyuanying/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. +> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. #### `tl_chain_send` — **Remote Write** @@ -3506,6 +3506,8 @@ This package is **the SSOT** for tool schemas, error codes, and `meta.schemaVers **GitHub**: [https://github.com/TronLink/tronlink-skills](https://github.com/TronLink/tronlink-skills) +> **Version scope.** The command reference on this page (6 skills, 33 commands) was written for **v1.0.x**. The default branch — what `git clone` and `install.sh` install — is now **v1.1.0** (commit `7d2d58cb`): it adds 7 read-only commands (40 in total) and requires exactly **Node.js 24.22.1**. See [Version & License](#version-license); treat `tron_api.mjs --help` / MCP `tools/list` from your installed copy as authoritative. + **TronLink Wallet Skills** is an AI Agent skill set that provides complete TRON blockchain wallet and DeFi functionality through natural language. Designed for Claude Code, Cursor, OpenCode, Codex CLI, and other AI agents. **Key Highlights:** @@ -3983,7 +3985,7 @@ tronlink-skills/ | Dependency | Required? | Purpose | |------------|-----------|---------| -| Node.js 24.22.1 (exact) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | +| Node.js 24.22.1 (exact; default branch v1.1.0) | Yes | Runtime (native fetch, crypto). Pinned by `.nvmrc` and `package.json` `engines` on the default branch; `install.sh` exits with an error on any other version. Run `nvm install 24.22.1 && nvm use 24.22.1` before installing. | | npm install | Not needed | All operations work without any npm dependencies | --- @@ -4045,7 +4047,10 @@ node scripts/tron_api.mjs optimize-cost --address TAddress... ## Version & License -- **Package:** `tronlink-skills` v1.0.1 +- **Package:** `tronlink-skills` v1.0.1 — the version the command tables on this page describe. +- **Default branch:** v1.1.0 (commit `7d2d58cb`, `package.json` `version: 1.1.0`), installed by `git clone` / `install.sh`. Differences from v1.0.1 that affect agents: + - 7 additional read-only commands, also exposed as `tron_` MCP tools: `wallet-approvals`, `wallet-overview`, `token-overview`, `bandwidth-price`, `tx-cost`, `chain-params`, `health-check`. 40 commands in total; all remain Network Read. + - Node.js is pinned to exactly 24.22.1 (`.nvmrc`, `engines`); `install.sh` exits on any other version. - **License:** MIT — `SPDX-License-Identifier: MIT` - **Changelog / releases:** [https://github.com/TronLink/tronlink-skills/releases](https://github.com/TronLink/tronlink-skills/releases) — no GitHub-tagged releases yet for v1.0.x; track changes by commit until the first tag. @@ -5177,7 +5182,10 @@ Use the resulting `id` as `permissionId` below. ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +// fromAddress = the account whose active permission controls the funds (the tx owner). +// It is not necessarily the connected signer: if the connected account is only a +// co-signer listed in that permission's keys[], set fromAddress to the controlled account. +const fromAddress = tronweb.defaultAddress.base58; const activePermissionId = 2; // obtained via tronWeb.trx.getAccount(fromAddress).active_permission const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -5185,7 +5193,11 @@ const tx = await tronweb.transactionBuilder.sendTrx( ); // Step 1 try { const signedTx = await tronweb.trx.multiSign(tx, undefined, activePermissionId); // Step 2 - await tronweb.trx.sendRawTransaction(signedTx); // Step 3 + const res = await tronweb.trx.sendRawTransaction(signedTx); // Step 3 + if (!res.result) { + // Node rejections are returned, not thrown — see Errors below. + console.error(res.code, tronweb.toUtf8(res.message)); + } } catch (e) {} ``` @@ -5200,10 +5212,12 @@ Note that the broadcast only collects one signature in this call — a fully sig | Code | Meaning | Where it comes from | Retryable? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'` (string) | User clicked **Reject** in the signing popup | `tronWeb.trx.multiSign(...)` | No — user declined | -| (thrown) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})` — wrong or revoked permission | No — re-query `getAccount(...).active_permission` | -| (thrown) | Signature weight below `threshold` after broadcast | `sendRawTransaction` | No — collect more signatures (one `multiSign` call per co-signer) | +| `code: 'SIGERROR'`, `message` decodes to `Validate signature error: permission isn't exit` | `permissionId` does not exist on `fromAddress` (wrong or revoked). `sendTrx` does **not** validate the permission — the node rejects at broadcast | Return value of `sendRawTransaction(...)` (not thrown) | No — re-query `getAccount(fromAddress).active_permission` and rebuild the transaction | +| `code: 'SIGERROR'`, other `Validate signature error: …` messages | Signatures do not satisfy the permission — e.g. total weight below `threshold`, or a signer that is not in its `keys[]` | Return value of `sendRawTransaction(...)` (not thrown) | No — collect the missing signatures (one `multiSign` call per co-signer) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | Broadcast succeeded but execution failed on-chain | `getTransactionInfo(txid)` | **No — the tx is final; never auto-retry** | +`message` in a `sendRawTransaction` result is hex-encoded; decode it with `tronweb.toUtf8(res.message)`. To check before broadcasting, call `tronweb.trx.getSignWeight(signedTx)`: `result.code` is `PERMISSION_ERROR` when the permission does not exist and `NOT_ENOUGH_PERMISSION` while the signatures are still below `threshold`. + For cross-surface translation see the [Error Code Map](../reference/error-code-map.md). --- diff --git a/docs/llms-full.zh.txt b/docs/llms-full.zh.txt index 72b89ef..b43de31 100644 --- a/docs/llms-full.zh.txt +++ b/docs/llms-full.zh.txt @@ -2,11 +2,11 @@ > 中文文档全文拼接,适合 LLM 一次性 ingest。由 scripts/gen_llms_full.py 生成。索引见 ../llms.txt 的 Localized 段。 -- Generated: 2026-10-30T07:18:33Z -- Commit: 49ac6515992c +- Generated: 2026-11-04T07:52:55Z +- Commit: 5af6e87d9ee1 - Language: zh - Pages: 23 -- Token estimate: ~41,046 (chars / 4) +- Token estimate: ~41,384 (chars / 4) --- @@ -913,7 +913,7 @@ try { ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; -const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 +const fromAddress = tronweb.defaultAddress.base58; // 交易 owner:由该 active 权限控制的账户;若当前账户只是共同签名人,请显式填写被控制账户 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -1429,7 +1429,7 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; - const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 + const fromAddress = tronweb.defaultAddress.base58; // 交易 owner:由该 active 权限控制的账户;若当前账户只是共同签名人,请显式填写被控制账户 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -2460,7 +2460,7 @@ mcp-server-tronlink/ 以下是最关键工具输入的**文档侧镜像**——当 agent 需要在没有打开 MCP 会话的情况下写工具调用站点时使用。运行时 `list_tools` 仍是权威源:那里有完整的 Zod 元信息(描述、`default` 等)以及 `meta.schemaVersion`。下方字段抄自 `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts`,遵循 JSON Schema Draft 7。**未**镜像全部 52 个工具——以 core 仓库为 SSOT。 -> **平价由 CI 强制。** `scripts/check_doc_schema_parity.py`(在 push、PR 及每日定时通过 [`check-doc-schema-parity.yml`](https://github.com/xueyuanying/docs/blob/main/.github/workflows/check-doc-schema-parity.yml) 触发)会对下方每个块的顶层字段集 + required 标记与上游 `schemas.ts` 做 diff——上游改名或 required ↔ optional 漂移都会让 CI 失败。 +> **平价由 CI 强制。** `scripts/check_doc_schema_parity.py`(在 push、PR 及每日定时通过 [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml) 触发)会对下方每个块的顶层字段集 + required 标记与上游 `schemas.ts` 做 diff——上游改名或 required ↔ optional 漂移都会让 CI 失败。 #### `tl_chain_send` —— **Remote Write** @@ -3398,6 +3398,8 @@ npm run clean # 删除 dist/ **GitHub**: [https://github.com/TronLink/tronlink-skills](https://github.com/TronLink/tronlink-skills) +> **版本范围。** 本页的命令说明(6 大技能、33 个命令)基于 **v1.0.x** 编写。默认分支(即 `git clone` 和 `install.sh` 安装的版本)现为 **v1.1.0**(commit `7d2d58cb`):新增 7 个只读命令(共 40 个),并要求精确版本 **Node.js 24.22.1**。详见文末「版本与许可证」;以你本地安装版本的 `tron_api.mjs --help` / MCP `tools/list` 为准。 + **TronLink Wallet Skills** 是一套 AI Agent 技能集,通过自然语言提供完整的 TRON 区块链钱包和 DeFi 功能。专为 Claude Code、Cursor、OpenCode、Codex CLI 及其他 AI 代理设计。 **核心亮点:** @@ -3877,7 +3879,7 @@ tronlink-skills/ | 依赖 | 是否必需? | 用途 | |------|-----------|------| -| Node.js 24.22.1(精确版本) | 是 | 运行时(原生 fetch、crypto)。默认分支通过 `.nvmrc` 与 `package.json` 的 `engines` 固定该版本;`install.sh` 检测到其他版本会直接报错退出。安装前先执行 `nvm install 24.22.1 && nvm use 24.22.1`。 | +| Node.js 24.22.1(精确版本;默认分支 v1.1.0) | 是 | 运行时(原生 fetch、crypto)。默认分支通过 `.nvmrc` 与 `package.json` 的 `engines` 固定该版本;`install.sh` 检测到其他版本会直接报错退出。安装前先执行 `nvm install 24.22.1 && nvm use 24.22.1`。 | | npm install | 不需要 | 所有操作均无需安装任何 npm 依赖 | --- @@ -3939,7 +3941,10 @@ node scripts/tron_api.mjs optimize-cost --address T地址... ## 版本与许可证 -- **包:** `tronlink-skills` v1.0.1 +- **包:** `tronlink-skills` v1.0.1——本页命令表所描述的版本。 +- **默认分支:** v1.1.0(commit `7d2d58cb`,`package.json` 中 `version: 1.1.0`),`git clone` / `install.sh` 安装的就是该版本。与 v1.0.1 相比,影响 agent 的差异: + - 新增 7 个只读命令(同时以 `tron_` 形式暴露为 MCP 工具):`wallet-approvals`, `wallet-overview`, `token-overview`, `bandwidth-price`, `tx-cost`, `chain-params`, `health-check`。共 40 个命令,仍全部为 Network Read。 + - Node.js 固定为精确版本 24.22.1(`.nvmrc`、`engines`);`install.sh` 检测到其他版本会直接退出。 - **许可证:** MIT —— `SPDX-License-Identifier: MIT` - **变更记录 / 发布:** [https://github.com/TronLink/tronlink-skills/releases](https://github.com/TronLink/tronlink-skills/releases) —— 截至当前 v1.0.x 尚无 GitHub tag 发布;打 tag 之前请直接看 commit 历史。 @@ -5075,7 +5080,10 @@ console.log(activePermissions.map(p => ({ id: p.id, name: p.permission_name, thr ```javascript const tronweb = window.tron.tronWeb; const toAddress = "TRKb2nAnCBfwxnLxgoKJro6VbyA6QmsuXq"; -const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 +// fromAddress = 资金所在、由该 active 权限控制的账户(交易 owner)。 +// 它不一定是当前连接的签名账户:若当前账户只是该权限 keys[] 里的共同签名人, +// 请把 fromAddress 改成被控制的账户地址。 +const fromAddress = tronweb.defaultAddress.base58; const activePermissionId = 2; // 通过 tronWeb.trx.getAccount(fromAddress).active_permission 查出 const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -5083,7 +5091,11 @@ const tx = await tronweb.transactionBuilder.sendTrx( ); // 步骤1 try { const signedTx = await tronweb.trx.multiSign(tx, undefined, activePermissionId); // 步骤2 - await tronweb.trx.sendRawTransaction(signedTx); // 步骤3 + const res = await tronweb.trx.sendRawTransaction(signedTx); // 步骤3 + if (!res.result) { + // 节点拒绝以返回值给出,不会抛异常——见下方错误码。 + console.error(res.code, tronweb.toUtf8(res.message)); + } } catch (e) {} ``` @@ -5100,10 +5112,12 @@ try { | 码 | 含义 | 来源 | 可重试? | | :---: | --- | --- | :---: | | `'Confirmation declined by user'`(字符串) | 用户在签名弹窗里点【拒绝】 | `tronWeb.trx.multiSign(...)` | 否——用户拒绝 | -| (抛出) | `permission_id not active` / `permission_id not exist` | `transactionBuilder.sendTrx(to, amount, from, {permissionId})`——权限不存在或被撤销 | 否——重新 `getAccount(...).active_permission` 查 | -| (抛出) | 签名权重广播后仍低于 `threshold` | `sendRawTransaction` | 否——再凑签名(每个 co-signer 一次 `multiSign`) | +| `code: 'SIGERROR'`,`message` 解码为 `Validate signature error: permission isn't exit` | `fromAddress` 上不存在该 `permissionId`(填错或已撤销)。`sendTrx` **不会**校验权限,由节点在广播时拒绝 | `sendRawTransaction(...)` 的返回值(不抛异常) | 否——重新查 `getAccount(fromAddress).active_permission` 后重建交易 | +| `code: 'SIGERROR'`,其他 `Validate signature error: …` 信息 | 签名不满足该权限——如总权重低于 `threshold`,或签名人不在其 `keys[]` 中 | `sendRawTransaction(...)` 的返回值(不抛异常) | 否——补齐缺少的签名(每个 co-signer 一次 `multiSign`) | | `REVERT` / `OUT_OF_ENERGY` / `FAILED` | 广播成功但链上执行失败 | `getTransactionInfo(txid)` | **否——交易已 final,永远不要自动重试** | +`sendRawTransaction` 返回结果里的 `message` 是 hex 编码,用 `tronweb.toUtf8(res.message)` 解码。若要在广播前检查,可调用 `tronweb.trx.getSignWeight(signedTx)`:权限不存在时 `result.code` 为 `PERMISSION_ERROR`,签名权重仍低于 `threshold` 时为 `NOT_ENOUGH_PERMISSION`。 + 跨 surface 的码对照见[错误码对照表](../reference/error-code-map.md)。 --- diff --git a/docs/llms.txt b/docs/llms.txt index 76201b0..ad3262b 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -2,7 +2,7 @@ > TronLink is a decentralized wallet for the TRON ecosystem, available as a browser extension and a mobile app. This documentation covers integrating DApps with TronLink across the browser extension, the mobile app (via DeepLink), and AI/agent tooling (MCP servers, CLI, signer SDK). -> Updated: 2026-10-30T07:18:33Z · Commit: 49ac6515992c +> Updated: 2026-11-04T07:52:55Z · Commit: 5af6e87d9ee1 How integration works: TronLink injects a `window.tron` provider into every page, exposing a `tronWeb` instance, a `request` method, and `on` / `removeListener` for events. A DApp detects the wallet via TIP-6963, requests authorization via `eth_requestAccounts` (TIP-1102), then builds, signs, and broadcasts transactions through `tronWeb`. Account/network changes arrive as passive `accountsChanged` / `chainChanged` events. diff --git a/docs/llms.zh.txt b/docs/llms.zh.txt index 811ca6b..76babf5 100644 --- a/docs/llms.zh.txt +++ b/docs/llms.zh.txt @@ -2,7 +2,7 @@ > TronLink 是 TRON 生态的去中心化钱包,提供浏览器扩展和移动 App。本文档涵盖 DApp 通过浏览器扩展、移动端(DeepLink)以及 AI/智能体工具链(MCP 服务、CLI、签名 SDK)与 TronLink 集成。 -> Updated: 2026-10-30T07:18:33Z · Commit: 49ac6515992c +> Updated: 2026-11-04T07:52:55Z · Commit: 5af6e87d9ee1 集成原理:TronLink 向页面注入 `window.tron` provider,暴露 `tronWeb` 实例、`request` 方法以及 `on` / `removeListener` 事件订阅。DApp 通过 TIP-6963 检测钱包,用 `eth_requestAccounts`(TIP-1102)请求授权,再经 `tronWeb` 构建、签名并广播交易。账户/网络变化以 `accountsChanged` / `chainChanged` 被动事件送达。 diff --git a/docs/plugin-wallet/active-requests.en.md b/docs/plugin-wallet/active-requests.en.md index 1ce92a3..51f975f 100644 --- a/docs/plugin-wallet/active-requests.en.md +++ b/docs/plugin-wallet/active-requests.en.md @@ -171,7 +171,7 @@ Refer to **Normal Transfer** above. ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; -const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different +const fromAddress = tronweb.defaultAddress.base58; // tx owner: the account this active permission controls; set it explicitly if the connected account is only a co-signer const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( @@ -705,7 +705,7 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; - const fromAddress = tronweb.defaultAddress.base58; // the multi-sig controlled account that pays; replace if different + const fromAddress = tronweb.defaultAddress.base58; // tx owner: the account this active permission controls; set it explicitly if the connected account is only a co-signer const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( diff --git a/docs/plugin-wallet/active-requests.zh.md b/docs/plugin-wallet/active-requests.zh.md index b0ab384..285a02d 100644 --- a/docs/plugin-wallet/active-requests.zh.md +++ b/docs/plugin-wallet/active-requests.zh.md @@ -155,7 +155,7 @@ try { ```typescript const tronweb = window.tron.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; -const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 +const fromAddress = tronweb.defaultAddress.base58; // 交易 owner:由该 active 权限控制的账户;若当前账户只是共同签名人,请显式填写被控制账户 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, @@ -671,7 +671,7 @@ if (window.tronLink.ready) { if (window.tronLink.ready) { const tronweb = tronLink.tronWeb; const toAddress = "TDvSsdrNM5eeXNL3czpa6AxLDHZA9nwe9K"; - const fromAddress = tronweb.defaultAddress.base58; // 被多签控制的转出账户;若不是当前账户请替换 + const fromAddress = tronweb.defaultAddress.base58; // 交易 owner:由该 active 权限控制的账户;若当前账户只是共同签名人,请显式填写被控制账户 const activePermissionId = 2; const tx = await tronweb.transactionBuilder.sendTrx( toAddress, 10, fromAddress, diff --git a/scripts/gen_llms_full.py b/scripts/gen_llms_full.py index 060f944..048c5b6 100644 --- a/scripts/gen_llms_full.py +++ b/scripts/gen_llms_full.py @@ -8,6 +8,9 @@ We also write `llms-full.txt` as a verbatim copy of the English bundle so existing links (e.g. /llms-full.txt) keep working. +It also rebuilds docs/AGENTS.txt (served at /AGENTS.txt) from the repo-root +AGENTS.md, rewriting repo-relative `docs/...` links to docs.tronlink.org URLs. + Usage: python3 scripts/gen_llms_full.py @@ -311,6 +314,48 @@ def verify_live(base_url: str, sample_size: int = 5) -> int: return 0 +SITE_BASE = "https://docs.tronlink.org/" + +# Repo-relative directory links in AGENTS.md -> a representative published page. +AGENTS_DIR_TARGETS = { + "plugin-wallet/": "plugin-wallet/active-requests/", + "reference/": "reference/networks/", +} + + +def agents_link_url(href: str) -> str: + """`docs/ai-support/ai-llms.en.md#x` -> `https://docs.tronlink.org/ai-support/ai-llms/#x`.""" + path, _, frag = href[len("docs/"):].partition("#") + if path.endswith(".en.md"): + path = path[: -len(".en.md")] + "/" + path = AGENTS_DIR_TARGETS.get(path, path) + return SITE_BASE + path + (f"#{frag}" if frag else "") + + +def render_agents_txt() -> str: + """Published copy of AGENTS.md with repo-relative `docs/...` links made absolute. + + AGENTS.md links are correct on GitHub, but served from the site root as + /AGENTS.txt they resolve to /docs/... and 404 (scan finding TL-E04). + """ + def repl(m: re.Match) -> str: + text, href = m.group(1), m.group(2) + url = agents_link_url(href) + if text.startswith("docs/"): + # Path-like label: pages show their URL, directories read as `/*`. + rel = text[len("docs/"):] + if rel.endswith("/"): + rel += "*" + text = "docs.tronlink.org/" + rel if rel.endswith(("*", ".txt")) else url[len("https://"):] + return f"[{text}]({url})" + + src = (REPO / "AGENTS.md").read_text(encoding="utf-8") + out = re.sub(r"\[([^\]]+)\]\((docs/[^)]+)\)", repl, src) + if "](docs/" in out: + raise SystemExit("AGENTS.txt still contains repo-relative docs/ links") + return out + + def generate_bundles() -> None: sha = git_short_sha() generated_at = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") @@ -342,6 +387,10 @@ def generate_bundles() -> None: stamp_index_header(index_path, generated_at, sha) print(f"Stamped {index_path.relative_to(REPO)} (commit {sha})") + agents_path = DOCS / "AGENTS.txt" + agents_path.write_text(render_agents_txt(), encoding="utf-8") + print(f"Wrote {agents_path.relative_to(REPO)} (from AGENTS.md, site-absolute links)") + if all_missing: msg = "; ".join(f"{lang}: {', '.join(m)}" for lang, m in all_missing.items()) raise SystemExit("Missing pages — " + msg) From 90b7e3d76d9db3cb3a9fb2d1634552bb36c04e20 Mon Sep 17 00:00:00 2001 From: leon Date: Wed, 4 Nov 2026 16:51:09 +0800 Subject: [PATCH 3/5] docs: bundle Error Code Map into llms-full; CI check for stale derived files - Add reference/error-code-map (en/zh) to the llms-full bundles in nav order; it was the only nav page missing from the full-text bundle. - gen_llms_full.py --check renders the bundles and AGENTS.txt in memory and exits 1 if the committed copies differ (header stamps ignored). - New check-derived-files.yml runs it on push/PR touching docs/, AGENTS.md, or the generator. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/check-derived-files.yml | 36 +++++++++++ AGENTS.md | 2 +- docs/AGENTS.txt | 2 +- docs/llms-full.en.txt | 72 ++++++++++++++++++++-- docs/llms-full.txt | 72 ++++++++++++++++++++-- docs/llms-full.zh.txt | 74 +++++++++++++++++++++-- docs/llms.txt | 2 +- docs/llms.zh.txt | 2 +- scripts/gen_llms_full.py | 46 ++++++++++++++ 9 files changed, 292 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/check-derived-files.yml diff --git a/.github/workflows/check-derived-files.yml b/.github/workflows/check-derived-files.yml new file mode 100644 index 0000000..3826b01 --- /dev/null +++ b/.github/workflows/check-derived-files.yml @@ -0,0 +1,36 @@ +name: Check derived files + +# Fails when docs/llms-full*.txt or docs/AGENTS.txt were not regenerated +# after a source change. Fix: run `python3 scripts/gen_llms_full.py` and commit. + +on: + push: + branches: + - main + paths: + - "docs/**" + - "AGENTS.md" + - "scripts/gen_llms_full.py" + - ".github/workflows/check-derived-files.yml" + pull_request: + paths: + - "docs/**" + - "AGENTS.md" + - "scripts/gen_llms_full.py" + - ".github/workflows/check-derived-files.yml" + workflow_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.11" + + - name: Check llms-full bundles and AGENTS.txt are up to date + run: python3 scripts/gen_llms_full.py --check diff --git a/AGENTS.md b/AGENTS.md index a37738b..dbc9c85 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,4 +47,4 @@ If you need to change runtime behavior (tool schemas, error codes, transaction l python3 scripts/gen_llms_full.py ``` -This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate, and rebuilds the published `docs/AGENTS.txt` from this file with site-absolute links. Run it after any change under `docs/` or to this file; do not edit `docs/AGENTS.txt` by hand. +This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate, and rebuilds the published `docs/AGENTS.txt` from this file with site-absolute links. Run it after any change under `docs/` or to this file; do not edit `docs/AGENTS.txt` by hand. CI (`check-derived-files.yml`) runs `python3 scripts/gen_llms_full.py --check` and fails if these files are stale. diff --git a/docs/AGENTS.txt b/docs/AGENTS.txt index 931e630..bb7c1b7 100644 --- a/docs/AGENTS.txt +++ b/docs/AGENTS.txt @@ -47,4 +47,4 @@ If you need to change runtime behavior (tool schemas, error codes, transaction l python3 scripts/gen_llms_full.py ``` -This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate, and rebuilds the published `docs/AGENTS.txt` from this file with site-absolute links. Run it after any change under `docs/` or to this file; do not edit `docs/AGENTS.txt` by hand. +This regenerates `docs/llms-full.txt` with a fresh commit SHA, timestamp, and token estimate, and rebuilds the published `docs/AGENTS.txt` from this file with site-absolute links. Run it after any change under `docs/` or to this file; do not edit `docs/AGENTS.txt` by hand. CI (`check-derived-files.yml`) runs `python3 scripts/gen_llms_full.py --check` and fails if these files are stale. diff --git a/docs/llms-full.en.txt b/docs/llms-full.en.txt index 5714e3c..efd705d 100644 --- a/docs/llms-full.en.txt +++ b/docs/llms-full.en.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-11-04T07:52:55Z -- Commit: 5af6e87d9ee1 +- Generated: 2026-11-04T08:51:09Z +- Commit: 7c37b1ce958c - Language: en -- Pages: 23 -- Token estimate: ~59,956 (chars / 4) +- Pages: 24 +- Token estimate: ~61,608 (chars / 4) --- @@ -5443,6 +5443,70 @@ Definitions of terms, standards, and identifiers used across this documentation. --- + + +# Error Code Map + +TronLink agents traverse three or four error-code dialects when a single user request crosses the DApp provider → DeepLink → MCP → CLI surfaces. This page is a single horizontal join keyed by **business meaning**; use it to translate a code from one dialect to its peers and to decide whether retrying is safe. + +> The per-surface tables linked in the column headers remain the SSOT. This page is a navigation aid — when in doubt, branch on the structured field of the surface you actually called (`error.code` for MCP Server TronLink; the `Error: ` text for MCP TronLink Signer; exit status + the stderr `error` string for CLI; the `code` field for `window.tron.request` (the rejection string for `tronWeb.trx.*` signing); the callback `code` for DeepLink). + +**Error shape:** On the TronLink-injected `tronWeb` (extension 4.0.0 and later), when the user rejects `trx.sign`, `trx.multiSign`, or `trx.signMessageV2`, the promise rejects with the **plain string** `'Confirmation declined by user'` — not an `Error` object, and without a numeric `code`. The `{ code: 4001, message: 'User rejected the request.' }` object is returned only by `window.tron.request(...)` methods such as `eth_requestAccounts`. Other failures (locked wallet, invalid payload, watch-only account) use other values — see [Handling rejections](#handling-rejections). Do not automatically retry signing. + +| Business meaning | DApp provider ([EIP-1474][provider]) | DeepLink ([5-digit][deeplink]) | MCP ([`TL_*`][mcp]) | CLI v1.0.1 ([exit status][cli]) | Retryable? | +| --- | :---: | :---: | :---: | :---: | :---: | +| **User rejected** the signing or connection prompt | `4001` from `window.tron.request(...)`; the string `'Confirmation declined by user'` from `tronWeb.trx.sign` / `multiSign` / `signMessageV2` | `300` (Transaction canceled) | — (HITL — re-prompt only on a fresh tool call) | `1` | **No** | +| **Invalid input** / malformed params | thrown by `tronWeb` builder | `10001`–`10020`, `10024`, `10025` | `TL_INVALID_INPUT` | `1` | **No** — fix the payload | +| **Method / capability not supported** | `4200` | `10003`, `10008`, `10009`, `10011`, `10023` | `TL_CAPABILITY_NOT_AVAILABLE` | — | **No** | +| **Wallet authorization mismatch** (initiator ≠ current wallet) | provider returns empty `accounts[]` | `10021`, `10022` | — | — | **No** — re-authorize | +| **No wallet / no session** | provider not injected (`window.tron` undefined) | `10016` | `TL_NO_ACTIVE_SESSION` | — | **No** — initialize / `tl_launch` first | +| **Rate-limited / wallet locked** | `-32000` (`eth_requestAccounts` within 20 s while locked) | — | — | — | **Yes** — wait and retry | +| **Network / RPC transient** (TronGrid, RPC error) | TronGrid HTTP error in `tronWeb` call | — | `TL_CHAIN_QUERY_FAILED`, `TL_GASFREE_QUERY_FAILED`, `TL_MULTISIG_QUERY_FAILED` | `1` | **Yes** | +| **On-chain execution failed** (post-broadcast: `REVERT`, `OUT_OF_ENERGY`, `FAILED`) | thrown by `sendRawTransaction` or surfaces via `getTransactionInfo` | — | `TL_CHAIN_SEND_FAILED`, `TL_CHAIN_SWAP_FAILED`, `TL_GASFREE_SEND_FAILED`, `TL_MULTISIG_SUBMIT_FAILED` | `1` | **No** — the tx is final; fix the root cause; never auto-retry writes | +| **Timeout** (user didn't sign in time, element not found) | call resolves slowly; no canonical code | — | `TL_WAIT_TIMEOUT`, `TL_NAVIGATION_FAILED` | `1` | **Maybe** — safe for reads; for writes that may have been broadcast, reconcile via `tronWeb.trx.getTransactionInfo` / `tl_chain_get_tx` before retrying | +| **Internal / unexpected** | `-32603` (Internal error) | — | `TL_INTERNAL_ERROR`, `TL_LAUNCH_FAILED` | — | **Yes once** — retry once then escalate with logs | + +[provider]: ../dapp/getting-started.md#request-authorization +[deeplink]: ../mobile/deeplink.md#result-code +[mcp]: ../ai-support/tronlink-mcp-core.md#error-codes +[cli]: ../ai-support/tronlink-cli.md#exit-codes + +## Handling rejections + +Besides the user-rejection values described above, other values a DApp can receive from the signing methods include `'User has not unlocked wallet'` (wallet locked, or the DApp was disconnected after authorization), `'Invalid transaction provided'` (invalid payload, or signing failed inside the wallet), `'Transaction integrity check failed'` (4.11.1 and later; the payload failed TronLink's integrity check, e.g. a non-string message — returned after the user closes TronLink's warning popup), and `{ code: 4100, message: 'Watch accounts cannot sign' }` (watch-only account; 4.10.0 and later). Treat anything you do not recognize as an unexpected error, not as a user rejection. + +```javascript +function isUserRejection(err) { + if (typeof err === 'string') return err === 'Confirmation declined by user'; + return err != null && err.code === 4001; +} + +try { + const signed = await window.tron.tronWeb.trx.sign(tx); +} catch (err) { + if (isUserRejection(err)) { + // user declined — do not retry automatically + } else { + // locked, invalid payload, watch-only account, or unexpected — inspect `err` + } +} +``` + +## How to use this map + +1. Receive an error from any surface, look up its row, and read across to find the corresponding code (or absence) on the other surfaces. +2. The **Retryable?** column is the agent-safety hint: + - **No** — auto-retry will fail or do harm. The most dangerous case is "On-chain execution failed", where the tx is already final on-chain. + - **Yes** — transient; back off (exponential, max 3 retries) and retry the original call. + - **Maybe** — read-only retry is OK; **never auto-retry writes** without first reconciling with on-chain state. +3. The DeepLink and CLI columns have many gaps because those surfaces only cover a slice of the lifecycle — DeepLink is mobile-only and lives on a separate trust boundary; CLI v1.0.1 exits with `1` for every failure class, so its column cannot distinguish them — read the string `error` on stderr instead (`—` means the CLI has no dedicated condition for it; any failure still exits `1`). For CLI write commands, an exit `1` is never safe to auto-retry, even in rows marked **Yes** — confirm on chain first. Use the most specific surface available. + +## Notes for downstream MCP servers + +Downstream MCP servers built on TronLink MCP Core (for example custom Skills) **must reuse** the `TL_*` codes from this map rather than minting new strings. If a new business meaning emerges, add a new row here and a new `TL_*` constant in `tronlink-mcp-core` (the SSOT) before shipping; do not invent codes in the consuming server. + +--- + # FAQ diff --git a/docs/llms-full.txt b/docs/llms-full.txt index 5714e3c..efd705d 100644 --- a/docs/llms-full.txt +++ b/docs/llms-full.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-11-04T07:52:55Z -- Commit: 5af6e87d9ee1 +- Generated: 2026-11-04T08:51:09Z +- Commit: 7c37b1ce958c - Language: en -- Pages: 23 -- Token estimate: ~59,956 (chars / 4) +- Pages: 24 +- Token estimate: ~61,608 (chars / 4) --- @@ -5443,6 +5443,70 @@ Definitions of terms, standards, and identifiers used across this documentation. --- + + +# Error Code Map + +TronLink agents traverse three or four error-code dialects when a single user request crosses the DApp provider → DeepLink → MCP → CLI surfaces. This page is a single horizontal join keyed by **business meaning**; use it to translate a code from one dialect to its peers and to decide whether retrying is safe. + +> The per-surface tables linked in the column headers remain the SSOT. This page is a navigation aid — when in doubt, branch on the structured field of the surface you actually called (`error.code` for MCP Server TronLink; the `Error: ` text for MCP TronLink Signer; exit status + the stderr `error` string for CLI; the `code` field for `window.tron.request` (the rejection string for `tronWeb.trx.*` signing); the callback `code` for DeepLink). + +**Error shape:** On the TronLink-injected `tronWeb` (extension 4.0.0 and later), when the user rejects `trx.sign`, `trx.multiSign`, or `trx.signMessageV2`, the promise rejects with the **plain string** `'Confirmation declined by user'` — not an `Error` object, and without a numeric `code`. The `{ code: 4001, message: 'User rejected the request.' }` object is returned only by `window.tron.request(...)` methods such as `eth_requestAccounts`. Other failures (locked wallet, invalid payload, watch-only account) use other values — see [Handling rejections](#handling-rejections). Do not automatically retry signing. + +| Business meaning | DApp provider ([EIP-1474][provider]) | DeepLink ([5-digit][deeplink]) | MCP ([`TL_*`][mcp]) | CLI v1.0.1 ([exit status][cli]) | Retryable? | +| --- | :---: | :---: | :---: | :---: | :---: | +| **User rejected** the signing or connection prompt | `4001` from `window.tron.request(...)`; the string `'Confirmation declined by user'` from `tronWeb.trx.sign` / `multiSign` / `signMessageV2` | `300` (Transaction canceled) | — (HITL — re-prompt only on a fresh tool call) | `1` | **No** | +| **Invalid input** / malformed params | thrown by `tronWeb` builder | `10001`–`10020`, `10024`, `10025` | `TL_INVALID_INPUT` | `1` | **No** — fix the payload | +| **Method / capability not supported** | `4200` | `10003`, `10008`, `10009`, `10011`, `10023` | `TL_CAPABILITY_NOT_AVAILABLE` | — | **No** | +| **Wallet authorization mismatch** (initiator ≠ current wallet) | provider returns empty `accounts[]` | `10021`, `10022` | — | — | **No** — re-authorize | +| **No wallet / no session** | provider not injected (`window.tron` undefined) | `10016` | `TL_NO_ACTIVE_SESSION` | — | **No** — initialize / `tl_launch` first | +| **Rate-limited / wallet locked** | `-32000` (`eth_requestAccounts` within 20 s while locked) | — | — | — | **Yes** — wait and retry | +| **Network / RPC transient** (TronGrid, RPC error) | TronGrid HTTP error in `tronWeb` call | — | `TL_CHAIN_QUERY_FAILED`, `TL_GASFREE_QUERY_FAILED`, `TL_MULTISIG_QUERY_FAILED` | `1` | **Yes** | +| **On-chain execution failed** (post-broadcast: `REVERT`, `OUT_OF_ENERGY`, `FAILED`) | thrown by `sendRawTransaction` or surfaces via `getTransactionInfo` | — | `TL_CHAIN_SEND_FAILED`, `TL_CHAIN_SWAP_FAILED`, `TL_GASFREE_SEND_FAILED`, `TL_MULTISIG_SUBMIT_FAILED` | `1` | **No** — the tx is final; fix the root cause; never auto-retry writes | +| **Timeout** (user didn't sign in time, element not found) | call resolves slowly; no canonical code | — | `TL_WAIT_TIMEOUT`, `TL_NAVIGATION_FAILED` | `1` | **Maybe** — safe for reads; for writes that may have been broadcast, reconcile via `tronWeb.trx.getTransactionInfo` / `tl_chain_get_tx` before retrying | +| **Internal / unexpected** | `-32603` (Internal error) | — | `TL_INTERNAL_ERROR`, `TL_LAUNCH_FAILED` | — | **Yes once** — retry once then escalate with logs | + +[provider]: ../dapp/getting-started.md#request-authorization +[deeplink]: ../mobile/deeplink.md#result-code +[mcp]: ../ai-support/tronlink-mcp-core.md#error-codes +[cli]: ../ai-support/tronlink-cli.md#exit-codes + +## Handling rejections + +Besides the user-rejection values described above, other values a DApp can receive from the signing methods include `'User has not unlocked wallet'` (wallet locked, or the DApp was disconnected after authorization), `'Invalid transaction provided'` (invalid payload, or signing failed inside the wallet), `'Transaction integrity check failed'` (4.11.1 and later; the payload failed TronLink's integrity check, e.g. a non-string message — returned after the user closes TronLink's warning popup), and `{ code: 4100, message: 'Watch accounts cannot sign' }` (watch-only account; 4.10.0 and later). Treat anything you do not recognize as an unexpected error, not as a user rejection. + +```javascript +function isUserRejection(err) { + if (typeof err === 'string') return err === 'Confirmation declined by user'; + return err != null && err.code === 4001; +} + +try { + const signed = await window.tron.tronWeb.trx.sign(tx); +} catch (err) { + if (isUserRejection(err)) { + // user declined — do not retry automatically + } else { + // locked, invalid payload, watch-only account, or unexpected — inspect `err` + } +} +``` + +## How to use this map + +1. Receive an error from any surface, look up its row, and read across to find the corresponding code (or absence) on the other surfaces. +2. The **Retryable?** column is the agent-safety hint: + - **No** — auto-retry will fail or do harm. The most dangerous case is "On-chain execution failed", where the tx is already final on-chain. + - **Yes** — transient; back off (exponential, max 3 retries) and retry the original call. + - **Maybe** — read-only retry is OK; **never auto-retry writes** without first reconciling with on-chain state. +3. The DeepLink and CLI columns have many gaps because those surfaces only cover a slice of the lifecycle — DeepLink is mobile-only and lives on a separate trust boundary; CLI v1.0.1 exits with `1` for every failure class, so its column cannot distinguish them — read the string `error` on stderr instead (`—` means the CLI has no dedicated condition for it; any failure still exits `1`). For CLI write commands, an exit `1` is never safe to auto-retry, even in rows marked **Yes** — confirm on chain first. Use the most specific surface available. + +## Notes for downstream MCP servers + +Downstream MCP servers built on TronLink MCP Core (for example custom Skills) **must reuse** the `TL_*` codes from this map rather than minting new strings. If a new business meaning emerges, add a new row here and a new `TL_*` constant in `tronlink-mcp-core` (the SSOT) before shipping; do not invent codes in the consuming server. + +--- + # FAQ diff --git a/docs/llms-full.zh.txt b/docs/llms-full.zh.txt index b43de31..7c5325f 100644 --- a/docs/llms-full.zh.txt +++ b/docs/llms-full.zh.txt @@ -2,11 +2,11 @@ > 中文文档全文拼接,适合 LLM 一次性 ingest。由 scripts/gen_llms_full.py 生成。索引见 ../llms.txt 的 Localized 段。 -- Generated: 2026-11-04T07:52:55Z -- Commit: 5af6e87d9ee1 +- Generated: 2026-11-04T08:51:09Z +- Commit: 7c37b1ce958c - Language: zh -- Pages: 23 -- Token estimate: ~41,384 (chars / 4) +- Pages: 24 +- Token estimate: ~42,408 (chars / 4) --- @@ -5342,6 +5342,72 @@ TRON 地址有两种可互转的编码: --- + + +# 错误码对照表 + +TronLink 智能体在一次用户请求里跨 DApp provider → DeepLink → MCP → CLI 时,会先后碰到三四套错误码方言。本页是以**业务含义**为主轴的横向对照,用来把任一方言里的错误码翻译到其他方言,并判断重试是否安全。 + +> 各列表头链接的"每个 surface 自己的错误表"仍然是 SSOT,本页只是导航工具——遇到歧义时,以**你实际调用的那个 surface 的结构化字段**为准(MCP Server TronLink 看 `error.code`;MCP TronLink Signer 看 `Error: ` 文本;CLI 看退出状态和 stderr 的 `error` 字符串;`window.tron.request` 看 `code` 字段(`tronWeb.trx.*` 签名看拒签字符串);DeepLink 看回调里的 `code`)。 + +**错误结构:** 在 TronLink 注入的 `tronWeb` 上(插件 4.0.0 起),用户拒绝 `trx.sign`、`trx.multiSign` 或 `trx.signMessageV2` 时,Promise 以**纯字符串** `'Confirmation declined by user'` reject——不是 `Error` 对象,也没有数字 `code`。`{ code: 4001, message: 'User rejected the request.' }` 对象只由 `window.tron.request(...)` 方法(如 `eth_requestAccounts`)返回。其他失败(钱包未解锁、载荷非法、观察钱包等)返回其他值——参见[处理拒签](#handling-rejections)。不要自动重试签名。 + +| 业务含义 | DApp provider([EIP-1474][provider]) | DeepLink([5 位码][deeplink]) | MCP([`TL_*`][mcp]) | CLI v1.0.1([退出状态][cli]) | 可重试? | +| --- | :---: | :---: | :---: | :---: | :---: | +| **用户拒绝**签名或连接弹窗 | `window.tron.request(...)` 为 `4001`;`tronWeb.trx.sign` / `multiSign` / `signMessageV2` 为字符串 `'Confirmation declined by user'` | `300`(交易取消) | —(HITL——只能在新的 tool 调用里再次唤起) | `1` | **否** | +| **参数非法** / payload 错 | `tronWeb` 构造器抛错 | `10001`–`10020`、`10024`、`10025` | `TL_INVALID_INPUT` | `1` | **否**——修参数 | +| **方法 / capability 不支持** | `4200` | `10003`、`10008`、`10009`、`10011`、`10023` | `TL_CAPABILITY_NOT_AVAILABLE` | — | **否** | +| **钱包授权不匹配**(发起地址 ≠ 当前钱包) | provider 返回空 `accounts[]` | `10021`、`10022` | — | — | **否**——重新授权 | +| **没有钱包 / 无会话** | provider 未注入(`window.tron` 不存在) | `10016` | `TL_NO_ACTIVE_SESSION` | — | **否**——先初始化 / `tl_launch` | +| **限流 / 钱包锁定** | `-32000`(20 秒内重复 `eth_requestAccounts` 且钱包锁定) | — | — | — | **是**——等一会儿再试 | +| **网络 / RPC 抖动**(TronGrid、RPC 错) | `tronWeb` 调用里的 TronGrid HTTP 错 | — | `TL_CHAIN_QUERY_FAILED`、`TL_GASFREE_QUERY_FAILED`、`TL_MULTISIG_QUERY_FAILED` | `1` | **是** | +| **链上执行失败**(广播后:`REVERT`、`OUT_OF_ENERGY`、`FAILED`) | `sendRawTransaction` 抛错或经 `getTransactionInfo` 暴露 | — | `TL_CHAIN_SEND_FAILED`、`TL_CHAIN_SWAP_FAILED`、`TL_GASFREE_SEND_FAILED`、`TL_MULTISIG_SUBMIT_FAILED` | `1` | **否**——交易已 final;查根因;**永远不要**自动重试写操作 | +| **超时**(用户没及时签 / 元素找不到) | 调用解析慢,无规范化的码 | — | `TL_WAIT_TIMEOUT`、`TL_NAVIGATION_FAILED` | `1` | **视情况**——读操作可以;**可能已被广播的写操作**先用 `tronWeb.trx.getTransactionInfo` / `tl_chain_get_tx` 对账后再决定 | +| **内部 / 未知** | `-32603`(Internal error) | — | `TL_INTERNAL_ERROR`、`TL_LAUNCH_FAILED` | — | **可重试一次**——再失败带 log 上报 | + +[provider]: ../dapp/getting-started.md +[deeplink]: ../mobile/deeplink.md +[mcp]: ../ai-support/tronlink-mcp-core.md +[cli]: ../ai-support/tronlink-cli.md + + + +## 处理拒签 + +除上文所述的用户拒绝值外,签名方法还可能返回:`'User has not unlocked wallet'`(钱包未解锁,或 DApp 授权后已断开连接)、`'Invalid transaction provided'`(载荷非法,或钱包内部签名失败)、`'Transaction integrity check failed'`(4.11.1 起;载荷未通过 TronLink 完整性校验,如非字符串消息——在用户关闭 TronLink 警告弹窗后返回)、`{ code: 4100, message: 'Watch accounts cannot sign' }`(观察钱包;4.10.0 起)。无法识别的值应按意外错误处理,不要当作用户拒绝。 + +```javascript +function isUserRejection(err) { + if (typeof err === 'string') return err === 'Confirmation declined by user'; + return err != null && err.code === 4001; +} + +try { + const signed = await window.tron.tronWeb.trx.sign(tx); +} catch (err) { + if (isUserRejection(err)) { + // 用户拒绝——不要自动重试 + } else { + // 未解锁、载荷非法、观察钱包或其他意外错误——检查 err + } +} +``` + +## 使用方式 + +1. 在任一 surface 收到错误后,在表里找到对应的业务含义行,横向读出其他 surface 的对应码(或空白)。 +2. **可重试?** 列是给智能体的安全提示: + - **否**——自动重试会失败甚至有害。最危险的是"链上执行失败",此时交易已上链,无法撤回。 + - **是**——临时性问题,退避(指数,最多 3 次)后重试原调用。 + - **视情况**——读操作可以重试;**写操作不要在没对账的情况下自动重试**。 +3. DeepLink 和 CLI 两列有很多空白,是因为这两个 surface 只覆盖了生命周期的一段——DeepLink 仅限移动端且跨信任边界;CLI v1.0.1 所有失败都退出 `1`,该列无法区分失败类别,请改读 stderr 中的 `error` 字符串(`—` 表示 CLI 没有对应的专门情况,任何失败仍退出 `1`)。CLI 写命令退出 `1` 时,即使该行标为**是**也不能自动重试——先在链上确认。**用得到哪个 surface 就以哪个 surface 为准**。 + +## 给下游 MCP 服务的约束 + +基于 TronLink MCP Core 的下游 MCP 服务(如自定义 Skills)**必须复用**本表里的 `TL_*` 码,不要自创新字符串。如果出现了新的业务含义,先在本页加行 + 在 `tronlink-mcp-core`(SSOT)加新的 `TL_*` 常量,再在消费端引用——**不要在消费端临时造码**。 + +--- + # 常见问题 diff --git a/docs/llms.txt b/docs/llms.txt index ad3262b..3a85008 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -2,7 +2,7 @@ > TronLink is a decentralized wallet for the TRON ecosystem, available as a browser extension and a mobile app. This documentation covers integrating DApps with TronLink across the browser extension, the mobile app (via DeepLink), and AI/agent tooling (MCP servers, CLI, signer SDK). -> Updated: 2026-11-04T07:52:55Z · Commit: 5af6e87d9ee1 +> Updated: 2026-11-04T08:51:09Z · Commit: 7c37b1ce958c How integration works: TronLink injects a `window.tron` provider into every page, exposing a `tronWeb` instance, a `request` method, and `on` / `removeListener` for events. A DApp detects the wallet via TIP-6963, requests authorization via `eth_requestAccounts` (TIP-1102), then builds, signs, and broadcasts transactions through `tronWeb`. Account/network changes arrive as passive `accountsChanged` / `chainChanged` events. diff --git a/docs/llms.zh.txt b/docs/llms.zh.txt index 76babf5..c9a89f1 100644 --- a/docs/llms.zh.txt +++ b/docs/llms.zh.txt @@ -2,7 +2,7 @@ > TronLink 是 TRON 生态的去中心化钱包,提供浏览器扩展和移动 App。本文档涵盖 DApp 通过浏览器扩展、移动端(DeepLink)以及 AI/智能体工具链(MCP 服务、CLI、签名 SDK)与 TronLink 集成。 -> Updated: 2026-11-04T07:52:55Z · Commit: 5af6e87d9ee1 +> Updated: 2026-11-04T08:51:09Z · Commit: 7c37b1ce958c 集成原理:TronLink 向页面注入 `window.tron` provider,暴露 `tronWeb` 实例、`request` 方法以及 `on` / `removeListener` 事件订阅。DApp 通过 TIP-6963 检测钱包,用 `eth_requestAccounts`(TIP-1102)请求授权,再经 `tronWeb` 构建、签名并广播交易。账户/网络变化以 `accountsChanged` / `chainChanged` 被动事件送达。 diff --git a/scripts/gen_llms_full.py b/scripts/gen_llms_full.py index 048c5b6..e5fb778 100644 --- a/scripts/gen_llms_full.py +++ b/scripts/gen_llms_full.py @@ -16,6 +16,11 @@ python3 scripts/gen_llms_full.py Generate the three bundles in docs/. + python3 scripts/gen_llms_full.py --check + Skip writing; exit 1 if any derived file (llms-full bundles, + AGENTS.txt) is stale relative to its sources. Header stamps + (timestamp, commit, token estimate) are ignored. Used in CI. + python3 scripts/gen_llms_full.py --verify https://docs.tronlink.org Skip generation; sample-check that the curated indexes' links return 200 on the live deployment. Used as a post-deploy CI gate. @@ -70,6 +75,7 @@ "dapp/stake2.en.md", "reference/networks.en.md", "reference/glossary.en.md", + "reference/error-code-map.en.md", "reference/faq.en.md", ] @@ -97,6 +103,7 @@ "dapp/stake2.zh.md", "reference/networks.zh.md", "reference/glossary.zh.md", + "reference/error-code-map.zh.md", "reference/faq.zh.md", ] @@ -356,6 +363,38 @@ def repl(m: re.Match) -> str: return out +# Header lines that change on every run; ignored by --check. +VOLATILE_HEADER_PREFIXES = ("- Generated: ", "- Commit: ", "- Token estimate: ") + + +def strip_volatile(text: str, header_lines: int = 12) -> str: + lines = text.splitlines() + head = [l for l in lines[:header_lines] if not l.startswith(VOLATILE_HEADER_PREFIXES)] + return "\n".join(head + lines[header_lines:]) + + +def check_derived() -> int: + """Return 1 if a committed derived file differs from a fresh render.""" + expected = { + "llms-full.en.txt": render_bundle(PAGES_EN, "en", "check", "check")[0], + "llms-full.zh.txt": render_bundle(PAGES_ZH, "zh", "check", "check")[0], + "AGENTS.txt": render_agents_txt(), + } + expected["llms-full.txt"] = expected["llms-full.en.txt"] + stale = [] + for name, text in expected.items(): + path = DOCS / name + actual = path.read_text(encoding="utf-8") if path.exists() else "" + if strip_volatile(actual) != strip_volatile(text): + stale.append(name) + if stale: + print("Stale derived files: " + ", ".join(f"docs/{n}" for n in stale), file=sys.stderr) + print("Run `python3 scripts/gen_llms_full.py` and commit the result.", file=sys.stderr) + return 1 + print(f"All {len(expected)} derived files are up to date") + return 0 + + def generate_bundles() -> None: sha = git_short_sha() generated_at = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ") @@ -404,6 +443,11 @@ def main() -> None: help="Skip generation; sample-check curated index links against this base URL " "(e.g. https://docs.tronlink.org).", ) + parser.add_argument( + "--check", + action="store_true", + help="Skip generation; exit 1 if llms-full bundles or AGENTS.txt are stale.", + ) parser.add_argument( "--sample-size", type=int, @@ -412,6 +456,8 @@ def main() -> None: ) args = parser.parse_args() + if args.check: + sys.exit(check_derived()) if args.verify: sys.exit(verify_live(args.verify, sample_size=args.sample_size)) generate_bundles() From 56f294d79923118a14b6c149bdb578db8f8f0f2f Mon Sep 17 00:00:00 2001 From: leon Date: Wed, 4 Nov 2026 16:53:55 +0800 Subject: [PATCH 4/5] docs: review fixes for multi-sig example and derived-file generator - Multi-sig example: guard toUtf8 against a missing res.message (it throws on undefined, which the empty catch would swallow). - gen_llms_full.py: fail when AGENTS.md links to a docs path that does not exist, instead of emitting a 404 URL; --check now also fails on pages missing from the bundle lists. Co-Authored-By: Claude Opus 5.5 --- docs/dapp/multi-sign-transfer.en.md | 2 +- docs/dapp/multi-sign-transfer.zh.md | 2 +- docs/llms-full.en.txt | 8 ++++---- docs/llms-full.txt | 8 ++++---- docs/llms-full.zh.txt | 8 ++++---- docs/llms.txt | 2 +- docs/llms.zh.txt | 2 +- scripts/gen_llms_full.py | 13 ++++++++----- 8 files changed, 24 insertions(+), 21 deletions(-) diff --git a/docs/dapp/multi-sign-transfer.en.md b/docs/dapp/multi-sign-transfer.en.md index 7628b6b..ceec34d 100644 --- a/docs/dapp/multi-sign-transfer.en.md +++ b/docs/dapp/multi-sign-transfer.en.md @@ -42,7 +42,7 @@ try { const res = await tronweb.trx.sendRawTransaction(signedTx); // Step 3 if (!res.result) { // Node rejections are returned, not thrown — see Errors below. - console.error(res.code, tronweb.toUtf8(res.message)); + console.error(res.code, res.message && tronweb.toUtf8(res.message)); } } catch (e) {} ``` diff --git a/docs/dapp/multi-sign-transfer.zh.md b/docs/dapp/multi-sign-transfer.zh.md index 8502030..7e20039 100644 --- a/docs/dapp/multi-sign-transfer.zh.md +++ b/docs/dapp/multi-sign-transfer.zh.md @@ -42,7 +42,7 @@ try { const res = await tronweb.trx.sendRawTransaction(signedTx); // 步骤3 if (!res.result) { // 节点拒绝以返回值给出,不会抛异常——见下方错误码。 - console.error(res.code, tronweb.toUtf8(res.message)); + console.error(res.code, res.message && tronweb.toUtf8(res.message)); } } catch (e) {} ``` diff --git a/docs/llms-full.en.txt b/docs/llms-full.en.txt index efd705d..0f1f2e9 100644 --- a/docs/llms-full.en.txt +++ b/docs/llms-full.en.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-11-04T08:51:09Z -- Commit: 7c37b1ce958c +- Generated: 2026-11-04T08:53:50Z +- Commit: 90b7e3d76d9d - Language: en - Pages: 24 -- Token estimate: ~61,608 (chars / 4) +- Token estimate: ~61,612 (chars / 4) --- @@ -5196,7 +5196,7 @@ try { const res = await tronweb.trx.sendRawTransaction(signedTx); // Step 3 if (!res.result) { // Node rejections are returned, not thrown — see Errors below. - console.error(res.code, tronweb.toUtf8(res.message)); + console.error(res.code, res.message && tronweb.toUtf8(res.message)); } } catch (e) {} ``` diff --git a/docs/llms-full.txt b/docs/llms-full.txt index efd705d..0f1f2e9 100644 --- a/docs/llms-full.txt +++ b/docs/llms-full.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-11-04T08:51:09Z -- Commit: 7c37b1ce958c +- Generated: 2026-11-04T08:53:50Z +- Commit: 90b7e3d76d9d - Language: en - Pages: 24 -- Token estimate: ~61,608 (chars / 4) +- Token estimate: ~61,612 (chars / 4) --- @@ -5196,7 +5196,7 @@ try { const res = await tronweb.trx.sendRawTransaction(signedTx); // Step 3 if (!res.result) { // Node rejections are returned, not thrown — see Errors below. - console.error(res.code, tronweb.toUtf8(res.message)); + console.error(res.code, res.message && tronweb.toUtf8(res.message)); } } catch (e) {} ``` diff --git a/docs/llms-full.zh.txt b/docs/llms-full.zh.txt index 7c5325f..e5c254b 100644 --- a/docs/llms-full.zh.txt +++ b/docs/llms-full.zh.txt @@ -2,11 +2,11 @@ > 中文文档全文拼接,适合 LLM 一次性 ingest。由 scripts/gen_llms_full.py 生成。索引见 ../llms.txt 的 Localized 段。 -- Generated: 2026-11-04T08:51:09Z -- Commit: 7c37b1ce958c +- Generated: 2026-11-04T08:53:50Z +- Commit: 90b7e3d76d9d - Language: zh - Pages: 24 -- Token estimate: ~42,408 (chars / 4) +- Token estimate: ~42,412 (chars / 4) --- @@ -5094,7 +5094,7 @@ try { const res = await tronweb.trx.sendRawTransaction(signedTx); // 步骤3 if (!res.result) { // 节点拒绝以返回值给出,不会抛异常——见下方错误码。 - console.error(res.code, tronweb.toUtf8(res.message)); + console.error(res.code, res.message && tronweb.toUtf8(res.message)); } } catch (e) {} ``` diff --git a/docs/llms.txt b/docs/llms.txt index 3a85008..e956951 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -2,7 +2,7 @@ > TronLink is a decentralized wallet for the TRON ecosystem, available as a browser extension and a mobile app. This documentation covers integrating DApps with TronLink across the browser extension, the mobile app (via DeepLink), and AI/agent tooling (MCP servers, CLI, signer SDK). -> Updated: 2026-11-04T08:51:09Z · Commit: 7c37b1ce958c +> Updated: 2026-11-04T08:53:50Z · Commit: 90b7e3d76d9d How integration works: TronLink injects a `window.tron` provider into every page, exposing a `tronWeb` instance, a `request` method, and `on` / `removeListener` for events. A DApp detects the wallet via TIP-6963, requests authorization via `eth_requestAccounts` (TIP-1102), then builds, signs, and broadcasts transactions through `tronWeb`. Account/network changes arrive as passive `accountsChanged` / `chainChanged` events. diff --git a/docs/llms.zh.txt b/docs/llms.zh.txt index c9a89f1..651bf93 100644 --- a/docs/llms.zh.txt +++ b/docs/llms.zh.txt @@ -2,7 +2,7 @@ > TronLink 是 TRON 生态的去中心化钱包,提供浏览器扩展和移动 App。本文档涵盖 DApp 通过浏览器扩展、移动端(DeepLink)以及 AI/智能体工具链(MCP 服务、CLI、签名 SDK)与 TronLink 集成。 -> Updated: 2026-11-04T08:51:09Z · Commit: 7c37b1ce958c +> Updated: 2026-11-04T08:53:50Z · Commit: 90b7e3d76d9d 集成原理:TronLink 向页面注入 `window.tron` provider,暴露 `tronWeb` 实例、`request` 方法以及 `on` / `removeListener` 事件订阅。DApp 通过 TIP-6963 检测钱包,用 `eth_requestAccounts`(TIP-1102)请求授权,再经 `tronWeb` 构建、签名并广播交易。账户/网络变化以 `accountsChanged` / `chainChanged` 被动事件送达。 diff --git a/scripts/gen_llms_full.py b/scripts/gen_llms_full.py index e5fb778..3c1a42f 100644 --- a/scripts/gen_llms_full.py +++ b/scripts/gen_llms_full.py @@ -333,6 +333,8 @@ def verify_live(base_url: str, sample_size: int = 5) -> int: def agents_link_url(href: str) -> str: """`docs/ai-support/ai-llms.en.md#x` -> `https://docs.tronlink.org/ai-support/ai-llms/#x`.""" path, _, frag = href[len("docs/"):].partition("#") + if not (DOCS / path).exists(): + raise SystemExit(f"AGENTS.md links to missing docs path: {href}") if path.endswith(".en.md"): path = path[: -len(".en.md")] + "/" path = AGENTS_DIR_TARGETS.get(path, path) @@ -375,11 +377,12 @@ def strip_volatile(text: str, header_lines: int = 12) -> str: def check_derived() -> int: """Return 1 if a committed derived file differs from a fresh render.""" - expected = { - "llms-full.en.txt": render_bundle(PAGES_EN, "en", "check", "check")[0], - "llms-full.zh.txt": render_bundle(PAGES_ZH, "zh", "check", "check")[0], - "AGENTS.txt": render_agents_txt(), - } + en, _, missing_en = render_bundle(PAGES_EN, "en", "check", "check") + zh, _, missing_zh = render_bundle(PAGES_ZH, "zh", "check", "check") + if missing_en or missing_zh: + print(f"Missing pages — en: {missing_en}; zh: {missing_zh}", file=sys.stderr) + return 1 + expected = {"llms-full.en.txt": en, "llms-full.zh.txt": zh, "AGENTS.txt": render_agents_txt()} expected["llms-full.txt"] = expected["llms-full.en.txt"] stale = [] for name, text in expected.items(): From 62317faac1a3de8947af44cadf70f64ada2580d2 Mon Sep 17 00:00:00 2001 From: leon Date: Wed, 4 Nov 2026 18:13:02 +0800 Subject: [PATCH 5/5] docs: simplify MCP schema parity note and fix zh mistranslation Co-Authored-By: Claude Opus 5.5 --- docs/ai-support/mcp-server-tronlink.en.md | 2 +- docs/ai-support/mcp-server-tronlink.zh.md | 2 +- docs/llms-full.en.txt | 8 ++++---- docs/llms-full.txt | 8 ++++---- docs/llms-full.zh.txt | 8 ++++---- docs/llms.txt | 2 +- docs/llms.zh.txt | 2 +- 7 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/ai-support/mcp-server-tronlink.en.md b/docs/ai-support/mcp-server-tronlink.en.md index e4f18bf..81eaab4 100644 --- a/docs/ai-support/mcp-server-tronlink.en.md +++ b/docs/ai-support/mcp-server-tronlink.en.md @@ -448,7 +448,7 @@ Pinned to the `package.json` of `mcp-server-tronlink@0.1.1`. Re-verify when bump These are **docs-side mirrors** of the most critical tool inputs — useful when an agent is writing a tool-call call site without an MCP session open. Runtime `list_tools` remains the authoritative source: the schemas there carry full Zod metadata (descriptions, `default`, etc.) plus `meta.schemaVersion`. Fields below are derived from `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts` and follow JSON Schema Draft 7. The full set of 52 tool schemas is **not** reproduced here — see core for the SSOT. -> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. +> Docs CI checks the field names and required flags of every block below against upstream `schemas.ts`; if they ever disagree, `list_tools` wins. #### `tl_chain_send` — **Remote Write** diff --git a/docs/ai-support/mcp-server-tronlink.zh.md b/docs/ai-support/mcp-server-tronlink.zh.md index 3d4e6f6..54eab39 100644 --- a/docs/ai-support/mcp-server-tronlink.zh.md +++ b/docs/ai-support/mcp-server-tronlink.zh.md @@ -442,7 +442,7 @@ mcp-server-tronlink/ 以下是最关键工具输入的**文档侧镜像**——当 agent 需要在没有打开 MCP 会话的情况下写工具调用站点时使用。运行时 `list_tools` 仍是权威源:那里有完整的 Zod 元信息(描述、`default` 等)以及 `meta.schemaVersion`。下方字段抄自 `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts`,遵循 JSON Schema Draft 7。**未**镜像全部 52 个工具——以 core 仓库为 SSOT。 -> **平价由 CI 强制。** `scripts/check_doc_schema_parity.py`(在 push、PR 及每日定时通过 [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml) 触发)会对下方每个块的顶层字段集 + required 标记与上游 `schemas.ts` 做 diff——上游改名或 required ↔ optional 漂移都会让 CI 失败。 +> 下方各块的字段名和 required 标记由文档 CI 与上游 `schemas.ts` 自动比对;如有不一致,以 `list_tools` 为准。 #### `tl_chain_send` —— **Remote Write** diff --git a/docs/llms-full.en.txt b/docs/llms-full.en.txt index 0f1f2e9..c93053b 100644 --- a/docs/llms-full.en.txt +++ b/docs/llms-full.en.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-11-04T08:53:50Z -- Commit: 90b7e3d76d9d +- Generated: 2026-11-04T10:12:58Z +- Commit: 56f294d79923 - Language: en - Pages: 24 -- Token estimate: ~61,612 (chars / 4) +- Token estimate: ~61,555 (chars / 4) --- @@ -2538,7 +2538,7 @@ Pinned to the `package.json` of `mcp-server-tronlink@0.1.1`. Re-verify when bump These are **docs-side mirrors** of the most critical tool inputs — useful when an agent is writing a tool-call call site without an MCP session open. Runtime `list_tools` remains the authoritative source: the schemas there carry full Zod metadata (descriptions, `default`, etc.) plus `meta.schemaVersion`. Fields below are derived from `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts` and follow JSON Schema Draft 7. The full set of 52 tool schemas is **not** reproduced here — see core for the SSOT. -> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. +> Docs CI checks the field names and required flags of every block below against upstream `schemas.ts`; if they ever disagree, `list_tools` wins. #### `tl_chain_send` — **Remote Write** diff --git a/docs/llms-full.txt b/docs/llms-full.txt index 0f1f2e9..c93053b 100644 --- a/docs/llms-full.txt +++ b/docs/llms-full.txt @@ -2,11 +2,11 @@ > Concatenation of all English documentation pages for single-fetch LLM ingestion. Generated by scripts/gen_llms_full.py. See ./llms.txt for the curated index. -- Generated: 2026-11-04T08:53:50Z -- Commit: 90b7e3d76d9d +- Generated: 2026-11-04T10:12:58Z +- Commit: 56f294d79923 - Language: en - Pages: 24 -- Token estimate: ~61,612 (chars / 4) +- Token estimate: ~61,555 (chars / 4) --- @@ -2538,7 +2538,7 @@ Pinned to the `package.json` of `mcp-server-tronlink@0.1.1`. Re-verify when bump These are **docs-side mirrors** of the most critical tool inputs — useful when an agent is writing a tool-call call site without an MCP session open. Runtime `list_tools` remains the authoritative source: the schemas there carry full Zod metadata (descriptions, `default`, etc.) plus `meta.schemaVersion`. Fields below are derived from `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts` and follow JSON Schema Draft 7. The full set of 52 tool schemas is **not** reproduced here — see core for the SSOT. -> **Parity is enforced.** `scripts/check_doc_schema_parity.py` (run on push, PR, and daily via [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml)) diffs the top-level field set + required-flag set of every block below against the live `schemas.ts`. Upstream rename or required→optional drift fails CI. +> Docs CI checks the field names and required flags of every block below against upstream `schemas.ts`; if they ever disagree, `list_tools` wins. #### `tl_chain_send` — **Remote Write** diff --git a/docs/llms-full.zh.txt b/docs/llms-full.zh.txt index e5c254b..a52d0df 100644 --- a/docs/llms-full.zh.txt +++ b/docs/llms-full.zh.txt @@ -2,11 +2,11 @@ > 中文文档全文拼接,适合 LLM 一次性 ingest。由 scripts/gen_llms_full.py 生成。索引见 ../llms.txt 的 Localized 段。 -- Generated: 2026-11-04T08:53:50Z -- Commit: 90b7e3d76d9d +- Generated: 2026-11-04T10:12:58Z +- Commit: 56f294d79923 - Language: zh - Pages: 24 -- Token estimate: ~42,412 (chars / 4) +- Token estimate: ~42,359 (chars / 4) --- @@ -2460,7 +2460,7 @@ mcp-server-tronlink/ 以下是最关键工具输入的**文档侧镜像**——当 agent 需要在没有打开 MCP 会话的情况下写工具调用站点时使用。运行时 `list_tools` 仍是权威源:那里有完整的 Zod 元信息(描述、`default` 等)以及 `meta.schemaVersion`。下方字段抄自 `@tronlink/tronlink-mcp-core` `src/mcp-server/schemas.ts`,遵循 JSON Schema Draft 7。**未**镜像全部 52 个工具——以 core 仓库为 SSOT。 -> **平价由 CI 强制。** `scripts/check_doc_schema_parity.py`(在 push、PR 及每日定时通过 [`check-doc-schema-parity.yml`](https://github.com/TronLink/docs/blob/main/.github/workflows/check-doc-schema-parity.yml) 触发)会对下方每个块的顶层字段集 + required 标记与上游 `schemas.ts` 做 diff——上游改名或 required ↔ optional 漂移都会让 CI 失败。 +> 下方各块的字段名和 required 标记由文档 CI 与上游 `schemas.ts` 自动比对;如有不一致,以 `list_tools` 为准。 #### `tl_chain_send` —— **Remote Write** diff --git a/docs/llms.txt b/docs/llms.txt index e956951..2ee39de 100644 --- a/docs/llms.txt +++ b/docs/llms.txt @@ -2,7 +2,7 @@ > TronLink is a decentralized wallet for the TRON ecosystem, available as a browser extension and a mobile app. This documentation covers integrating DApps with TronLink across the browser extension, the mobile app (via DeepLink), and AI/agent tooling (MCP servers, CLI, signer SDK). -> Updated: 2026-11-04T08:53:50Z · Commit: 90b7e3d76d9d +> Updated: 2026-11-04T10:12:58Z · Commit: 56f294d79923 How integration works: TronLink injects a `window.tron` provider into every page, exposing a `tronWeb` instance, a `request` method, and `on` / `removeListener` for events. A DApp detects the wallet via TIP-6963, requests authorization via `eth_requestAccounts` (TIP-1102), then builds, signs, and broadcasts transactions through `tronWeb`. Account/network changes arrive as passive `accountsChanged` / `chainChanged` events. diff --git a/docs/llms.zh.txt b/docs/llms.zh.txt index 651bf93..d211fa0 100644 --- a/docs/llms.zh.txt +++ b/docs/llms.zh.txt @@ -2,7 +2,7 @@ > TronLink 是 TRON 生态的去中心化钱包,提供浏览器扩展和移动 App。本文档涵盖 DApp 通过浏览器扩展、移动端(DeepLink)以及 AI/智能体工具链(MCP 服务、CLI、签名 SDK)与 TronLink 集成。 -> Updated: 2026-11-04T08:53:50Z · Commit: 90b7e3d76d9d +> Updated: 2026-11-04T10:12:58Z · Commit: 56f294d79923 集成原理:TronLink 向页面注入 `window.tron` provider,暴露 `tronWeb` 实例、`request` 方法以及 `on` / `removeListener` 事件订阅。DApp 通过 TIP-6963 检测钱包,用 `eth_requestAccounts`(TIP-1102)请求授权,再经 `tronWeb` 构建、签名并广播交易。账户/网络变化以 `accountsChanged` / `chainChanged` 被动事件送达。