Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ Both manage the same kind of wallet on the same networks — your address is ide
| **Command style** | PascalCase verbs: `RegisterWallet`, `SendCoin`, `GetBalance`. Amounts in **SUN** (1 TRX = 1,000,000 SUN). | Noun-verb subcommands: `create`, `tx send`, `account balance`, with `--flags`. |
| **Output for scripts** | Human-readable text. | Stable JSON via `-o json` ([`wallet-cli.result.v1`](ts/docs/machine-interface.md)) + fixed exit codes (`0`/`1`/`2`). |
| **Config / networks** | `config.conf` (net type + full node), or `SwitchNetwork` at runtime. Mainnet · Nile · Shasta · custom. | `--network` flag / `config` command. `tron:mainnet` · `tron:nile` · `tron:shasta`. |
| **Signing** | Software keystore · Ledger. | Encrypted local keystore · Ledger. Secrets never via argv/env. |
| **Signing** | Software keystore · Ledger. | Encrypted local keystore · Ledger. Secrets enter via stdin/TTY, never argv or dedicated secret env vars. |
| **Feature scope** | **The full surface** — wallets and transfers, staking, voting and rewards, governance, contracts, TRC10, and the on-chain exchange. | **The full surface** — HD wallets, TRX/TRC20/TRC10 transfers, staking & delegation, voting & rewards, governance proposals & super-representative operation, contract call/deploy/governance, TRC10 issuance, the on-chain Bancor exchange, multi-sig, GasFree transfers, message signing, and on-chain queries. |
| **Best for** | People at a terminal who want every TRON capability. | Scripting, CI pipelines, and AI agents. |
| **Full docs** | [java/README.md](java/README.md) | [ts/README.md](ts/README.md) |
Expand Down
4 changes: 2 additions & 2 deletions ts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ The agent-first implementation of wallet-cli, built for automation: every comman
## Key features

