Feat/java remove standard cli - #991
Merged
Merged
Conversation
Execution blueprint for removing org.tron.walletcli.cli from the Java implementation, measured against the tree rather than restated from the requirements doc. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
…ckage Standard CLI removal prep. CommandErrorException lives in org.tron.walletcli.cli but leaks into the main sources in 127 places, including REPL-reachable methods (getUSDTBalance, gasFreeTransferInternal). Deleting the cli/ package with the type still inside would not compile. Move it verbatim to org.tron.core.exception, alongside the exceptions signTransactionForCli already throws (CancelException). Package move only: same class name, same semantics. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
BREAKING CHANGE: the only supported invocation is now a bare `java -jar wallet-cli.jar`, which starts the interactive shell. runMain() was a Standard CLI skeleton: GlobalOptions parsing, a JSON-enveloped --version, a --help backed by CommandRegistry, and a StandardCliRunner dispatch. Replace it with the four-case whitelist from the removal plan: no args -> interactive shell, exit 0 --version -> "wallet-cli vX.Y.Z" as plain text, exit 0 --help -> shell usage plus the migration hint, exit 0 anything else -> one-line migration hint on stderr, exit 2 --interactive goes away with it; it was never documented (java/README.md only ever showed the bare invocation) and only existed to escape from the non-interactive entry into the REPL. The hint is deliberately not a JSON envelope: emitting one would let scripts believe the contract is still there. Exit 2 matches the old usage-error code, so "non-zero means failure" keeps holding. Drops the four cli/ imports, the now-unused LinkedHashMap/Map imports, and shouldLaunchInteractiveByDefault / requestsJsonOutput / initRegistry. ClientMainTest is rewritten in the same commit so the test tree never spends a commit broken. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
…r.sign cli/ and the main sources depend on each other both ways: cli/ makes 55 *ForCli calls, while WalletApi and WalletApiWrapper name cli.ledger.LedgerSigner and cli.ledger.LedgerSignOutcome by fully-qualified name at their injection points. Deleting either side first fails to compile, and no reordering fixes that. Move the two types to org.tron.ledger.sign, which is neutral ground next to the Ledger package the interactive shell keeps. That cuts the main-sources -> cli/ edge, so the otherwise atomic removal can be split into a mechanical bulk delete and a surgical one. Both types are deleted again with the rest of the non-interactive Ledger adapter. Package move only, no behavior change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
…urces
BREAKING CHANGE: every non-interactive command is gone. Scripts and CI
should move to the TypeScript CLI, @tron-walletcli/wallet-cli.
The mechanical half of the removal, kept separate from the surgical half so
each can be reviewed on its own terms and a regression can be bisected to the
right side:
- src/main/java/org/tron/walletcli/cli/ (36 files)
- src/test/java/org/tron/walletcli/cli/ (19 test classes)
- src/test/java/org/tron/qa/ (QARunner, QASecretImporter)
- src/main/resources/aliases/{main,nile,shasta}.json
The alias feature goes with the package rather than surviving on its own: it
was reachable only through standard CLI commands (alias-add / alias-remove /
alias-list / alias-resolve), and the REPL never constructs an AliasResolver.
Users may delete the leftover Wallet/aliases/ and Wallet/.active-wallet
themselves; this release does not touch files under their wallet directory.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
The surgical half of the removal. Small diff, dense judgment; kept apart from the bulk delete so a regression bisects to the right side. *ForCli family: 65 names, 101 declarations across WalletApiWrapper (55), WalletApi (45) and ApiClient (1). Client.java referenced none of them; every caller lived in the deleted package. Symbols without the ForCli suffix that were standard-CLI-only all the same: the LAST_CLI_OPERATION_ERROR ThreadLocal and its four accessors (it existed to feed the JSON error envelope), the *OrThrow helpers, throwIfCliOperationFailed / throwCliError / validateCliWalletName, getGasFreeInfoData, gasFreeTraceData, getUSDTBalanceExact, extractTransactionReturnMessage, passwordValidQuiet, deleteFilesQuiet, GasFreeApi.getMessageOrThrow, CliWalletCreationResult, lastGasFreeId, the WalletApiWrapper.setWallet setter, and WalletCreationResult's mnemonicKeystoreName. The printMnemonicPath parameter was only ever false for the CLI, so it collapses to an unconditional print. gasFreeTransferInternal survives — the REPL reaches it through gasFreeTransfer — so its standardCli parameter is folded out branch by branch, including the IllegalStateException catch that named no such variable and was reachable only through getMessageOrThrow. The "GasFreeTransfer result:" line stays; it was guarded by if (!standardCli) and is now unconditional. Ledger: only the non-interactive adapter goes. WalletApi's injected signer field, signTransactionForCli, WalletApiWrapper.setLedgerSigner, the gasfree signing branch, and LedgerEventListener's standardCliQuiet / lastSendResult are removed; the quiet guards fold to always-print, which is what the REPL already saw. All 24 files of org.tron.ledger and every Ledger path in the interactive shell are untouched. Orphaned by the above and removed with it: WalletApi's instance triggerConstantContractExtention, estimateEnergyMessage and estimateEnergyMessageDirect. triggerConstantContractExtentionDirect stays — getUSDTBalance still calls it. Unrelated pre-existing dead code in WalletApi is left alone. Tests follow the same rule: src/main references decide, src/test does not. WalletApiWrapperTest loses seven cases, WalletApiTest one, and ClearWalletUtilsTest is deleted outright. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
qa/ only ever exercised the standard CLI. Every one of its 103 cases invoked `java -jar wallet-cli.jar --network <net> [--output json] <args>`; the "text vs json comparison" compared the standard CLI's two output modes against each other, never the REPL against anything. With the standard CLI gone the harness has no subject left. Removes qa/ (11 files), the qaJar and qaRun gradle tasks, and the four qa/ entries in .gitignore. The QARunner and QASecretImporter classes it drove went with the bulk delete. No CI job referenced any of this. The Java implementation is left without automated end-to-end coverage, which is where it already stood. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
BREAKING CHANGE: MASTER_PASSWORD is no longer read. Keystore passwords come from the terminal prompt only. Five loose ends the package deletion left behind: - The MASTER_PASSWORD channel. The standard CLI read the variable through its own path, but Utils.inputPassword — the shell's own prompt — carried a second reader for it behind a ThreadLocal switch that only tests ever flipped. It was dormant, not live, and a single call to the setter would have made it live again on the interactive path. The branch, resolveEnvPassword, set/isEnvPasswordInputEnabled and UtilsPasswordTest all go. - The wallet chooser. selcetWalletFile and its sibling listed Wallet/ without excluding subdirectories, so a leftover Wallet/aliases/ would appear as a numbered entry, count toward the total, and fail to parse when selected. Both filters now skip directories. This was already wrong for any subdirectory; the alias store just made it easy to hit. The .active-wallet filter stays — it is what keeps that file out of the list. - java/docs/standard-cli-contract-spec.md, which described a contract that no longer exists. - CLAUDE.md: the standard CLI examples, the two-modes section, the contract section, the request flow, the four cli/ key classes, the "adding a command" recipe and the two package rows. The QA section is replaced by a statement of what is actually true — there is no automated end-to-end coverage, and there was none before, since qa/ only ever drove the standard CLI. - VERSION -> v4.13.0, in step with the TypeScript package. Not a major bump, so a pinned build will not be held back by the version alone; the fallback hint and the release notes carry that weight instead. Release notes are added at java/docs/release-notes-v4.13.0.md. They state plainly that Ledger support in the interactive shell is untouched and that only non-interactive Ledger signing is removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
WalletApiWrapper's only @Setter was on the `wallet` field, removed with setWallet in ed35a6eb; the import stayed behind. Caught in review. WalletApi's unused java.net.URI and SignatureInterface imports are left alone — both were already dead at 3913909, so they are pre-existing, not orphans of this work. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
Round-2 review catch. TransactionUtils.PERMISSION_ID_OVERRIDE and its public set/clear pair existed so standard CLI handlers could supply --permission-id without a prompt. Every caller lived in the deleted package (StandardCliRunner:75 and 14 sites across the *Commands classes), so the mechanism is now unreachable from src/main. It is the same shape as the MASTER_PASSWORD channel D10 removed: dormant, not live, but one call to a public setter away from being live again — and here that setter suppresses the interactive shell's "Please confirm and input your permission id" confirmation on the multisig signing path (WalletApi:941, :3411), or cancels the transaction outright with no prompt at all. The §9.3 grep gates cannot see it; its name matches none of them. Removes the ThreadLocal, the override branch, the tipString == null early return (its only caller was the deleted signTransactionForCli), both public methods, and TransactionUtilsTest, whose single case exercised the null-tip path. Both surviving callers pass a non-null tip, so the prompt behaves exactly as before. No ThreadLocal now remains in src/main. Also collapses the blank-line runs that the deletions left behind in WalletApi, WalletApiWrapper, GasFreeApi and ApiClient, each back to the density it had at 3913909. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
Round-3 review catch. LedgerSignResult.upsertState, .getStateByTxid and HidServicesWrapper.hasAnyLedgerAttached had exactly one caller each at 3913909, all three in cli/ledger/ProductionLedgerPorts, so deleting the non-interactive adapter left them with none. These are orphans this work created, not pre-existing dead code, so CLAUDE.md's "remove what your change made unused" applies. §5.2 requires keeping all 24 files of org.tron.ledger and they are kept — the package still has 24 files and still ships 33 classes; the plan already scoped in-file cleanup inside that package when it folded LedgerEventListener's standardCliQuiet guards. Inert helpers, not switches: the REPL uses the siblings updateState, getLastTransactionState and appendLineIfNotExists, all untouched. No caller, no reflection, no cascade — readAllLines, writeAllLines, getHidServices and LEDGER_VENDOR_ID all remain live. LedgerSignResult's own pre-existing zero-caller methods (getFilePath, fileExists, writeAllLines, getLastTransaction) are left alone: they were already unused at 3913909. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxauSno5mhxX4DmBr39iso
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.
No description provided.