feat: ts v0.1.1#950
Conversation
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>
feat(ts): add vote and reward commands
…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>
matrix-agent116
left a comment
There was a problem hiding this comment.
Summary
This PR adds substantial TypeScript CLI functionality and a broad command-contract refactor. However, the new password-rotation path can leave the keystore partially migrated if a rename fails during the multi-file commit, so it is not safe to merge yet.
- Blocker: Make password rotation recoverable across the entire set of encrypted blobs and the verifier. The current sequential renames are only atomic per file; add rollback, journaling, or an equivalent recovery mechanism, plus a test that fails after at least one rename has succeeded.
- Suggestion: Validate
waitTimeoutMswhen loadingconfig.yaml, not only when it is written throughConfigService, so manually supplied invalid values cannot enter the effective configuration.
| for (const { tmp } of staged) { try { unlinkSync(tmp); } catch { /* best-effort */ } } | ||
| throw e; | ||
| } | ||
| for (const { tmp, path } of staged) renameSync(tmp, path); // atomic per file |
There was a problem hiding this comment.
[blocker] These sequential renames are atomic only per file. If a later renameSync fails, earlier keystore blobs have already been replaced while the remaining blobs—and possibly the verifier—still use the old password. changePassword then reports a rollback even though the vault may require two passwords or become unusable. Please make the commit recoverable across all files and add a test that injects a failure after one rename succeeds.
| } | ||
| if (raw.defaultOutput === "json" || raw.defaultOutput === "text") defaultOutput = raw.defaultOutput; | ||
| if (typeof raw.timeoutMs === "number") timeoutMs = raw.timeoutMs; | ||
| if (typeof raw.waitTimeoutMs === "number") waitTimeoutMs = raw.waitTimeoutMs; |
There was a problem hiding this comment.
[suggestion] Please apply the documented non-negative-integer validation here as well. A manually edited config.yaml currently accepts negative or fractional waitTimeoutMs values even though ConfigService rejects them, allowing an invalid effective configuration.
feat(ts): TypeScript Wallet CLI v0.1.1
Stake/chain queries, governance (vote/reward), a configurable confirmation
timeout, TTY-only secret entry, and a family-keyed command contract — layered
on top of
release_v4.9.8. User-facing command surface is additive; the onebreaking change is the command-id scheme (see below).
Highlights
New commands
vote cast | list | status— cast/replace your full SR vote allocation,list super representatives & candidates (with brokerage → reward-ratio), and
show current votes + voting power + reward overview.
reward balance | withdraw— claimable voting/block reward and 24hwithdraw-window status; withdraw accrued rewards.
chain params | prices | node— on-chain governance parameters,energy/bandwidth unit prices + memo fee, and connected-node sync status.
stake info | delegated— staked amounts, voting power, resource usage,unfreeze schedule; and V2 delegation records (both directions).
change-password— re-encrypt every software keystore under a new masterpassword (TTY-only, confirmed).
Faster, fresher reads (
--wait)TRON reads and transaction confirmation now hit the full node's unconfirmed
view instead of the solidified node. Confirmation resolves ~one block after
inclusion (~3s) rather than after solidification (~19 blocks / ~60s), and all
reads are fresh and mutually consistent.
Configurable confirmation cap
New config key
waitTimeoutMs(built-in 60000 ms) supplies the default--waitpolling cap;--wait-timeoutoverrides per-invocation.Secret policy: wallet secrets are TTY-only
import mnemonic/import private-key/change-passwordsecrets are enteredinteractively (hidden prompt) — the
--mnemonic-stdin/--private-key-stdinchannels were removed. Only
password,tx, andmessageremain stdin-backed.No secret ever sits in argv, env, or the process table.
Refactors (no behavior change)
ChainCommandDefinitionper logicalchain command: a service-free
ChainSpecplus afamily → FamilyBindingtable.
registerTronChainCommandsreplacesTronModule;commands/tron/*folded up into
commands/*.render/index.tssplit by command domain (wallet / account / tx / vote /reward / chain / misc). Golden suite byte-identical.
--forvia yargsarray: true(no preprocess/pipe patch).
Stable command id dropped the
tron.prefix: chain command ids are nowpath.join(".")(e.g.tx.send, nottron.tx.send). The family travels in theenvelope's
chain.family. The--json-schemacatalog is otherwise identicalmodulo this prefix removal.
Docs
ts/docs/typescript-wallet-cli-architecture-source-of-truth.mdupdated to match:command surface, command contract, ports/use-cases, capability list, full-node
read model, secret policy, config keys, and arity.
Verification
typecheck·depcruise·test·buildclean; golden suite passing.