- **Agent-first** — stable JSON output, deterministic exit codes, and discoverable schemas, built for scripts, CI, and AI agents (details in [The contract, in one paragraph](#the-contract-in-one-paragraph)).
- **Encrypted local storage** — software keystores are encrypted on disk; secrets are never passed via argv or environment variables.
- **Encrypted local storage** — software keystores are encrypted on disk; secrets enter via stdin/TTY, never argv or dedicated secret environment variables.
- **Software and Ledger signing** — sign in software, or on a Ledger device (the private key never leaves the device).
- **Covers the full TRON feature surface** — HD wallets, TRX and TRC20/TRC10 transfers, staking / resource delegation, voting / rewards, governance proposals and super-representative operation, smart-contract calls, deployment and governance, TRC10 issuance, the on-chain Bancor exchange, multi-sig, GasFree transfers, message signing, and on-chain queries.

Expand Down Expand Up @@ -174,7 +174,7 @@ Offline local commands and configuration.

## The contract, in one paragraph

Every command supports `-o json` and then prints **exactly one** terminal JSON frame on stdout, schema [`wallet-cli.result.v1`](docs/machine-interface.md#the-result-envelope). Exit codes are fixed: `0` success, `1` execution failure, `2` usage error. Secrets (passwords, mnemonics, private keys) are never accepted via argv or environment variables — only via stdin flags or interactive TTY prompts; mnemonic/private-key import and `change-password` are interactive-only (no stdin path at all). Full spec: [machine-interface.md](docs/machine-interface.md); for calling from an AI agent, see the [Agent skill](skills/wallet-cli/SKILL.md).
Every command supports `-o json` and then prints **exactly one** terminal JSON frame on stdout, schema [`wallet-cli.result.v1`](docs/machine-interface.md#the-result-envelope). Exit codes are fixed: `0` success, `1` execution failure, `2` usage error. Secrets (passwords, mnemonics, private keys) are never accepted via argv and are not read from dedicated secret environment variables. Passwords can enter through stdin flags or interactive TTY prompts; mnemonic/private-key import and `change-password` are interactive-only (no stdin path at all). Full spec: [machine-interface.md](docs/machine-interface.md); for calling from an AI agent, see the [Agent skill](skills/wallet-cli/SKILL.md).

## Understanding TRON mechanics

Expand Down
2 changes: 1 addition & 1 deletion ts/docs/commands/tx/broadcast.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Broadcast a presigned transaction.

```
wallet-cli tx broadcast (--hex <hex> | --file <path> | --transaction <json> | --tx-stdin)
[--dry-run] --network <id> [options]
[--dry-run] [--network <id>] [options]
```

## Description
Expand Down
17 changes: 11 additions & 6 deletions ts/docs/commands/tx/send.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ a different id is refused outright), but a wrong value *inside* that range canno
locally — there is nothing to compare it against. When the exact base-unit quantity matters, pass
`--raw-amount`, which is used verbatim and never rescaled.

Early exits: `--dry-run` builds and estimates only — no signature, no broadcast, nothing leaves your machine; `--sign-only` signs and prints the signed transaction **hex**; `--build-only` builds but does **not** sign, printing the **unsigned** hex. The hex is protobuf on TRON and RLP (`0x02…`) on EVM; either feeds [`tx sign`](sign.md) and [`tx broadcast`](broadcast.md).
Early exits still build through the selected network first. `--dry-run` builds and estimates, then returns the plan with no signature and no broadcast; `--sign-only` builds, estimates, signs, and prints the signed transaction **hex** without broadcasting; `--build-only` builds and estimates but does **not** unlock or sign, printing the **unsigned** hex. The hex is protobuf on TRON and RLP (`0x02…`) on EVM; either feeds [`tx sign`](sign.md) and [`tx broadcast`](broadcast.md).

**Fees are family-specific.** TRON burns bandwidth/energy and caps the energy spend with `--fee-limit`; EVM pays gas, so `--gas-limit`, `--max-fee`, `--priority-fee` and `--nonce` apply instead. Help tags each set `(tron only)` / `(evm only)`, and using one on the other family is refused with `invalid_option` — as are `--max-fee` / `--priority-fee` on an EVM chain that still prices in `gasPrice`.

Expand All @@ -42,7 +42,12 @@ TRON multi-sig uses `--permission-id` to select the signing group and `--expirat

**By default the command returns at submission** (`stage: "submitted"`), not confirmation — add `--wait` to block until confirmed/failed, or poll [`tx status`](status.md).

Requires an account and the master password via `--password-stdin` — signing commands do not show an interactive prompt, so without it the command fails with `auth_required`.
Requires:

```text
the master password only when the selected mode signs — pass --password-stdin then; other modes need no password
an account — defaults to active; override with --account <accountId|label> (or run `wallet-cli use <account>` to change the active account)
```

## Options

Expand All @@ -53,9 +58,9 @@ Requires an account and the master password via `--password-stdin` — signing c
| `--raw-amount <string>` | Raw integer amount in native base units (SUN / wei) or token base units |
| `--token <string>` | Token symbol from the address book; excludes `--contract`, `--asset-id` |
| `--contract <string>` | Token contract address; omit for a native-coin transfer |
| `--dry-run` | Build and estimate only; excludes `--sign-only` / `--build-only` |
| `--sign-only` | Sign without broadcasting, output the signed hex; excludes `--dry-run` / `--build-only` |
| `--build-only` | Build only, output the **unsigned** hex; excludes `--dry-run` / `--sign-only` |
| `--dry-run` | Build and estimate through the selected network; no signing or broadcast; excludes `--sign-only` / `--build-only` |
| `--sign-only` | Build, estimate, sign, and output the signed hex without broadcasting; excludes `--dry-run` / `--build-only` |
| `--build-only` | Build and estimate, output the **unsigned** hex without unlocking; excludes `--dry-run` / `--sign-only` |
| `--wait` / `--wait-timeout <ms>` | Poll after broadcast until confirmed/failed (cap default 60000; on cap returns the submitted receipt) |
| `--password-stdin` | Master password from stdin |

Expand All @@ -81,7 +86,7 @@ Plus the [global options](../index.md#global-options-every-command).

## Examples

> **Password**: except for `--dry-run`, the examples below omit the password to keep the focus on the selector flags. A real send needs the master password on stdin — prefix with `printf '%s' "$PW" |` and append `--password-stdin` (see the description above).
> **Password**: the examples below omit the password to keep the focus on selector flags. Software signing modes need the master password on stdin — prefix with `printf '%s' "$PW" |` and append `--password-stdin`; `--dry-run`, `--build-only`, and Ledger signing do not.

```bash
# 1 TRX on Nile; 1 ETH-denominated amount on Sepolia
Expand Down
12 changes: 8 additions & 4 deletions ts/docs/commands/tx/status.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ Reports which step a transaction is at, using **four states**, on TRON and EVM n

| `data.state` | Meaning | Terminal? |
|---|---|---|
| `confirmed` | On chain — solidified on TRON, receipted on EVM; `blockNumber` present | yes |
| `confirmed` | Included in a block and an execution result/receipt is available; `blockNumber` present | yes |
| `failed` | Included and reverted / rejected | yes |
| `pending` | Seen by the node, not yet solidified | no — keep polling |
| `not_found` | Unknown to the queried node (wrong network? not propagated yet?) | no — poll within your own deadline |
| `pending` | Seen by the node, with no execution result/receipt yet | no — keep polling |
| `not_found` | Unknown to the queried endpoint (wrong network, not propagated, dropped, or pruned); outcome unknown | no — keep polling/reconcile; do not assume failure |

> `confirmed` is an inclusion-and-receipt state, not a finality guarantee. If a workflow needs finality, verify it separately with a TRON SolidityNode view or an EVM finalized block.

## Options

Expand Down Expand Up @@ -54,7 +56,7 @@ wallet-cli tx status --txid 0x55b0068ef31bce39bbf5b06d456eaef307fd77f96d85ea291f
{"schema":"wallet-cli.result.v1","success":true,"command":"tx.status","data":{"txid":"0x55b0068ef31bce39bbf5b06d456eaef307fd77f96d85ea291f48c1ae4b900d80","state":"confirmed","confirmed":true,"failed":false,"blockNumber":11576586,"confirmations":0},"meta":{"durationMs":408,"warnings":[]},"chain":{"family":"evm","network":"evm:11155111","chainId":"11155111"}}
```

An unknown txid is a **success** with `state: "not_found"` (exit 0) — the query worked; the answer is "not there":
An unknown txid is a **success** with `state: "not_found"` (exit 0) — the query worked; this endpoint has no record of that hash:

```json
{"schema":"wallet-cli.result.v1","success":true,"command":"tx.status","data":{"txid":"0000…0000","state":"not_found","confirmed":false,"failed":false},"meta":{"durationMs":1022,"warnings":[]},"chain":{"family":"tron","network":"tron:nile","chainId":"nile"}}
Expand All @@ -66,6 +68,8 @@ On EVM, `not_found` also carries a `meta.warnings` entry, because a public endpo
{"…":"…","data":{"txid":"0x0000…0000","state":"not_found","confirmed":false,"failed":false},"meta":{"durationMs":407,"warnings":["0x0000…0000 is unknown to this endpoint. Public nodes often prune history, so this may mean the node has no record of it rather than that it never existed; try an archival endpoint."]}}
```

> A polling deadline that ends in `pending` or `not_found` is still an unknown outcome. Do not treat it as failure or use it as an automatic resend trigger; reconcile the txid against the intended network and endpoint history first.

## Output

| Field | Type | Meaning |
Expand Down
4 changes: 2 additions & 2 deletions ts/docs/concepts/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ One seed covers **every chain family** — the same phrase re-derives your TRON

## Secrets in transit: stdin or TTY, never argv/env

Anything in a command's arguments or environment leaks into shell history, `ps` output, and CI logs. wallet-cli therefore refuses secrets there — they enter only via:
Anything in a command's arguments leaks into shell history and `ps` output. Exported environment variables are also easy to leak through shells and CI logs. wallet-cli therefore refuses passwords, mnemonics, and private keys in argv and does not read any dedicated secret environment variables for them — they enter only via:

- interactive TTY prompts, or
- explicit stdin flags: `--password-stdin`, `--tx-stdin` — **one `*-stdin` flag per run**, so a pipeline can never silently feed the wrong secret to the wrong prompt. The highest-value secrets go further: mnemonics and private keys are accepted **only** via hidden TTY input (`import mnemonic` / `import private-key` / `change-password` have no stdin path at all).
Expand Down Expand Up @@ -46,7 +46,7 @@ Unexpected internal exceptions are collapsed to a generic `internal_error` messa
| Software key | `create` / `import` | Convenient; host compromise = key compromise |
| Ledger | `import ledger` | Key never on host; every send confirmed on-device. `--app` fixes the account to one chain family — import once per app to cover both — see [Ledger guide](../guide/ledger.md) |
| Watch-only | `import watch` | No signing at all; safe for monitoring balances of cold storage. Bound to the pasted address's family |
| Split sign/broadcast | `--sign-only` + `tx broadcast` | Signing machine needs no network — see [Scripting](../guide/scripting.md#sign-here-broadcast-there) |
| Split sign/broadcast | `tx send --build-only` `tx sign --offline` → `tx broadcast` | Signing machine can stay offline; `--sign-only` still builds and estimates online — see [Scripting](../guide/scripting.md#sign-here-broadcast-there) |

## What wallet-cli cannot do for you

Expand Down
18 changes: 12 additions & 6 deletions ts/docs/guide/scripting.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ else
fi
```

**3. Secrets via stdin, never argv.** Passwords/mnemonics/keys in arguments would end up in shell history and `ps` output:
**3. Secrets via stdin, never argv.** Passwords/mnemonics/keys in arguments would end up in shell history and `ps` output. wallet-cli does not read dedicated secret environment variables either:

```bash
printf '%s' "$PW" | wallet-cli tx send --to T... --amount 1 \
--network tron:nile --password-stdin -o json
```

(`$PW` should come from your secret store, not from a file in the repo. Only one `*-stdin` flag per run.)
(`$PW` should come from your secret store as a short-lived shell variable for this pipe, not from a file in the repo and not from a long-lived `export`. Only one `*-stdin` flag per run.)

## Waiting for confirmation

Expand All @@ -57,18 +57,24 @@ Or decouple: capture `data.txId`, then poll [`tx status`](../commands/tx/status.

## Sign here, broadcast there

`--sign-only` and `tx broadcast` split signing from submission, so the machine holding keys never needs chain access:
`--sign-only` separates signing from broadcast, but it still builds and estimates through the selected RPC endpoint before signing. For a signing machine with no chain access, build unsigned hex online, sign that artifact offline, then broadcast from an online machine:

```bash
# on the signing machine
# on the connected build machine
wallet-cli tx send --to T... --amount 1 --network tron:nile \
--password-stdin --sign-only -o json | jq -r '.data.hex' > signed.hex
--build-only -o json | jq -r '.data.hex' > unsigned.hex

# on the offline signing machine
printf '%s' "$PW" | wallet-cli tx sign --file unsigned.hex --network tron:nile \
--offline --password-stdin --out signed.hex

# on the connected machine
wallet-cli tx broadcast --file signed.hex --network tron:nile -o json
```

The **hex** form above works on both chain families — protobuf on TRON, RLP on EVM. The JSON form is TRON-only:
The **hex** form above works on both chain families — protobuf on TRON, RLP on EVM. If the signing machine does have RPC access and you only want to withhold broadcast, `tx send --sign-only` emits signed hex directly.

TRON also accepts signed transaction JSON, but JSON must go through `--transaction` or `--tx-stdin`; `--file` and `--hex` are hex-only:

```bash
wallet-cli tx send ... --sign-only -o json | jq -c '.data.signed' > signed.json
Expand Down
Loading