Add zsh completion script for wallet CLI

This commit is contained in:
fryorcraken 2026-01-06 11:09:49 +11:00
parent 1d09afd9e0
commit 4d3845b8e0
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
2 changed files with 442 additions and 0 deletions

117
completions/README.md Normal file
View File

@ -0,0 +1,117 @@
# Wallet CLI Completion
Completion scripts for the LSSA `wallet` command.
## ZSH
Works with both vanilla zsh and oh-my-zsh.
### Features
- Full completion for all wallet subcommands
- Contextual option completion for each command
- Dynamic account ID completion via `wallet account list`
- Descriptions for all commands and options
### Supported Commands
| Command | Description |
|------------------------|-------------------------------------------------------------|
| `wallet auth-transfer` | Authenticated transfer (init, send) |
| `wallet chain-info` | Chain info queries (current-block-id, block, transaction) |
| `wallet account` | Account management (get, list, new, sync-private) |
| `wallet pinata` | Piñata faucet (claim) |
| `wallet token` | Token operations (new, send) |
| `wallet amm` | AMM operations (new, swap, add-liquidity, remove-liquidity) |
| `wallet check-health` | Health check |
### Installation
#### Vanilla Zsh
1. Create a completions directory:
```sh
mkdir -p ~/.zsh/completions
```
2. Copy the completion file:
```sh
cp ./zsh/_wallet ~/.zsh/completions/
```
3. Add to your `~/.zshrc` (before any `compinit` call, or add these lines if you don't have one):
```sh
fpath=(~/.zsh/completions $fpath)
autoload -Uz compinit && compinit
```
4. Reload your shell:
```sh
exec zsh
```
#### Oh-My-Zsh
1. Create the plugin directory and copy the file:
```sh
mkdir -p ~/.oh-my-zsh/custom/plugins/wallet
cp _wallet ~/.oh-my-zsh/custom/plugins/wallet/
```
2. Add `wallet` to your plugins array in `~/.zshrc`:
```sh
plugins=(... wallet)
```
3. Reload your shell:
```sh
exec zsh
```
### Requirements
The completion script calls `wallet account list` to dynamically fetch account IDs. Ensure the `wallet` command is in your `$PATH`.
### Usage
```sh
# Main commands
wallet <TAB>
# Account subcommands
wallet account <TAB>
# Options for auth-transfer send
wallet auth-transfer send --<TAB>
# Account types when creating
wallet account new <TAB>
# Shows: public private
# Account IDs (fetched dynamically)
wallet account get --account-id <TAB>
# Shows: Public/... Private/...
```
## Troubleshooting
### Completions not appearing
1. Check that `compinit` is called in your `.zshrc`
2. Rebuild the completion cache:
```sh
rm -f ~/.zcompdump*
exec zsh
```
### Account IDs not completing
Ensure `wallet account list` works from your command line.

325
completions/zsh/_wallet Normal file
View File

@ -0,0 +1,325 @@
#compdef wallet
# Zsh completion script for the wallet CLI
# See instructions in ../README.md
_wallet() {
local -a commands
local -a subcommands
local curcontext="$curcontext" state line
typeset -A opt_args
_arguments -C \
'1: :->command' \
'*:: :->args'
case $state in
command)
commands=(
'auth-transfer:Authenticated transfer subcommand'
'chain-info:Generic chain info subcommand'
'account:Account view and sync subcommand'
'pinata:Pinata program interaction subcommand'
'token:Token program interaction subcommand'
'amm:AMM program interaction subcommand'
'check-health:Check the wallet can connect to the node and builtin local programs match the remote versions'
'help:Print help message or the help of the given subcommand(s)'
)
_describe -t commands 'wallet commands' commands
;;
args)
case $line[1] in
auth-transfer)
_wallet_auth_transfer
;;
chain-info)
_wallet_chain_info
;;
account)
_wallet_account
;;
pinata)
_wallet_pinata
;;
token)
_wallet_token
;;
amm)
_wallet_amm
;;
help)
_wallet_help
;;
esac
;;
esac
}
# auth-transfer subcommand
_wallet_auth_transfer() {
local -a subcommands
_arguments -C \
'1: :->subcommand' \
'*:: :->args'
case $state in
subcommand)
subcommands=(
'init:Initialize account under authenticated transfer program'
'send:Send native tokens from one account to another with variable privacy'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'auth-transfer subcommands' subcommands
;;
args)
case $line[1] in
init)
_arguments \
'--account-id[Account ID to initialize]:account_id:_wallet_account_ids'
;;
send)
_arguments \
'--from[Source account ID]:from_account:_wallet_account_ids' \
'--to[Destination account ID (for owned accounts)]:to_account:_wallet_account_ids' \
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
'--to-ipk[Destination viewing public key (for foreign private accounts)]:ipk:' \
'--amount[Amount of native tokens to send]:amount:'
;;
esac
;;
esac
}
# chain-info subcommand
_wallet_chain_info() {
local -a subcommands
_arguments -C \
'1: :->subcommand' \
'*:: :->args'
case $state in
subcommand)
subcommands=(
'current-block-id:Get current block id from sequencer'
'block:Get block at id from sequencer'
'transaction:Get transaction at hash from sequencer'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'chain-info subcommands' subcommands
;;
args)
case $line[1] in
block)
_arguments \
'--id[Block ID to retrieve]:block_id:'
;;
transaction)
_arguments \
'--hash[Transaction hash to retrieve]:tx_hash:'
;;
esac
;;
esac
}
# account subcommand
_wallet_account() {
local -a subcommands
_arguments -C \
'1: :->subcommand' \
'*:: :->args'
case $state in
subcommand)
subcommands=(
'get:Get account data'
'list:List all accounts'
'new:Produce new public or private account'
'sync-private:Sync private accounts'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'account subcommands' subcommands
;;
args)
case $line[1] in
get)
_arguments \
'--account-id[Account ID to query]:account_id:_wallet_account_ids'
;;
new)
_arguments \
'1:account type:(public private)'
;;
esac
;;
esac
}
# pinata subcommand
_wallet_pinata() {
local -a subcommands
_arguments -C \
'1: :->subcommand' \
'*:: :->args'
case $state in
subcommand)
subcommands=(
'claim:Claim tokens from the Piñata faucet'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'pinata subcommands' subcommands
;;
args)
case $line[1] in
claim)
_arguments \
'--to[Destination account ID to receive claimed tokens]:to_account:_wallet_account_ids'
;;
esac
;;
esac
}
# token subcommand
_wallet_token() {
local -a subcommands
_arguments -C \
'1: :->subcommand' \
'*:: :->args'
case $state in
subcommand)
subcommands=(
'new:Produce a new token'
'send:Send tokens from one account to another with variable privacy'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'token subcommands' subcommands
;;
args)
case $line[1] in
new)
_arguments \
'--name[Token name]:name:' \
'--total-supply[Total supply of tokens to mint]:total_supply:' \
'--definition-account-id[Account ID for token definition]:definition_account:_wallet_account_ids' \
'--supply-account-id[Account ID to receive initial supply]:supply_account:_wallet_account_ids'
;;
send)
_arguments \
'--from[Source holding account ID]:from_account:_wallet_account_ids' \
'--to[Destination holding account ID]:to_account:_wallet_account_ids' \
'--amount[Amount of tokens to send]:amount:'
;;
esac
;;
esac
}
# amm subcommand
_wallet_amm() {
local -a subcommands
_arguments -C \
'1: :->subcommand' \
'*:: :->args'
case $state in
subcommand)
subcommands=(
'new:Create a new liquidity pool'
'swap:Swap tokens using the AMM'
'add-liquidity:Add liquidity to an existing pool'
'remove-liquidity:Remove liquidity from a pool'
'help:Print this message or the help of the given subcommand(s)'
)
_describe -t subcommands 'amm subcommands' subcommands
;;
args)
case $line[1] in
new)
_arguments \
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
'--user-holding-lp[User LP token holding account ID]:holding_lp:_wallet_account_ids' \
'--balance-a[Amount of token A to deposit]:balance_a:' \
'--balance-b[Amount of token B to deposit]:balance_b:'
;;
swap)
_arguments \
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
'--amount-in[Amount of tokens to swap]:amount_in:' \
'--min-amount-out[Minimum tokens expected in return]:min_amount_out:' \
'--token-definition[Definition ID of the token being provided]:token_def:'
;;
add-liquidity)
_arguments \
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
'--user-holding-lp[User LP token holding account ID]:holding_lp:_wallet_account_ids' \
'--max-amount-a[Maximum amount of token A to deposit]:max_amount_a:' \
'--max-amount-b[Maximum amount of token B to deposit]:max_amount_b:' \
'--min-amount-lp[Minimum LP tokens to receive]:min_amount_lp:'
;;
remove-liquidity)
_arguments \
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
'--user-holding-lp[User LP token holding account ID]:holding_lp:_wallet_account_ids' \
'--balance-lp[Amount of LP tokens to burn]:balance_lp:' \
'--min-amount-a[Minimum token A to receive]:min_amount_a:' \
'--min-amount-b[Minimum token B to receive]:min_amount_b:'
;;
esac
;;
esac
}
# help subcommand
_wallet_help() {
local -a commands
commands=(
'auth-transfer:Authenticated transfer subcommand'
'chain-info:Generic chain info subcommand'
'account:Account view and sync subcommand'
'pinata:Pinata program interaction subcommand'
'token:Token program interaction subcommand'
'amm:AMM program interaction subcommand'
'check-health:Check the wallet can connect to the node'
)
_describe -t commands 'wallet commands' commands
}
# Helper function to complete account IDs
# Uses `wallet account list` to get available accounts
# Only includes accounts with /N prefix (where N is a number)
_wallet_account_ids() {
local -a accounts
local line
# Try to get accounts from wallet account list command
# Filter to lines starting with /N (numbered accounts) and extract the account ID
if command -v wallet &>/dev/null; then
while IFS= read -r line; do
# Remove trailing comma if present and add to array
[[ -n "$line" ]] && accounts+=("${line%,}")
done < <(wallet account list 2>/dev/null | grep '^/[0-9]' | awk '{print $2}')
fi
# Provide type prefixes as fallback if command fails or returns nothing
if (( ${#accounts} == 0 )); then
compadd -S '' -- 'Public/' 'Private/'
return
fi
_multi_parts / accounts
}
_wallet "$@"