Skip to content

Release v4.9.8#954

Merged
gummy789j merged 24 commits into
masterfrom
release_v4.9.8
Jul 16, 2026
Merged

Release v4.9.8#954
gummy789j merged 24 commits into
masterfrom
release_v4.9.8

Conversation

@gummy789j

Copy link
Copy Markdown
Collaborator

New Features

Change

  1. Upgrade the TypeScript implementation of wallet-cli to v0.1.1. This release adds vote and reward commands, on-chain stake and chain-parameter queries, a change-password flow with recoverable keystore password rotation, and a configurable transaction waitTimeoutMs for confirmation waiting. It also introduces a fail-fast watch-only guard on write operations, fsync-backed write durability (with backup-id conflict avoidance and correct rollback error propagation), fuller leaf-level help text, and a tree-style unstake listing. The CLI is refactored to a family-keyed command contract with a unified command id, and the render layer is split by command domain. (#950)

  2. Reorganize the repository and documentation into two clearly separated implementations. The Java (REPL-first) code, docs, QA suite, and Gradle build now live under java/, and the agent-first TypeScript CLI lives under ts/. The root README.md becomes a routing entry point, per-command reference docs and output examples are added, and a TypeScript wallet-cli agent skill (SKILL.md) plus docs are shipped inside the npm package. (#953, #950)

Bug Fixes

Change

  1. Bump jackson-databind from 2.16.1 to 2.18.8 to pick up upstream security and stability fixes. (#951)

gummy789j and others added 24 commits July 7, 2026 16:42
Addresses CVE-2026-54512/54513/54514/54515 (PolymorphicTypeValidator
bypass in jackson-databind). Fixed on the 2.x line in 2.18.8.

Kotlin stdlib (CVE-2026-53914) intentionally left at 1.9.10: it is a
build-time-only issue reached transitively via okhttp, and the patched
stable release (2.4.20) is not yet published (only 2.4.20-Beta1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
fix(deps): bump jackson-databind 2.16.1 -> 2.18.8
feat(docs): re-org README and documents for java and ts version
One ChainCommandDefinition per logical chain command: a neutral,
service-free ChainSpec (path, policy, baseFields, shared formatText)
plus a family->FamilyBinding table (run + delta fields/refine).
Registry assembles same-path bindings; shell dispatches by resolving
the network first, then the binding via net.family
(network_family_mismatch when absent), merging baseFields with the
binding's delta and composing base->family refines.

- command id = path.join(".") — drop the tron. prefix; the family
  travels in the envelope's chain.family
- help/catalog render one entry per chain command with families: [...]
  and a merged input schema
- registerTronChainCommands(registry, deps) replaces TronModule;
  commands/tron/* folded up into commands/*
- remove dead legacy paths: resolveCandidates/resolveForFamily/tree(),
  CommandDefinition.family, and the Networked/Networkless union —
  CommandDefinition is now neutral-and-networkless by type

User-facing surface is unchanged: --json-schema catalog is identical
modulo the tron. prefix removal; all describe()/summary strings are
byte-identical; golden suite 360 passed / 2 skipped; tsc clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pure moves, no output change (golden suite byte-identical):
  family.ts  — FAMILY_RENDER hook table + renderFamily
  wallet.ts  — wallet receipts + list tree view
  account.ts — account/token queries + history/portfolio rows
  tx.ts      — signing receipts + tx status/info
  misc.ts    — config/networks/contract/message/block
index.ts stays the barrel: reassembles TextFormatters (spread) and
keeps renderGenericText, so no importer changes. methodName moves to
scalars.ts (shared by tx receipts and contract call).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…s, vote/reward

Steven's v0.1.1 slice plus Leon's vote/reward (#949), rectified to repo conventions:
- config: waitTimeoutMs (configurable --wait-timeout default)
- gateway: TRON stake/chain read RPCs; reads + tx confirmation via the full node
  (fast --wait ~3s instead of ~60s solidity lag; fresh, consistent reads)
- stake: info / delegated queries + public votingPower()
- chain: params / prices / node
- change-password + import mnemonic/private-key: TTY-only secret entry (no --*-stdin)
- vote: cast / list / status ; reward: balance / withdraw
  (rectified: reuse stake.votingPower via injected TronStakeService, scope.warn instead
   of a __walletCliWarnings data side-channel, shared scalars.formatAtWithRelative,
   bounded/cached brokerage fan-out, pct & receipt-summary cleanups)
- arity: first-class array flags (--for) via yargs array:true — no preprocess/pipe patch
- render: preserve fractional TRX; chain untagged (generic, not TRON-exclusive)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add an optional multi-line `description` field to command specs so leaf help
(`<cmd> --help`) can carry the doc's user-value semantics (overwrite behavior,
TP math, per-call limits, warnings) instead of collapsing to the one-line
`summary` used in the parent group's listing. Populate it for vote/reward/
stake/chain/import/change-password commands, extend the group description for
vote, and render the stake-info unfreezing list as an aligned tree (├─/└─).
Add golden + formatter tests covering the new help copy and layout.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add SignerResolver.assertCanSign — a cheap capability gate (no RPC, no
keystore decrypt) that rejects watch-only accounts before any business
validation. Call it as the first line of every write entry (send, stake,
vote cast, reward withdraw, contract call/deploy) via a thin TxPipeline
delegate, so "watch-only can't sign" wins over rule errors like
insufficient_voting_power and even --dry-run is refused for watch accounts.

Also rename backup()'s error from watch_only_no_signer to not_exportable:
that branch covers watch and ledger accounts and is an export failure, not
a signing one.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…Ms on load

Address the two review comments on PR #950.

[blocker] change-password could leave the keystore half-migrated: writeJsonAll
staged all temps then renamed each into place, atomic per file only. A rename
failing mid-commit left some blobs (and possibly the verifier) on the new
password and others on the old, while changePassword still reported a clean
rollback. Make the commit recoverable — back up each existing target, install
the new blob, and on any failure restore every already-committed target from
its backup. If automatic restore itself fails, throw io_error("manual recovery
needed") and leave the backups on disk instead of falsely claiming rollback.
changePassword now lets that explicit error propagate unmasked.

[suggestion] ConfigLoader accepted negative/fractional waitTimeoutMs from a
hand-edited config.yaml even though ConfigService rejects them on write. Apply
the same non-negative-integer rule on load so the effective config stays valid.

Tests: fault-injection coverage for the mid-commit and failed-restore paths
(fs.test.ts) via a commitRename seam; waitTimeoutMs load-validation cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… errors

- writeJsonAll clean-rollback now fsyncs affected dirs before rethrowing,
  so a power loss right after rollback can't resurrect a half-committed state
- fsyncDir no longer swallows all errors: skip on Windows (can't open a dir
  handle), tolerate only POSIX not-applicable codes (EINVAL/ENOTSUP/
  EOPNOTSUPP/ENOSYS), and propagate real faults (EIO/ENOSPC/EACCES/EBADF)
- split raw syscall into overridable rawFsyncDir seam for fault injection
- add tests: rollback dir-fsync, real-error propagation, unsupported-code swallow

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Making fsyncDir propagate real errors exposed two paths where writeJsonAll
threw a bare error that changePassword then mislabeled as "rolled back":

- post-commit success path: the new blobs are already installed and readable,
  so a dir-fsync failure there is NOT a rollback. Throw a distinct io_error
  ("committed but durability unconfirmed; new state in effect") and retain the
  backups instead of cleaning them up, so callers stop reporting it as reverted.
- clean-rollback path: restores already succeeded, but their fsync failing let
  a bare error escape and masked the original write failure. Throw a precise
  io_error ("rolled back, durability of restore unconfirmed") preserving the
  original cause.

Both now surface as ExecutionError, which changePassword passes through
unmasked, so the error message always matches the real on-disk state.

Add tests for both paths.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s in npm package

Docs showed family-qualified command ids (tron.account.balance) but the
runtime emits the unprefixed logical id (account.balance); the family
travels only in the envelope's chain.family. Rewrote all 35 user-facing
reference/guide docs to match actual output. Historical superpowers specs
left untouched.

Also add docs/ and skills/ to package.json files[] so README-linked
reference pages and the agent skill actually ship (tarball 9 -> 93 files).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Follow-up to 0b410ed: the message namespace was not in the previous
replacement set, so tron.message.sign remained. Now unprefixed like the
rest.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
These two were the only non-interactive commands lacking a JSON output
example (change-password stays exampleless — it produces no structured
output by design). Shapes derived from the actual use-case returns:
block -> {block: <raw node block>} (large fields elided as … per the
tx.info convention); import.ledger -> the shared account descriptor with
type "ledger" and the device path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gummy789j
gummy789j merged commit 397c0b5 into master Jul 16, 2026
1 check passed
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.

3 participants