┌─┐┌─┐┌─┐┬ ┬
├─┘├┤ │ │ │
┴ └─┘└─┘└─┘
a Verus wallet that lives in your terminal
pecu is a command-line Verus wallet, and the example app for the
Verus Rust SDK. Keys, transparent
sends, air-gapped signing, transaction decoding, the VerusID lifecycle and
currency operations — from one binary.
chainvue.github.io/pecu-cli — the same documentation, searchable, with the demos below playing in place.
Every demo here is one recording shown twice: phosphor green if you read GitHub
in the dark, the same panels in dark ink if you read it in the light. pecu
decides for itself whether to emit colour at all — a pipe or NO_COLOR gets
none — but it never guesses your terminal's background, because there is no way
to ask that is worth a wrong answer on a spend confirmation. On a light
terminal, say so once:
export PECU_THEME=light # or --theme light, one command at a timeThere is no verusd to install, no chain to sync, no wallet daemon to keep
running. pecu asks a public RPC endpoint questions and hands it finished
transaction bytes. Nothing else.
pecu id show VRSCTEST@ # ~0.2s, about as fast as curl to the same nodeYour keys never leave the machine you are on. They are generated locally,
encrypted at rest with Argon2id + ChaCha20-Poly1305, and signing happens in
process — the node is never asked to hold, unlock or use a key. Point it
somewhere else with --node or a config file; it is one URL.
Rust 1.95, which rust-toolchain.toml pins.
cargo build --release
./target/release/pecu --help| Command | Does |
|---|---|
pecu doctor |
Node reachability, chain tip, whether DeFi is switched off, config paths, build info |
pecu key gen|import|list|show|export|phrase |
Encrypted keystore |
pecu wallet balance|utxos|history |
Spendable, withheld, token and unconfirmed balances |
pecu tx explain |
Says what every output in a transaction actually is |
pecu send |
Transparent sends: native, token, or out of a VerusID's own funds |
pecu plan send · sign · broadcast |
The air-gap trio, over files or QR codes — the chain's own coins only |
pecu id list |
Which VerusIDs an address is a primary of — the one read that starts from a key |
pecu id show|register|update|revoke|recover|unlock |
The VerusID lifecycle, including timelocks |
pecu currency show|launch|mint|preconvert|convert |
Currency definitions, launches, minting, conversions |
Every command takes --explain, which prints the exact verus-sdk calls it
made. The output is meant to teach you the SDK.
Full reference: docs/commands.md · configuration · design notes · status
The last line is the point of the tool. An identity that is its own recovery authority is unrevokable, and nothing in the raw RPC reply says so.
Give it a txid and it fetches; give it hex or - and it never touches the
network. This is a real currency launch on VRSCTEST — seven outputs, of which
one holds a VerusID and one holds reserves:
Output #2 is the reason this command exists: an undecodable CryptoCondition
that may hold currency, called out rather than shown as an empty 0.00000000.
Spendable, withheld, in-conditions and every token on the address, separated — because a balance that adds them up is a balance you cannot spend from.
Two transactions: one commits to the name, a second claims it once the first
confirms. pecu runs both and waits in between.
Interrupting is safe. The reservation is written to disk before the commitment is broadcast, so Ctrl-C, a timeout or a dead connection all leave a registration the same command picks up. That is not theoretical: an earlier run lost its node mid-wait and resumed from the file.
--dry-run builds and signs and stops, so you can read the panel before
anything is broadcast. --json refuses to spend without --yes.
--currency moves a token instead of the chain's own coins. The amount is
labelled with what is actually moving; the fee stays in VRSCTEST, because that
is what the miner is paid in. The currency id row is what the name resolved
to — a name is text somebody registered, the id is the part that identifies
anything.
The token-carrying outputs read 0.00000000 VRSCTEST because a token rides in
the output's script, not its value. Five go to the recipient, twenty come back
as change — which is the sum a reader is meant to check before typing yes.
Three commands, three machines. The one holding the key never opens a socket.
pecu plan send --address R… --to R… --amount 1 --out plan.hex # online, no key
pecu sign @plan.hex --key cold --out signed.hex # offline, no node
pecu broadcast @signed.hex # online, no keyEach step also speaks QR codes, so the offline machine needs no cable.
The gap carries the chain's own coins, and nothing else. pecu plan send
takes --currency and --from-identity and refuses each by name, before it
opens a socket: a token rides in an output's script and a VerusID's funds sit in
pay-to-identity outputs, and the SDK builds an unsigned form of neither — every
token and identity builder signs as it builds, so there is no partial to carry
offline. pecu send moves both, and it signs on the machine that talks to the
node.
- Mainnet ships unable to spend.
allow_spendis off for it; moving real coins takes a deliberate edit, not a forgotten--profile. --dry-runbuilds and stops. Nothing is broadcast, nothing is written.--jsonis output, not consent. Machine-readable mode refuses to spend without--yes, because the confirmation prompt would go to the stream you are parsing.- Irreversible things say so first, on a panel, before asking.
Early, and honest about it.
Proven on chain: identity registration and reads, transaction decoding, key management, balances and UTXO reads, transparent sends.
Built, waiting on a chain: --nft, seeded contributions at launch, and
paying a token to a VerusID are each refused by a named diagnostic rather than
attempted. The SDK gaps they were written for have since closed upstream;
tests/upstream.rs proves that offline. Removing a guard needs it watched onto
the chain, which needs DeFi enabled on the test chain — see
docs/status.md.
Not in scope: shielded/z-address operations, marketplace offers.
Apache-2.0, matching the SDK.