Add TRON Phase 3: USB HID Ledger signing + broadcast - #25
Merged
Conversation
Replaces the Phase-2 preview-only behavior on all `prepare_tron_*` tools with end-to-end signing via `@ledgerhq/hw-app-trx` over USB HID, since Ledger Live's WalletConnect relay does not honor the `tron:` namespace (verified 2026-04-14). Adds `pair_ledger_tron`, routes TRON handles through `send_transaction`, and broadcasts signed envelopes via TronGrid. Handles stay alive on sign/broadcast failure so users can retry without re-preparing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
szhygulin
force-pushed
the
feat/tron-phase3-signing
branch
from
April 14, 2026 07:57
663a81f to
0b36638
Compare
The `getSessionStatus after pairing` test's `vi.doMock` of walletconnect.js never applied: by the time this test ran, earlier tests had already resolved session.ts's transitive import of the real module, so the cached binding was used. Call vi.resetModules() before the doMock so the fresh session.ts import picks up the stub. Also ignore the two .mcpregistry_* token files that mcp-publisher drops into the working tree on `login`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds an optional `accountIndex` param (default 0) to pair_ledger_tron so users with multiple TRON accounts on a single Ledger can pair each one by its standard Ledger Live BIP-44 slot (m/44'/195'/<i>'/0/0). The single-slot cache is replaced with a per-path map; get_ledger_status' `tron` field becomes an array ordered by accountIndex. send_transaction for TRON now looks up the paired entry by `from` and signs on the matching path, so an account-1 tx is signed with the account-1 path instead of silently falling back to account 0 and failing the device address check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
@ledgerhq/hw-app-trxover USB HID. All sevenprepare_tron_*tools are no longer preview-only — their handles are now accepted bysend_transaction.pair_ledger_trontool probes the USB-connected Ledger, caches the address forget_ledger_status, and verifies the TRON app is open. Pair once per session.send_transactionroutes by handle store: TRON handles sign on USB and broadcast via TronGrid; EVM handles continue through WalletConnect unchanged. Handles stay alive on sign/broadcast failure so users can retry within the 15-min TTL.Why USB instead of WalletConnect
Ledger Live's WalletConnect relay does not honor the
tron:CAIP namespace (verified 2026-04-14). USB HID is the only path today — the user's Ledger must be plugged into the host running the MCP, unlocked, with the Tron app open. On Linux this needs Ledger's udev rules andlibudev-dev+ a C toolchain for thenode-hidnative compile; README calls both out.Implementation notes
.jsextensions under--moduleResolution bundler). Worked around with a thintron-usb-loader.tsusingcreateRequireto pull the CJS entries. Isolating therequire()also makes the signer trivially mockable in tests.finally— HID handles are exclusive, so holding one would blockledger-liveand other tooling.fromon every sign call; cached pairing is never trusted for authorization.tokenSignatures []passed tosignTransaction— USDT has hardcoded TRON-app support; other TRC-20 amounts may display as raw hex. Contract address + amount remain verifiable on-device.broadcastTronTxdecodes to UTF-8 before surfacing.Test plan
test/tron-phase3-signing.test.tscovering: happy-path sign, address-mismatch refusal, user-reject (0x6985), wrong-app (0x6511), no-device, malformed signature, broadcast happy path, hex-decoded error, plain-text error,send_transactionTRON routing with handle retirement, handle survives sign failure,pair_ledger_tronpopulates session status.tscclean.🤖 Generated with Claude Code