wavecli dev is a generated, low-level RPC escape hatch for daemon
services. It is intentionally separate from the curated user-facing commands
so developers can reach every exposed daemon RPC without hand-writing a CLI
command for each method.
make rpc regenerates protobuf stubs and then runs:
go run ./cmd/wavecli/internal/gen-devrpcThe generator reads the linked Go descriptors for:
waverpc.File_daemon_proto(waverpc.DaemonService, aliasdaemon)swapclientrpc.File_swap_client_proto(swapclientrpc.SwapClientService, aliasswapclient)wavewalletrpc.File_wallet_proto(wavewalletrpc.WalletServiceandWalletInspectionService, aliaseswalletandwallet-inspection)btcwalletrpc.File_api_proto(walletrpc.VersionServiceandwalletrpc.WalletService, aliasesbtcwallet-versionandbtcwallet)
It writes cmd/wavecli/waveclicommands/devrpc/registry_generated.go.
That generated file contains only service and method metadata. The runtime
builder in cmd/wavecli/waveclicommands/devrpc owns flag parsing,
dynamic request construction, RPC invocation, streaming response rendering, and
error mapping.
The canonical form is:
wavecli dev <grpc_service> <call>Examples:
wavecli dev waverpc.DaemonService GetInfo
wavecli dev daemon getinfo
wavecli dev daemon list-vtxos --status-filter live
wavecli dev swapclient start-pay --invoice <bolt11>The generated registry also provides one stable short alias for each service and one stable kebab-case alias for each method.
The runtime builds request messages dynamically from protobuf descriptors. Generated flags use proto field names so the command stays predictable and does not drift from the wire contract.
Help and examples show kebab-case flag names. The corresponding snake_case spellings remain silent aliases, while field names inside JSON payloads stay snake_case to match proto JSON.
Field handling rules:
- Scalar fields become canonical
--field-nameflags. - Boolean fields become normal Cobra bool flags.
- Repeated scalar fields become repeatable
--field-nameflags. - Bytes fields accept hex strings, with or without a
0xprefix. - Enums accept numeric values, full enum value names, or lower aliases.
- Singular nested message fields are flattened with dotted flag names.
- Repeated messages and maps stay JSON via
--field-name-json. - The global
--jsonflag remains a raw protojson escape hatch and takes precedence over generated flags.
Flattening is deliberately bounded to singular messages. For example:
wavecli dev daemon prepare-oor \
--recipient.address bcrt1... \
--recipient.amount-sat 1000
wavecli dev daemon refresh-vtxos \
--outpoints.outpoints txid:0 \
--outpoints.outpoints txid:1 \
--dry-runRepeated message fields are not flattened because indexed flags would need a larger form language for grouping, ordering, merging, and partial validation. Use JSON for those fields:
wavecli dev daemon send-vtxo \
--recipients-json '[{"address":"bcrt1...","amount_sat":1000}]'The builder checks oneof conflicts while applying flags, including nested oneofs reached through flattened paths. These two flags conflict:
--recipient.address bcrt1... --recipient.pubkey 00But multiple fields under the same selected message are allowed:
--recipient.address bcrt1... --recipient.amount-sat 1000Daemon-side validation remains authoritative. The generated command only ensures the request can be represented as a valid protobuf message before it is sent.