Skip to content

Release v4.9.6#931

Open
gummy789j wants to merge 6 commits into
masterfrom
release_v4.9.6
Open

Release v4.9.6#931
gummy789j wants to merge 6 commits into
masterfrom
release_v4.9.6

Conversation

@gummy789j
Copy link
Copy Markdown
Collaborator

@gummy789j gummy789j commented May 13, 2026

Summary

This PR builds on standard CLI stdin credential input and adds:

  • Standard CLI Ledger signing support
  • Standard CLI address book / alias support
  • Hardening fixes for Ledger timeout state and alias persistence
  • Version bump to v4.9.6

Changes

Ledger support for standard CLI

  • Adds non-interactive Ledger signing for standard CLI wallet-authenticated commands.
  • Uses the selected Ledger keystore’s stored BIP44 path and address.
  • Requires normal keystore auth via MASTER_PASSWORD / --password-stdin.
  • Suppresses legacy Ledger stdout noise so JSON output remains machine-readable.
  • Emits structured ledger_* errors:
    • ledger_not_connected
    • ledger_app_not_open
    • ledger_sign_by_hash_disabled
    • ledger_unsupported_contract
    • ledger_already_signing
    • ledger_user_rejected
    • ledger_timeout
    • ledger_sign_failed
  • Adds Ledger timeout state tracking so stale signing state does not block later standard CLI commands.

Address book alias support

  • Adds per-network alias files under Wallet/aliases/<network>.json.
  • Adds built-in token aliases for supported networks.
  • Adds alias commands:
    • alias-add
    • alias-remove
    • alias-list
    • alias-resolve
  • Supports typed alias resolution:
    • account-position options resolve account aliases
    • contract/token-position options resolve token aliases
  • Adds JSON audit metadata for resolved aliases under meta.resolved.
  • Keeps raw Base58Check and hex TRON addresses working directly.

Hardening fixes

  • Prevents malformed user alias files from being treated as empty during mutating alias commands.
  • Rejects invalid token decimals outside 0..18.
  • Ensures Ledger quiet-mode singleton state is reset on production adapter exceptions.
  • Separates Ledger timeout from user rejection by adding explicit timeout state.

Docs and QA

  • Updates standard CLI contract spec.
  • Adds Ledger standard CLI user manual section.
  • Adds Ledger smoke QA doc.
  • Adds alias QA script.

Testing

Targeted tests passed:

./gradlew test --tests 'org.tron.walletcli.cli.aliases.*' \
  --tests org.tron.walletcli.cli.ledger.NonInteractiveLedgerSignerTest \
  --tests org.tron.walletcli.cli.StandardCliRunnerTest

* fix: ledger app-not-open detection and quiet-flag leak

- Split LedgerAddressUtil.getTronAddress into getRawAddressResponse +
  parseTronAddress so callers can inspect APDU status words before parsing
- Add LedgerPorts.AppNotOpenException for APDU 0x6511 (Tron app not open),
  distinct from a null return (device not found / address mismatch)
- NonInteractiveLedgerSigner catches AppNotOpenException and returns
  APP_NOT_OPEN outcome instead of NOT_CONNECTED
- ProductionLedgerPorts uses try-finally to unconditionally reset
  standardCliQuiet after executeSignListen returns, fixing permanent stdout
  suppression when device times out without a HID callback
- AliasResolutionException overrides fillInStackTrace as a no-op to avoid
  unnecessary stack capture on control-flow exceptions

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: correctly detect app-not-open when Ledger HID open() fails

On some OS/firmware combinations, HidDevice.open() returns false when
the Tron app is not running, causing getLedgerHidDevice() to return null
and the signer to report NOT_CONNECTED instead of APP_NOT_OPEN.

- Add HidServicesWrapper.hasAnyLedgerAttached() to distinguish "no device"
  from "device present but not openable"
- Throw AppNotOpenException in ProductionLedgerPorts when getHidDevice()
  returns null but a Ledger is physically attached
- Also check the return value of the second device.open() call (B2 path)
  which was previously ignored, causing the same misclassification
- Add test: returnsAppNotOpenWhenFinderThrowsAppNotOpenException

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix: zero password buffers in StdinPasswordReader and rename misleading APDU constant

- StdinPasswordReader.readAll wraps the read/parse in try-finally and
  Arrays.fill the chunk and bytes buffers before returning, matching the
  defensive pattern already used in StandardCliRunner.authenticate. The
  returned String still holds the password in its own char[], but the
  intermediate byte arrays no longer linger on the heap until GC.
- Rename APDU_APP_IS_OPEN to APDU_APP_NOT_OPEN. The Javadoc and the error
  message ("Open the Tron app on your Ledger device") already treat 0x6511
  as the "not open" signal; the identifier now matches.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Will <>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants