Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
507df23
feat: add standard CLI mode with JSON output and harness verification
HarukaMa Apr 1, 2026
15d46d5
refactor: rename harness to qa, fix vote-witness test and CLI improve…
HarukaMa Apr 2, 2026
7baea04
fix: suppress stray output during full CLI lifecycle and remove unuse…
HarukaMa Apr 2, 2026
85ba50f
fix: ensure JSON mode produces strictly JSON-only stdout
HarukaMa Apr 2, 2026
5db7f2f
chore: add unit test hook to run after file edits
HarukaMa Apr 2, 2026
0201669
test: add comprehensive QA for list-wallet and set-active-wallet
HarukaMa Apr 2, 2026
f6461fe
feat: add active wallet management and implement transfer-usdt command
HarukaMa Apr 2, 2026
f995770
update setting
parsoncryptoai Apr 2, 2026
0365514
chore: simplify test hook command in settings
HarukaMa Apr 2, 2026
f56904d
chore: optimize Stop hooks with conditional test execution
HarukaMa Apr 2, 2026
006e4e8
fix: exclude .active-wallet from wallet listing and add success field…
HarukaMa Apr 3, 2026
7f3ac2d
fix: JSON envelope format, protobuf JSON output, and deploy-contract …
HarukaMa Apr 3, 2026
a9e666f
fix(qa): stabilize standard CLI flows and targeted QA reruns
gummy789j Apr 3, 2026
077b1cc
fix: skipped task
gummy789j Apr 6, 2026
71027c3
fix(cli): standardize JSON output envelope and QA checks
gummy789j Apr 8, 2026
d5eaf31
fix(wallet): clear sensitive buffers after private-key import
gummy789j Apr 8, 2026
cafebc0
fix(cli): tighten global option parsing and runner abort handling
gummy789j Apr 8, 2026
4d6d73e
fix: master passwrod strength validation & active wallet config stric…
gummy789j Apr 8, 2026
98ede09
fix(qa): tighten CLI review follow-ups and query verification flow
gummy789j Apr 8, 2026
b69c0b4
fix(cli,qa): close remaining review findings and retire stale QA paths
gummy789j Apr 9, 2026
ded1aaa
fix(cli): normalize contract/query json output and error handling
gummy789j Apr 9, 2026
a5403ba
fix(cli): tighten standard CLI output, auth, parsing, and QA checks
gummy789j Apr 9, 2026
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
22 changes: 22 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "if git diff --quiet HEAD -- 'src/' 'build.gradle' '*.java' 2>/dev/null; then echo 'No code changes, skipping tests.'; exit 0; fi && ./gradlew test 2>&1 || true",
"timeout": 300,
"statusMessage": "Running unit tests..."
},
{
"type": "command",
"command": "if git diff --quiet HEAD -- 'src/' 'build.gradle' '*.java' 2>/dev/null; then echo 'No code changes, skipping QA.'; exit 0; fi && ./qa/run.sh verify",
"timeout": 600,
"statusMessage": "Running full QA verification..."
}
]
}
]
}
}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.claude/settings.local.json
.DS_Store
build
out
Expand All @@ -11,4 +12,15 @@ src/gen
tools
src/main/resources/static/js/tronjs/tron-protoc.js
logs
docs
FileTest

# Wallet keystore files created at runtime
Wallet/
Mnemonic/
wallet_data/

# QA runtime output
qa/results/
qa/report.txt

114 changes: 114 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Build & Run

```bash
# Build the project (generates protobuf sources into src/main/gen/)
./gradlew build

# Build fat JAR (output: build/libs/wallet-cli.jar)
./gradlew shadowJar

# Run in REPL 交互模式 (human-friendly, interactive prompts)
./gradlew run
# Or after building: java -jar build/libs/wallet-cli.jar

# Run in standard CLI mode (non-interactive, scriptable)
java -jar build/libs/wallet-cli.jar --network nile get-account --address TXyz...
java -jar build/libs/wallet-cli.jar --output json --network nile get-account --address TXyz...

# Run tests
./gradlew test

# Run a single test class
./gradlew test --tests "org.tron.keystore.StringUtilsTest"

# Clean (also removes src/main/gen/)
./gradlew clean
```

Java 8 source/target compatibility. Protobuf sources are in `src/main/protos/` and generate into `src/main/gen/` — this directory is git-tracked but rebuilt on `clean`.

## QA Verification

The `qa/` directory contains shell-based parity tests that compare interactive REPL output vs standard CLI (text and JSON modes). Requires a funded Nile testnet account.

```bash
# Run QA verification (needs TRON_TEST_APIKEY env var for private key)
TRON_TEST_APIKEY=<nile-private-key> bash qa/run.sh verify

# QA config is in qa/config.sh; test commands are in qa/commands/*.sh
# MASTER_PASSWORD env var is used for keystore auto-login (default: testpassword123A)
```

## Architecture

This is a **TRON blockchain CLI wallet** built on the [Trident SDK](https://github.com/tronprotocol/trident). It communicates with TRON nodes via gRPC.

### Two CLI Modes

1. **REPL 交互模式** (human-friendly) — `Client` class with JCommander `@Parameters` inner classes. Entry point: `org.tron.walletcli.Client`. Features tab completion, interactive prompts, and conversational output. This is the largest file (~4700 lines). Best for manual exploration and day-to-day wallet management by humans.
2. **Standard CLI 模式** (AI-agent-friendly) — `StandardCliRunner` with `CommandRegistry`/`CommandDefinition` pattern in `org.tron.walletcli.cli.*`. Supports `--output json`, `--network`, `--quiet` flags. Commands are registered in `cli/commands/` classes (e.g., `WalletCommands`, `TransactionCommands`, `QueryCommands`). Designed for automation: deterministic exit codes, structured JSON output, no interactive prompts, and env-var-based authentication — ideal for AI agents, scripts, and CI/CD pipelines.

The standard CLI suppresses all stray stdout/stderr in JSON mode to ensure machine-parseable output. Authentication is automatic via `MASTER_PASSWORD` env var + keystore files in `Wallet/`.

### Request Flow

```
# Standard CLI mode:
User Input → GlobalOptions → StandardCliRunner → CommandRegistry → CommandHandler → WalletApiWrapper → WalletApi → Trident SDK → gRPC → TRON Node

# Interactive REPL mode:
User Input → Client (JCommander) → WalletApiWrapper → WalletApi → Trident SDK → gRPC → TRON Node
```

### Key Classes

- **`org.tron.walletcli.Client`** — Legacy REPL entry point and CLI command dispatcher. Each command is a JCommander `@Parameters` inner class.
- **`org.tron.walletcli.cli.StandardCliRunner`** — New standard CLI executor. Handles network init, auto-authentication, JSON stream suppression, and command dispatch.
- **`org.tron.walletcli.cli.CommandRegistry`** — Maps command names/aliases to `CommandDefinition` instances. Supports fuzzy suggestion on typos.
- **`org.tron.walletcli.cli.CommandDefinition`** — Immutable command metadata (name, aliases, options, handler). Built via fluent `Builder` API.
- **`org.tron.walletcli.cli.OutputFormatter`** — Formats output as text or JSON. In JSON mode, wraps results in `{"success":true,"data":...}` envelope.
- **`org.tron.walletcli.WalletApiWrapper`** — Orchestration layer between CLI and core wallet logic. Handles transaction construction, signing, and broadcasting.
- **`org.tron.walletserver.WalletApi`** — Core wallet operations: account management, transaction creation, proposals, asset operations. Delegates gRPC calls to Trident.
- **`org.tron.walletcli.ApiClientFactory`** — Creates gRPC client instances for different networks (mainnet, Nile testnet, Shasta testnet, custom).

### Adding a New Standard CLI Command

1. Create or extend a class in `cli/commands/` (e.g., `TransactionCommands.java`)
2. Build a `CommandDefinition` via `CommandDefinition.builder()` with name, aliases, options, and handler
3. Register it in the appropriate `register(CommandRegistry)` method
4. The handler receives `(ParsedOptions, WalletApiWrapper, OutputFormatter)` — use `formatter.success()/error()` for output

### Package Organization

| Package | Purpose |
|---------|---------|
| `walletcli` | CLI entry points, API wrapper |
| `walletcli.cli` | Standard CLI framework: registry, definitions, options, formatter |
| `walletcli.cli.commands` | Standard CLI command implementations by domain |
| `walletserver` | Core wallet API and gRPC communication |
| `common` | Crypto utilities, encoding, enums, shared helpers |
| `core` | Configuration, data converters, DAOs, exceptions, managers |
| `keystore` | Wallet file encryption/decryption, key management |
| `ledger` | Ledger hardware wallet integration via HID |
| `mnemonic` | BIP39 mnemonic seed phrase support |
| `multi` | Multi-signature transaction handling |
| `gasfree` | GasFree transaction API (transfer tokens without gas) |

### Configuration

- **Network config:** `src/main/resources/config.conf` (HOCON format via Typesafe Config)
- **Logging:** `src/main/resources/logback.xml` (Logback, INFO level console + rolling file)
- **Lombok:** `lombok.config` — uses `logger` as the log field name (not the default `log`)

### Key Frameworks & Libraries

- **Trident SDK 0.10.0** — All gRPC API calls to TRON nodes
- **JCommander 1.82** — CLI argument parsing (REPL 交互模式)
- **JLine 3.25.0** — Interactive terminal/readline
- **BouncyCastle** — Cryptographic operations
- **Protobuf 3.25.5 / gRPC 1.60.0** — Protocol definitions and transport
- **Lombok** — `@Getter`, `@Setter`, `@Slf4j` etc. (annotation processing)
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,10 @@ shadowJar {
version = null
mergeServiceFiles() // https://github.com/grpc/grpc-java/issues/10853
}

task qaRun(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
mainClass = 'org.tron.qa.QARunner'
args = project.hasProperty('qaArgs') ? project.property('qaArgs').split(' ') : ['list']
standardInput = System.in
}
Loading