Visitar URL original
Releases · tronprotocol/wallet-cli · GitHub
Skip to content

Releases

wallet-cli-4.16.0

Choose a tag to compare

@gummy789j gummy789j released this 10 Nov 08:51
f631bf8

Notice

Non-mandatory upgrade

This release makes the TypeScript CLI safer for scripts and agents: commands now wait for
confirmation and finish within one time limit, and signing refuses payloads meant for another
network. Several options, error codes and JSON fields change, so check scripts that parse the
output before you upgrade. The Java REPL only carries the version bump, with no behavior change.

New Features

Change

  1. Commands wait for confirmation by default. A send, a broadcast or a GasFree transfer now returns when the transaction is confirmed or failed, not when it is submitted. Pass --no-wait to return right after submission. --wait-timeout and the waitTimeoutMs config key are removed, and the flag now fails with invalid_option. (#1046)

  2. One time limit for the whole command. --timeout <ms> (default 90 seconds, 0 for no limit) now covers the whole command, including Ledger approval and waiting for confirmation, but not your typing at a prompt. If time runs out after the transaction was accepted, the command still exits 0 with stage: "submitted", the txId and a warning. (#1046)

  3. Safer signing and credentials. Signing now refuses a transaction or typed data that names a different chain from the selected network (chain_id_mismatch), and every Ledger signature is checked against the account before it is used. TronLink, GasFree, B.AI and network API keys are set only with config <key> --api-key-stdin; passing them as arguments fails. (#1046)

  4. Clear signal when a transaction may have gone through. When a request may have acted although the command failed, the error carries error.details.outcome: "unknown" and the txId. Check it with tx status before sending again. Rebroadcasting a signed TRON transaction the node already holds returns alreadyKnown: true instead of an error. (#1046)

  5. sunswap swap: set the minimum you receive. --min-out <base-units> sets the floor directly instead of --slippage. If the route already quotes less, the command stops with slippage_exceeded before anything is approved, signed or sent. A route quoted at zero output is no longer offered. (#1046)

Bug Fixes

Change

  1. tx status reports TRON results correctly. A mined transaction whose receipt says DEFAULT is now confirmed instead of failed, and a transaction the node marks FAILED is failed. (#1046)

  2. Errors name the real cause. A wrong combination of options now fails with invalid_option instead of invalid_value. Malformed data from a node or a service fails with invalid_node_response or provider_error instead of showing zero or empty values, and HTTP 429 from any service is provider_rate_limited. (#1046)

  3. Failing transfers stop before they cost a fee. stake undelegate above the delegated amount fails with insufficient_stake, and a TRC20 or ERC20 tx send above the token balance fails with insufficient_token_balance. Both checks run before signing, in every mode including --dry-run. (#1046)

  4. Ambiguous token symbols stop before signing. If --token USDT matches no token or more than one token in the book, the command stops and lists the candidates. On EVM, --token together with --contract fails with invalid_option. (#1046)

  5. A blocked command says how to unblock it. When another wallet-cli process holds a lock, the error names the lock file and the process that holds it. If no wallet-cli command is running, delete the file. (#1046)

  6. Updated dependencies. TronWeb is updated to 6.5.1, which verifies the node's copy of a transaction before multi-signing and checks inputs from a single snapshot. Other dependencies with published advisories are updated as well. (#1046, #1049)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.15.1

Choose a tag to compare

@gummy789j gummy789j released this 23 Oct 07:52
7b52c6b

Notice

Non-mandatory upgrade

This release fixes interactive prompts in the TypeScript CLI, mainly on Windows, tightens how
x402 pay applies a raw payment limit, and requires a Node.js release that carries the October
2026 security fixes. The Java REPL only carries the version bump, with no behavior change.

Bug Fixes

Change

  1. Interactive prompts now work on Windows. You can now type passwords, recovery phrases and private keys at the terminal prompt on Windows. Before, commands such as import, change-password and delete failed with tty_required instead of asking. On Windows, a prompt needs the command to run directly in the console; in scripts, pipe the password with --password-stdin instead. (#1034)

  2. config baiApiKey --api-key-stdin reads from slow pipes. Piping the key from a tool that takes a moment to answer, such as a password manager CLI, no longer fails with "no data available on stdin". (#1034)

  3. Ctrl-C no longer hangs at a typed prompt. Pressing Ctrl-C at the delete confirmation, or when the CLI asks for a missing argument, now ends the command with exit code 130, as it already did at password prompts. (#1034)

  4. x402 pay --max-raw-amount now needs --token or --asset. A raw limit counts smallest units without naming a token, so a paid endpoint could ask for a different, more valuable token and still stay under it. The CLI now refuses a raw limit that is not pinned to a token, before anything is signed; scripts that pass --max-raw-amount alone fail with invalid_option until they add --token or --asset, or switch to --max-amount. After a payment, the result also shows which token and how much was paid (data.payment in JSON). (#1040)

  5. x402 roundtrip no longer fails on a busy machine. When signing took more than a few seconds, the paid request could fail with ECONNRESET and report an unknown payment status, although nothing had been paid. x402 serve now closes the connection after its payment challenge, so the paid request always starts on a fresh one, for x402 roundtrip and for any other payer. (#1042)

  6. The TypeScript CLI now needs Node.js 22.23.4, 24.22.1 or 26.12.1 or later. These releases fix the Node.js October 2026 security issues, including one in Brotli decompression that responses from RPC nodes and paid endpoints can reach. Node.js 20 is end-of-life and gets no fix. On an older Node.js, npm install prints an EBADENGINE warning, or fails with engine-strict, so upgrade Node.js first. (#1042)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.15.0

Choose a tag to compare

@gummy789j gummy789j released this 14 Oct 07:28
1bd2468

Notice

Non-mandatory upgrade

This release adds SunSwap and SunPump support to the TypeScript CLI. The Java REPL only carries
the version bump and a documentation correction, with no behavior change.

New Features

Change

  1. sunswap — trade and provide liquidity on SunSwap from the CLI. Swap tokens, add or remove liquidity on V2, V3 and V4 pools, and collect fees from your positions. You can also look up pools, positions, tokens and prices without a wallet. Every transaction can be previewed with --dry-run first, and any token approvals it needs are sent and confirmed for you before the trade. The swap and market queries run on mainnet; the liquidity commands also run on Nile. (#1025)

  2. sunpump — buy, sell and launch tokens on SunPump. Buy and sell tokens on their bonding curve, launch a new token, and browse or search the launchpad. --quote shows the price of a trade without an account or a transaction, and the platform fee is shown separately from the network fee. Once a token has launched, sunswap swap trades it instead. Available on mainnet. (#1025)

  3. Clearer network errors and price display. When a command is not available on the selected network, the error now tells you which networks support it. Very small USD prices are shown with their significant digits instead of 0.0000. Ledger users need Custom contracts and Sign by Hash enabled in the TRON app to use sunswap and sunpump. (#1025)

Bug Fixes

Change

  1. x402 pay now handles binary content correctly. Request bodies from --body-file are sent exactly as they are, instead of being altered when they are not plain text. A binary response, such as an image or a PDF, now requires --out to save it, instead of being printed as corrupted text. In addition, bai usage-summary no longer rounds large values. (#1029)

  2. A failed import no longer leaves files behind. When import rejected the label, it could still leave an encrypted key file in the wallet directory, or set a master password. The label is now checked before anything is saved. Error messages in text mode also no longer let a file name or label break the output across lines. (#1029)

  3. Ledger errors are clearer, and cancelling no longer hangs. Cancelling a Ledger operation or letting it time out now ends the command right away. When the device cannot be used, the error now tells you whether it is not connected, busy in another application such as Ledger Live, or disconnected during the operation. On TRON, broadcasting an expired transaction now reports tx_expired, so you know to rebuild and sign it again. (#1025)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.14.0

Choose a tag to compare

@gummy789j gummy789j released this 21 Sep 10:20
0790286

Notice

Non-mandatory upgrade

This release is TypeScript-only in substance: the Java REPL carries the version bump and
documentation touch-ups and no behavior change. If you are upgrading the TypeScript CLI from 4.13.0
or earlier, the legacy_derivation guidance in the
4.13.1 release note
still applies.

New Features

Change

  1. x402 — pay x402-protected HTTP endpoints from the wallet. A new command family lets an agent call an endpoint that answers 402 Payment Required, pick a payment route the endpoint offers on the selected network, sign the authorization with the active account and repeat the request with it; a facilitator settles on chain, so there is no --wait. x402 pay <url> takes the usual HTTP shape (--method, --header, --body / --body-file -) plus spend controls that are enforced before anything is signed: --max-amount / --max-raw-amount, --token / --asset, --scheme exact|exact_gasfree, and --max-gasfree-fee for a payment drawn from the account's GasFree balance instead of its token balance. --dry-run reports the route that would be paid; --out writes the paid response to a new file, refusing an existing one before the first request. x402 serve runs a local paywall (with --daemon for a background server), x402 roundtrip starts one, pays it once and exits, and provider-list / provider-show / endpoint-list / update-catalog browse a cached provider catalog. Every failure says whether money may have moved — error.details.phase, paymentStatus (not_sent / unknown / settled), retryPayment, candidateTxHash, and on TRON the one-time Permit2 approval that was signed — so a script never pays twice on a rumor; the SDK's own spend refusal surfaces as amount_exceeds_limit / no_matching_requirement at exit 1, and a rate-limited facilitator as provider_rate_limited with retryAfterSeconds. Permit2, EIP-3009 and GasFree deadlines are checked before and after the signer returns, and the TRON approve the bridge signs is pinned to approve(Permit2, MaxUint256) on the named token with zero call value, so a substituted transaction is refused before the device prompt. (#1002, #1007, #1008, #1010, #1011, #1013, #1021, #1022)

  2. bai — check and recharge a B.AI account with stablecoins. bai usage-summary, bai usage-records (cursor-paged: meta.pagination.hasMore / nextCursor, passed back with --cursor) and bai recharge-orders read the account; bai recharge <amount> [--token] [--to <email|address>] [--network tron|bsc|base] pays a recharge order with an x402 payment from the active account and reports the transaction to B.AI. The paying address must be bound to the B.AI account: recharge checks the binding on every run and, when it is missing, signs B.AI's binding message and binds it first, stopping with no order and no payment on any failure; --dry-run reports bindingRequired and what would be paid without binding, ordering or signing. When B.AI cannot confirm the credit in time the command still succeeds with creditStatus: "unconfirmed" and the transaction hash — the payment went through — and bai report-recharge <txHash> reports it again without paying. The personal API key is a new secret config key: config baiApiKey --api-key-stdin reads it from stdin only (config baiApiKey <key> on argv is invalid_option), saves it locally without contacting B.AI, and every bai command without one stops with bai_credentials_missing at exit 2; a wrong key is bai_auth_failed. (#1002, #1017, #1018, #1020)

  3. 8004 — read and manage ERC-8004 Agent identities. Eight commands work against the Identity Registry on tron, nile, shasta, bsc, bsc-testnet, base and base-sepolia (Ethereum and Sepolia fail with unsupported_network_capability): show and operator-check read without a wallet, and register <uri>, update, transfer, approve, add-operator and remove-operator sign with the active account under the usual transaction options (--wait, --sign-only, --build-only, and on TRON --fee-limit, --permission-id, --expiration). Agent ids may carry their canonical network (tron:3448148188:172, eip155:97:42) and are checked against the selected network with chain_id_mismatch. Authorization is decided during fee estimation, before signing: the registry's revert is decoded into not_authorized or agent_not_found, and any other revert is execution_reverted with error.details.revertData — TRON constant-call revert data, which TronWeb used to discard, is now preserved at the transport boundary for this. Receipts group the Agent fields under data.identity, with chain-read values (agentId, newURI, newOwner, approved) present only with --wait. (#1002, #1008)

  4. Machine-interface and packaging refinements around the new families. Long-running x402 and bai commands report progress on stderr — ⏳ … lines in text mode, one {"type":"activity"} line per step in JSON mode — which is informational and never carries the outcome. The config view now masks tronlinkSecretId and gasfreeApiKey as ******** alongside the secrets it already hid, and reading an unset key returns only key. delete on an HD wallet that has TRON sub-accounts always prints the legacy-derivation warning first, since without the password it cannot tell which path created them; the warning does not stop the deletion. The npm tarball now packages docs/troubleshooting/, so the recovery guide that five packaged documents link to ships with the package, and verify:package fails the build on any dangling in-package link. The --json-schema catalog, error-code index and every command page were re-synced for the new surface. (#1009, #1011, #1013, #1019, #1022)

Bug Fixes

Change

  1. Ledger on TRON: TIP-712 signatures were unverifiable, and large contract calls could not be signed at all. The TRON app's TIP-712 APDU returns the recovery byte as parity (00 / 01), and typed-data sign passed it through unchanged, so a contract ecrecover expecting 1b / 1c rejected every Ledger-signed typed-data message; the byte is now normalized to 27 / 28, while raw transaction signatures keep their unchanged wire format. Separately, hw-app-trx refuses to pack a transaction whose data field exceeds 250 bytes — a contract send with a long argument list failed with Too many bytes to encode. before any APDU was sent. The CLI now catches exactly that pre-transport error and falls back to signing the transaction's SHA-256 hash via signTransactionHash, after the same integrity checks as full signing, printing a warning that the device cannot display the details so the user must verify the transaction on the computer before approving. A device rejection, transport failure or cancelled operation is never retried as a hash. (#1015, #1016)

  2. A mined TRON contract call was reported as confirmed without an execution result. The confirmation normalizer only inspected the nested receipt.result: a top-level result: "FAILED" was ignored, a numeric receipt result was coerced away, and a receipt with no result at all defaulted to success, so a reverted call could come back as stage: confirmed. Both failure locations are now honored, and for contract call / deploy / TRC20 sends the poller keeps waiting until the receipt carries an execution result (native transfers and stakes, which legitimately omit it, are unchanged). In the same area, the pre-flight resource estimate for a payable call now passes --value through to energy estimation instead of estimating a zero-value call, and energyPriceSun reports the current price rather than the node's raw price-history string. (#1002, #1013, #1022)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.13.1

Choose a tag to compare

@gummy789j gummy789j released this 10 Sep 07:58
2df5863

Notice

Non-mandatory upgrade

If you created HD accounts at index 1 or above on 4.13.0 or earlier, read
Troubleshooting before upgrading — those TRON addresses need one export step
that must happen while the old wallet is still intact.

Troubleshooting

legacy_derivation — recovering TRON addresses derived before this release.

If a TRON account was derived at index 1 or above by 4.13.0 or earlier, it lives at
m/44'/195'/<index>'/0/0, a path this version no longer produces. Signing it, or deriving another
account into the same wallet, now fails with legacy_derivation (exit 1). The key is not lost —
the recovery phrase still derives it at that path — but this version's default import and derive
flow will not recreate the address, so it must be preserved before the wallet is rebuilt:

error [legacy_derivation]: account "main-1" was derived at m/44'/195'/1'/0/0, a TRON path this
version no longer produces, so it cannot be signed here. Follow the complete recovery procedure
before deleting anything:
  https://github.com/tronprotocol/wallet-cli/blob/wallet-cli-4.13.1/ts/docs/troubleshooting/legacy-derivation-recovery.md

The full procedure — save the account list and recovery phrase, export each affected TRON account
with backup --keystore and re-import it as a standalone account, then delete and re-import the
mnemonic wallet and re-derive every index — is documented in
Recover addresses after legacy_derivation.
Ethereum derivation did not change, so every EVM address is restored unchanged by the re-import;
only TRON at index 1 and above needs the export step. Do not delete the mnemonic wallet until
every TRON address you need appears as a standalone private-key account.
The whole procedure
reorganizes local keys only — it moves no funds on chain.

derivation_mismatch is a different failure and has no such rescue: it means the stored address
matches no derivation path of its seed, which an edited wallets.json or a wallet pointing at the
wrong vault would cause.

New Features

Change

  1. derive no longer demands a seed id. It now selects the HD wallet the way every other account command does: --account <accountId | label | address> names any account of the wallet, and with neither flag the active account decides. --seed-id wlt_… still works and takes precedence, so an existing script is unaffected, while wallet-cli derive on its own is now the common case. Selecting an account that belongs to a private-key, watch-only or Ledger wallet fails with seed_not_found at exit 2 and says which flag to reach for; --index names the address index in m/44'/<coin>'/0'/0/<index>, and re-running it on an index that already exists remains a no-op that re-activates the slot. (#1003)

  2. backup asks which format you want. In an interactive terminal, omitting --keystore now opens a two-line choice — Native wallet backup (the recovery phrase for the whole HD wallet) or Web3 keystore (the single private key for the selected network's family) — instead of silently taking the native path. The prompt appears only for a fully interactive invocation: passing --keystore, or piping the password in with --password-stdin, keeps the long-standing non-interactive default, so pipes and CI stay deterministic. A native backup of a seed wallet now also warns about any account this version's default mnemonic recovery would not recreate, naming each one with the exact backup --keystore command that preserves it. (#1003)

  3. derivationPath is now only ever reported by a command that actually opened the seed. list, current, use and rename need no master password, and without the seed they cannot tell an account derived under the old TRON template from one derived under the corrected one — so rather than print the current template as though it were an observed fact, they now return derivationPath: null for every account. A consumer that read derivationPath from those four commands must switch to a command that unlocks the seed: derive and backup resolve each cached address against its actual current or historical template before reporting, so their value is verified rather than assumed. ledger, watch and privateKey accounts return null as before. (#1003)

Bug Fixes

Change

  1. HD accounts on TRON were derived at a path no other TRON wallet scans. derive --index 1 produced its TRON key at m/44'/195'/1'/0/0, hanging the number at BIP44's account level, while TronLink, the Java wallet-cli and the wider TRON ecosystem all increment address_index. The address was real and the funds are safe, but restoring the same recovery phrase in any other wallet would not show it. TRON now derives at m/44'/195'/0'/0/<index>, the same shape EVM already used, so a derived account follows the default restore flow everywhere. Index 0 is identical under both templates and is unaffected; only index 1 and above were reachable at the old path. Accounts already sitting there are detected rather than overwritten: the stored address is resolved against both templates before any key is used, so signing such an account fails with the new legacy_derivation code (exit 1) pointing at the recovery guide instead of signing with a different key; deriving a further account into that wallet is refused for the same reason, because one wallet must never mix templates; the 4.13.0 → 4.13.1 wallet-file migration keeps a cached TRON address that the old template explains, rather than re-deriving over it; and backup --keystore deliberately still exports the old path's key, since that is the one command whose whole purpose is to let the key leave. A stored address that no template explains is a different failure with a different fix — wallets.json and the encrypted vault disagree — and now raises derivation_mismatch instead of being papered over. Both codes are published in --json-schema, and the complete ordered recovery procedure ships with the release. (#1003)

  2. import ledger --index did not mean what the device shows. The index was fed through the software derivation template, so on EVM it registered m/44'/60'/0'/0/<index> — an account Ledger Live does not display, leaving a user who picked "account 1" on their device with a different address than the one in front of them. Hardware paths are now built from Ledger Live's own template, m/44'/<coin>'/<index>'/0/0, for both families; TRON's path is unchanged, since that already was the template it used. --path remains the way to register any other scheme explicitly, --address scans Ledger Live accounts to find one, and the interactive account picker now prints each candidate's full path next to its address and says which template it is listing — so an account that lives on another scheme can no longer be silently mistaken for absent. (#1003)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.13.0

Choose a tag to compare

@gummy789j gummy789j released this 07 Sep 15:10
3960316

Notice

Non-mandatory upgrade

New Features

Change

  1. The TypeScript CLI now speaks EVM as well as TRON. A network belongs to one chain family, tron or evm, and that is what decides which commands and flags apply. Twenty-one commands are bound for evm — account balance / info / portfolio, block, chain node / prices, tx send / sign / broadcast / status / info, token balance / info / add / list / remove, contract call / send / deploy, and message sign / typed-data sign — against TRON's full surface, which keeps staking, permissions, proposals, TRC10, GasFree and TronLink multi-sig to itself. Four EVM networks ship built in (Ethereum, Sepolia, BNB Smart Chain and its testnet) alongside the three TRON ones. One seed produces a TRON address and a different EVM address, and a key-backed account serves both families; a watch-only or Ledger account holds one address and therefore one family, with --app tron|ethereum choosing which at import. Fees follow the chain: EIP-1559 gas estimation with --gas-limit / --nonce on EVM, bandwidth and energy on TRON. Calling a command on the wrong family fails with family_mismatch at exit 2 before any node call, using a flag from the other family is invalid_option, and --help tags every family-scoped row (TRON only) / (EVM only). contract deploy --artifact reads a Foundry / Hardhat / TronBox compiler artifact for both bytecode and ABI, so the same deploy command works on either family with the constructor's types coming from the compiler rather than from you. (#982, #984, #990)

  2. Canonical network ids are now CAIP-2, and persisted wallet data upgrades itself at startup. A network is identified by namespace:reference — tron:728126428, tron:3448148188, eip155:56 — the scheme WalletConnect, SIWE and the wider agent tooling already speak; the TRON references are the decimal genesis-hash prefix. Input is unaffected: tron:mainnet, tron:nile and tron:shasta remain permanent aliases, as do short spellings such as nile, sepolia and bsc. Output is a different matter — the envelope's chain.network, the networks listing's id and the config keys all now report the CAIP-2 id, so a consumer that string-matches or keys a map by tron:nile must be updated; an alias resolves once at selection and can never appear in a result. chainId goes with it, on both the envelope's chain object and the networks listing, because it keeps mirroring the id's second segment: TRON's readable mainnet / nile / shasta spellings become 728126428 / 3448148188 / 2494104990, the same decimal genesis-hash prefixes. One rule for both families beats a display string, and the alias column is where readability now lives. Because the rename would otherwise orphan stored data, every invocation — including --help, --version and --json-schema — checks the persisted wallet schema first and upgrades wallets.json and tokens.json before anything else runs. An upgrade asks for consent in a terminal, returns a single migration envelope at exit 0 with originalCommandExecuted: false, and deliberately does not run the command that triggered it, so nothing continues across an unexpected durable-state change; declining is a successful cancellation, and a non-interactive run that needs the master password returns migration_required at exit 2 unless it is piped in with --password-stdin. The commit re-reads each file under the lock, so a concurrent process's account cannot be erased by a stale snapshot. Each file's pre-upgrade copy rides inside the same transaction and is left beside it as wallets.json.v1.bak / tokens.json.v1.bak; nothing removes it later, so it is yours to keep as the rollback or to delete once you are satisfied — it holds the same wallet state as the file it shadows. Going back is a one-way trip in one respect: 4.13.0 leaves a file newer than itself alone and 4.12.0 never read the version field at all, so an older build still reads an upgraded wallets.json, but it scopes user-added tokens by the pre-CAIP-2 network id and would therefore list none of them. (#990, #994)

  3. The Java implementation is now the interactive shell and nothing else. The Standard CLI — its command registry, option parser, output formatter, alias book, non-interactive Ledger signer, and their tests and resources — is deleted, together with the qa/ harness that only ever drove it. The only supported invocation is a bare java -jar wallet-cli.jar, which opens the prompt; --version prints one plain-text line, --help prints the shell usage plus a pointer to the TypeScript CLI, and any other argument prints that one-line pointer on stderr and exits 2. The hint is deliberately not a JSON envelope, so a script cannot mistake it for the removed contract. Non-interactive, scriptable and CI use belongs to the TypeScript CLI, which reached feature parity in 4.12.0. In its place, java/qa-repl/ drives the real shell over a pty against a funded Nile account — wallet lifecycle, account queries, a signed transfer, and the not-logged-in guards — and the Gradle build version is now pinned to the version string the shell itself reports, with a test that fails a release build carrying -SNAPSHOT or drifted versioning. (#991, #990)

  4. The error-code index is published and machine-readable. wallet-cli --json-schema | jq '.errorCodes' returns one entry per code — {"rpc_error": {"exit": 1, "retry": "same", "meaning": "the node answered with an error"}} — so an agent no longer has to scrape prose to learn what a failure means. retry answers "now what": same (resend immediately), later (a lock-up or rate limit — back off first), changed (raise the fee, rebuild the nonce), never. Exit status is now derived from the error code itself rather than from the class that raised it, and a test holds every throw site to its code's declared exit, which settled four codes that had been thrown at both classes. Errors that name a choice rather than a dead end carry error.details.matches; ambiguous_account joins ambiguous_asset_name there, listing the candidate accounts when --account <address> does not resolve to a single interchangeable signer for the family being acted on. (#990, #994)

  5. Every chain HTTP call now goes through one transport, with per-network API keys and request pacing. The TRON and EVM clients share a single transport, and networks.<id>.apiKeyHeader / .apiKey are readable and writable through config: both must be set before a header is sent, the header name is validated as an RFC 9110 token so a hand-edited config.yaml cannot smuggle in a second one, apiKey is write-only on every read surface and forces the 0600 permission check, and a credentialed request refuses to follow redirects so a redirecting endpoint cannot collect the key. A key can also sit in the endpoint's own path, so a result no longer echoes the endpoint back in full: chain node reports its endpoint as the host alone, as does the one the networks listing now carries, and config networks.<id>.httpEndpoint stays the way to read the URL you configured. On top of it, requests to one endpoint are paced — a FIFO queue that starts them no closer together than 400ms — because TronGrid's anonymous tier admits about three requests per second on account-scoped endpoints and answers the rest with HTTP 429, identically whether they arrive concurrently or strictly sequentially. A wide fan-out such as account portfolio now runs clean instead of collecting rejections. Pacing is self-imposed, so the time a request waits is credited back to --timeout rather than charged against it; a request that loses its deadline while queued is dropped rather than sent, so an abandoned broadcast never reaches the node after the caller was told it timed out. (#990, #996)

Bug Fixes

Change

  1. An unreachable node was reported as a fact about the chain. tx status answered not_found at exit 0 when the endpoint simply could not be reached, and in the four-state model that string means "keep polling" — so a script waited forever on a node that was down. TRON's getTransactionInfoById resolves for an unknown hash and rejects only when the node failed, so its resolution is now the evidence that the node answered, after which "not found" is a fact about the transaction. block had the mirror-image defect: a height the node has no record of came back as {block: {}} at exit 0, leaving callers to guess what an empty object meant. A real block always carries blockID, so its absence is now not_found for a specific height, or invalid_node_response for latest — "the chain has no latest block" is not something a node can truthfully state. (#990)

  2. The wallet store could be taken down, or quietly lose a secret, by one unusual account. A wallets.json holding a source kind this build does not know took list down with a redacted internal_error, and the address scan walked every wallet, so a single unreadable account cost every other account its lookup — use, backup and delete by address all failed on a registry list could still show. delete was the costly one: it removed the wallet...

Read more

wallet-cli-4.12.0

Choose a tag to compare

@gummy789j gummy789j released this 19 Aug 06:43
0190dab

Notice

Non-mandatory upgrade

New Features

Change

  1. Chain governance and super-representative operation come to the TypeScript CLI. proposal list / show read chain-parameter proposals and are open to anyone, while proposal create / approve / delete require a registered witness; proposals are expressed in named chain parameters rather than raw numeric keys, and a created proposal's id is resolved from a snapshot taken before submission instead of guessed from the list afterwards. witness create / update / set-brokerage register and operate a super representative. Contract governance follows the same path: contract clear-abi, contract set-origin-energy-limit, contract set-user-resource-percent, and contract create2 for deterministic deployment addresses. Every write goes through the shared transaction pipeline, so --dry-run, --build-only, --sign-only, --permission-id, and multi-sig behave exactly as they do for transfers. (#972, #975)

  2. TRC10 issuance and the protocol-level Bancor exchange are now first-class commands. asset issue / update / participate / unfreeze / info / list cover the life of a TRC10 token (transfers continue to go through tx send), and exchange create / inject / withdraw / trade / show / list drive TRON's on-chain exchange. These reads are fetched and parsed losslessly, so an int64 total_supply or frozen_amount above 2^53 is reported exactly as a decimal string rather than rounded — sampling 1,400 mainnet assets found 252 above that bound. Reads are bound to the id asked for and to the protocol's precision range, and issuance still refuses a supply above 2^53 because java-tron cannot parse a numeric string into that field on the non-visible broadcast path. (#972, #975)

  3. Web3 keystore import and export, with an audit log for what left the machine. import keystore reads a standard Web3 v3 keystore file: the file is read and structurally validated before either password is asked for, so a mistyped path costs no typing, and both passwords — the file's own and the local master password — remain hidden-TTY-only. backup --keystore writes an account out in the same format, and backup --records lists the export audit log, which is preserved rather than overwritten when its contents cannot be read. The codec refuses a dklen below 32, which would leave the MAC's key slice empty and let any password appear to open the file, and compares the MAC as bytes so an uppercase-hex file is accepted instead of being reported as a wrong password. (#975)

  4. The TypeScript CLI now ships as a standalone executable, with no Node.js install required. npm run build:standalone compiles a single self-contained binary, and a GitHub Actions workflow builds and verifies one per platform — Linux x64/arm64, macOS x64/arm64, and Windows x64 — each built on its native runner so the embedded Ledger HID addon matches, checked against a glibc 2.35 baseline on Linux, and smoke-tested before publication. A companion CI workflow runs the architecture check, type-check, tests, and bundle build on every pull request. With this release the TypeScript CLI covers the same TRON feature surface as the Java REPL; the two now differ in how you drive them, not in what they can do. (#977)

Bug Fixes

Change

  1. A broadcast receipt quoted the node's transaction id instead of deriving its own. A TRON txID is the sha256 of the transaction body — derivable from the bytes that were signed, as --sign-only already did — but the broadcast path returned whatever the node echoed back. A dishonest node therefore chose which transaction --wait polled for and which id the receipt named, so a receipt could end up describing someone else's confirmed transaction. The derived id now wins across all three broadcast paths (the pipeline, tx broadcast --file, and the multi-sig relay); a disagreement is reported as a warning rather than an error, because the transaction has already been sent. (#975)

  2. Amounts in a --wait receipt lost precision above 2^53. /wallet/gettransactioninfobyid was still fetched through TronWeb's plain JSON.parse, so realized int64 quantities — unfreeze_amount, withdraw_amount, and the exchange amounts — were already rounded float64 values before the CLI saw them. This endpoint now follows the same lossless fetch and parse as getAccount, getBlock, listwitnesses, and listproposals. (#975)

  3. account activate --address accepted anything non-empty. The address was typed as a plain non-empty string rather than a TRON address, so a malformed value was only rejected once the node saw it. It is now validated locally, like every other address-taking command. Two documentation errors were corrected alongside it: contract deploy --build-only documented unsigned / unsignedHex while the command emits tx / hex, and the pagination inventory listed proposal show, which returns a single proposal, while omitting proposal list, which paginates. (#975)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.11.0

Choose a tag to compare

@gummy789j gummy789j released this 07 Aug 02:56
33a071b

Notice

Non-mandatory upgrade

New Features

Change

  1. Multi-sig is now a first-class workflow in the TypeScript CLI. permission show and permission update read and replace an account's permission structure on chain (the latter burns 100 TRX and warns before an owner lockout); every broadcast command gained --permission-id <n>, --expiration <ms>, and a new --build-only early-exit mode alongside --dry-run / --sign-only. tx sign now takes a transaction hex via --hex / --file, appends exactly one signature while preserving prior ones, and reports how far the accumulated weight is from the threshold — refusing before a key is ever decrypted if the account is not in the permission group (not_authorized) or has already approved (already_signed); --offline keeps the air-gapped path. tx approvals is the read-only companion that shows the permission group, threshold, accumulated weight, approved signers, and expiration without signing. (#963)

  2. tx multisig adds optional collaboration through the TronLink multi-sig service. Where the on-chain path passes a hex from person to person, the service holds the transaction, accumulates signatures, and pushes notifications: the default mode lists transactions awaiting this account, --create signs an unsigned hex and opens a collection at 1 / N, --sign <txId> co-signs a pending one, and --watch keeps a WebSocket open and reports only the count awaiting your signature (never transaction content). Once the threshold is reached the service broadcasts. Credentials (tronlinkSecretId / tronlinkSecretKey / tronlinkChannel) are set with config and are per-environment; without them the command fails with tronlink_credentials_missing. (#963)

  3. gasfree brings gas-less token transfers to the TypeScript CLI. gasfree info reports your GasFree address, activation status, nonce, and fee schedule; gasfree transfer signs an EIP-712 structured-data transfer and submits it to the GasFree provider, which puts it on chain and charges the fee in the transferred token itself, so no TRX is required; gasfree trace <traceId> follows the provider's WAITING → INPROGRESS → CONFIRMING → SUCCEED / FAILED states. Because submission goes to a provider rather than a node, the receipt carries a traceId instead of a txId — follow it with --wait or gasfree trace, not tx status. Credentials are gasfreeApiKey / gasfreeApiSecret via config. (#963)

  4. New account-lifecycle and local-utility commands. account activate creates a not-yet-existing address on chain without transferring any asset, with the payer covering the creation fee; account set writes the on-chain name or account id (permanent on mainnet, so it is deliberately one-at-a-time). A local contact book — contact add / list / remove, stored 0600 in the config directory — lets a saved name be used wherever a recipient is expected (tx send --to, gasfree transfer --to). encoding convert <input> auto-detects an input and prints every equivalent representation (TRON base58 / TRON hex / EVM / public key, or hex / Base64 / Base58Check), rejecting secrets outright. address generate produces a throwaway keypair offline, writing the private key to a 0600 file rather than the terminal unless --print-secret is passed. current --qr renders a scannable receive-address QR in text mode without unlocking or touching the network. (#963)

  5. The Java documentation was split out of java/README.md into a browsable java/docs/ tree. The README shrank from a single ~2,700-line page to an overview with quick links; commands now live under docs/commands/ by domain (wallet, account, transfers, staking, multisig, GasFree, DEX, proposals, contracts, …), with docs/concepts/, docs/guide/, and a field-by-field docs/reference/config.md. Stale planning and QA scratch documents were removed. No Java behavior changed in this release apart from the version constant. (#963)

Bug Fixes

Change

  1. A transaction the node rejected could be reported as submitted. TronWeb does not throw on rejection — it hands back the node's response verbatim, and a rejected /wallet/broadcasttransaction carries no result field at all, so the previous result === false check never fired and the CLI returned a success envelope with a txId for a transaction that was never accepted. Acceptance is now white-listed (result !== true is a rejection) on both the object and --hex broadcast paths, surfacing the node's reason as transaction_rejected. (#963)

  2. block lost precision on large int64 fields. Block responses were parsed through JavaScript numbers, so protobuf int64/uint64 values beyond Number.MAX_SAFE_INTEGER came back rounded. Blocks are now fetched and parsed losslessly, with out-of-range integers preserved as exact decimal strings. (#963)

  3. --dry-run reported doomed staking requests as fine. stake freeze and stake unfreeze are rejected by the node at broadcast time when the amount exceeds the available balance or the amount actually staked for that resource, but --dry-run never reaches the node — so a request that could not possibly succeed previewed cleanly. Both now pre-flight against the chain and fail with insufficient_balance / insufficient_stake. Relatedly, contract send now warns when the supplied --fee-limit is below the energy estimate at the current energy price, and the staked-amount computation was corrected for the node's habit of omitting the default BANDWIDTH enum in frozenV2. (#963)

  4. Chain-controlled text could repaint the terminal. Permission names, token names and symbols, and co-signer labels are written by whoever put them on chain. Terminal control bytes were already stripped, but bidirectional and zero-width formatting characters passed straight through — U+202E reverses the display order of everything after it, letting a crafted name change how the address or weight beside it appears, and zero-width characters can make two different names render identically. Text mode now escapes them visibly (<U+202E>) rather than dropping them, so legitimate right-to-left text still displays normally and tampering is obvious. JSON output is never rewritten. (#963)

  5. Filesystem failures surfaced as raw OS errors. backup and the atomic config/keystore writers let Node ErrnoExceptions escape, producing internal_error and, on a failed write, leaving a truncated or empty file at the destination. Failures are now typed as io_error with the partial artifact removed, and the multi-file atomic write reports a rolled-back failure distinctly from one that committed but could not confirm durability. Two new config-file conditions are also reported explicitly: invalid_config when config.yaml cannot be parsed (the parser detail is withheld, since it quotes the offending line and may carry a credential) and insecure_config when the file holds service credentials but is a symlink or group/world-readable. (#963)

  6. Positional arguments rejected number-shaped values. Yargs inferred a type for the anonymous positional tail, so a value such as 0xdeadbeef or 12345 arrived at its string-typed field as a number and was rejected. The tail is now typed as strings so the raw token survives parsing. As a consequence, a field exposed as a positional no longer also accepts its --<field> spelling — this affects the undocumented config --key/--value and block --number forms; the documented positional form is unchanged, and the global --account flag still works on use / rename / delete / backup. (#963)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.10.1

Choose a tag to compare

@gummy789j gummy789j released this 05 Aug 09:10
8f0d5c8

Notice

Non-mandatory upgrade

Bug Fixes

Change

  1. Update the postcss build dependency to 8.5.25 (and its transitive nanoid to 3.3.17) in the TypeScript CLI to clear GHSA-r28c-9q8g-f849. postcss is a development-only dependency of the ts/ package and is not shipped in the published bundle, so no runtime behavior changes for users; the bump keeps the build toolchain free of known advisories.

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification

wallet-cli-4.10.0

Choose a tag to compare

@gummy789j gummy789j released this 28 Jul 07:08
db60105

Notice

Non-mandatory upgrade

New Features

Change

  1. Add standalone signing commands to the TypeScript CLI: tx sign and typed-data sign. tx sign signs a transaction built elsewhere and prints the signed payload without broadcasting, so the signed result can be handed to tx broadcast later; because it appends to an existing signature array rather than replacing it, a partially signed transaction can be passed from signer to signer until a TRON multi-sig permission threshold is met. typed-data sign signs EIP-712 / TIP-712 structured data and returns the signature, the digest that was signed, and the resolved primary type; it accommodates real-world payloads by ignoring EIP712Domain in types, accepting value as an alias for message and accepting TRON base58 addresses in address fields, while rejecting a declared primaryType that is not the message root, since a nested type can never be what gets signed. Both commands are offline for software accounts (--network is optional) and both work with Ledger accounts. (#957)

  2. Enforce TRON transaction payload integrity before any signature is produced, in the software strategy and on Ledger alike. A TRON transaction states its content three times — raw_data (what a caller reads), raw_data_hex (what the node executes) and txID (the only thing actually signed) — and nothing in the format forces the three to agree, so a payload that displays a harmless raw_data can carry the hash and bytes of a different transaction. Signing now refuses (tx_integrity) unless txID is the sha256 of raw_data_hex, the contract types encoded in raw_data_hex match those raw_data declares, and raw_data re-encodes to exactly those bytes wherever the contract type can be encoded. The checks reject nothing a correct transaction builder produces. (#957)

  3. Make Ledger failures actionable rather than opaque. APDU statuses that previously surfaced as UNKNOWN_ERROR (0x6a8c) are now mapped to typed errors that name the fix: ledger_setting_required for the TRON app's "Sign by Hash", "Transactions data" and "Custom contracts" settings, and ledger_unsupported when the app version does not implement the instruction. Device signing also honours an abort signal, closing the transport immediately instead of holding the native handle until the timeout expires. (#957)

Bug Fixes

Change

  1. Fail closed on invalid global flag values in the TypeScript CLI. An out-of-range or non-matching value for a global flag (for example --timeout 0 or an unrecognized --output) silently fell back to the flag's default and the command ran under settings the caller never asked for. Such a value is now reported as invalid_value before any command dispatch, so no RPC is attempted. (#957)

  2. Reject operations that cannot succeed instead of returning misleading results. contract info on an address with no deployed contract returned a valid-but-empty contract normalized from TronWeb's empty response, and now fails as not found. stake withdraw with nothing withdrawable passed the node's broadcast-time checks but never confirmed, leaving a phantom txid; the withdrawable amount is now queried up front and the command fails with nothing_to_withdraw. (#957)

Integrity Check

All jar files available in this release are signed via this GPG key:

From the download listings below you should see links to the downloadable jar files as well as sig signature files. To verify the authenticity of any jar file, grab the jar and sig files with the same prefix name and then execute the verification process: GPG signature verification