mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-03-24 11:13:06 +00:00
feat: add --account-label as alternative to --account-id across all wallet subcommands
Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
fb083ce91e
commit
1474e01a26
@ -22,6 +22,20 @@ _wallet_complete_account_id() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Helper function to complete account labels
|
||||
_wallet_complete_account_label() {
|
||||
local cur="$1"
|
||||
local labels
|
||||
|
||||
if command -v wallet &>/dev/null; then
|
||||
labels=$(wallet account list 2>/dev/null | grep -o '\[.*\]' | sed 's/^\[//;s/\]$//')
|
||||
fi
|
||||
|
||||
if [[ -n "$labels" ]]; then
|
||||
COMPREPLY=($(compgen -W "$labels" -- "$cur"))
|
||||
fi
|
||||
}
|
||||
|
||||
_wallet() {
|
||||
local cur prev words cword
|
||||
_init_completion 2>/dev/null || {
|
||||
@ -91,20 +105,32 @@ _wallet() {
|
||||
--account-id)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--account-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--account-id" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--account-id --account-label" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
send)
|
||||
case "$prev" in
|
||||
--from | --to)
|
||||
--from)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--from-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--to)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--to-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--to-npk | --to-vpk | --amount)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--from --to --to-npk --to-vpk --amount" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--from --from-label --to --to-label --to-npk --to-vpk --amount" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -147,8 +173,11 @@ _wallet() {
|
||||
-a | --account-id)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--account-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "-r --raw -k --keys -a --account-id" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "-r --raw -k --keys -a --account-id --account-label" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -186,10 +215,13 @@ _wallet() {
|
||||
-a | --account-id)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--account-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
-l | --label)
|
||||
;; # no specific completion for label value
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "-a --account-id -l --label" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "-a --account-id --account-label -l --label" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -206,8 +238,11 @@ _wallet() {
|
||||
--to)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--to-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--to" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--to --to-label" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -221,49 +256,85 @@ _wallet() {
|
||||
;;
|
||||
new)
|
||||
case "$prev" in
|
||||
--definition-account-id | --supply-account-id)
|
||||
--definition-account-id)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--definition-account-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--supply-account-id)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--supply-account-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
-n | --name | -t | --total-supply)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--definition-account-id --supply-account-id -n --name -t --total-supply" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--definition-account-id --definition-account-label --supply-account-id --supply-account-label -n --name -t --total-supply" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
send)
|
||||
case "$prev" in
|
||||
--from | --to)
|
||||
--from)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--from-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--to)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--to-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--to-npk | --to-vpk | --amount)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--from --to --to-npk --to-vpk --amount" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--from --from-label --to --to-label --to-npk --to-vpk --amount" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
burn)
|
||||
case "$prev" in
|
||||
--definition | --holder)
|
||||
--definition)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--definition-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--holder)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--holder-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--amount)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--definition --holder --amount" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--definition --definition-label --holder --holder-label --amount" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
mint)
|
||||
case "$prev" in
|
||||
--definition | --holder)
|
||||
--definition)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--definition-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--holder)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--holder-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--holder-npk | --holder-vpk | --amount)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--definition --holder --holder-npk --holder-vpk --amount" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--definition --definition-label --holder --holder-label --holder-npk --holder-vpk --amount" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -277,49 +348,103 @@ _wallet() {
|
||||
;;
|
||||
new)
|
||||
case "$prev" in
|
||||
--user-holding-a | --user-holding-b | --user-holding-lp)
|
||||
--user-holding-a)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-a-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-b)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-b-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-lp)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-lp-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--balance-a | --balance-b)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-b --user-holding-lp --balance-a --balance-b" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-a-label --user-holding-b --user-holding-b-label --user-holding-lp --user-holding-lp-label --balance-a --balance-b" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
swap)
|
||||
case "$prev" in
|
||||
--user-holding-a | --user-holding-b)
|
||||
--user-holding-a)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-a-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-b)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-b-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--amount-in | --min-amount-out | --token-definition)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-b --amount-in --min-amount-out --token-definition" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-a-label --user-holding-b --user-holding-b-label --amount-in --min-amount-out --token-definition" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
add-liquidity)
|
||||
case "$prev" in
|
||||
--user-holding-a | --user-holding-b | --user-holding-lp)
|
||||
--user-holding-a)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-a-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-b)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-b-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-lp)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-lp-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--max-amount-a | --max-amount-b | --min-amount-lp)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-b --user-holding-lp --max-amount-a --max-amount-b --min-amount-lp" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-a-label --user-holding-b --user-holding-b-label --user-holding-lp --user-holding-lp-label --max-amount-a --max-amount-b --min-amount-lp" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
remove-liquidity)
|
||||
case "$prev" in
|
||||
--user-holding-a | --user-holding-b | --user-holding-lp)
|
||||
--user-holding-a)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-a-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-b)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-b-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--user-holding-lp)
|
||||
_wallet_complete_account_id "$cur"
|
||||
;;
|
||||
--user-holding-lp-label)
|
||||
_wallet_complete_account_label "$cur"
|
||||
;;
|
||||
--balance-lp | --min-amount-a | --min-amount-b)
|
||||
;; # no specific completion
|
||||
*)
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-b --user-holding-lp --balance-lp --min-amount-a --min-amount-b" -- "$cur"))
|
||||
COMPREPLY=($(compgen -W "--user-holding-a --user-holding-a-label --user-holding-b --user-holding-b-label --user-holding-lp --user-holding-lp-label --balance-lp --min-amount-a --min-amount-b" -- "$cur"))
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
|
||||
@ -90,12 +90,15 @@ _wallet_auth_transfer() {
|
||||
case $line[1] in
|
||||
init)
|
||||
_arguments \
|
||||
'--account-id[Account ID to initialize]:account_id:_wallet_account_ids'
|
||||
'--account-id[Account ID to initialize]:account_id:_wallet_account_ids' \
|
||||
'--account-label[Account label (alternative to --account-id)]:label:_wallet_account_labels'
|
||||
;;
|
||||
send)
|
||||
_arguments \
|
||||
'--from[Source account ID]:from_account:_wallet_account_ids' \
|
||||
'--from-label[Source account label (alternative to --from)]:label:_wallet_account_labels' \
|
||||
'--to[Destination account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
||||
'--to-label[Destination account label (alternative to --to)]:label:_wallet_account_labels' \
|
||||
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
||||
'--to-vpk[Destination viewing public key (for foreign private accounts)]:vpk:' \
|
||||
'--amount[Amount of native tokens to send]:amount:'
|
||||
@ -165,7 +168,8 @@ _wallet_account() {
|
||||
_arguments \
|
||||
'(-r --raw)'{-r,--raw}'[Get raw account data]' \
|
||||
'(-k --keys)'{-k,--keys}'[Display keys (pk for public accounts, npk/vpk for private accounts)]' \
|
||||
'(-a --account-id)'{-a,--account-id}'[Account ID to query]:account_id:_wallet_account_ids'
|
||||
'(-a --account-id)'{-a,--account-id}'[Account ID to query]:account_id:_wallet_account_ids' \
|
||||
'--account-label[Account label (alternative to --account-id)]:label:_wallet_account_labels'
|
||||
;;
|
||||
list|ls)
|
||||
_arguments \
|
||||
@ -189,6 +193,7 @@ _wallet_account() {
|
||||
label)
|
||||
_arguments \
|
||||
'(-a --account-id)'{-a,--account-id}'[Account ID to label]:account_id:_wallet_account_ids' \
|
||||
'--account-label[Account label (alternative to --account-id)]:label:_wallet_account_labels' \
|
||||
'(-l --label)'{-l,--label}'[The label to assign to the account]:label:'
|
||||
;;
|
||||
esac
|
||||
@ -216,7 +221,8 @@ _wallet_pinata() {
|
||||
case $line[1] in
|
||||
claim)
|
||||
_arguments \
|
||||
'--to[Destination account ID to receive claimed tokens]:to_account:_wallet_account_ids'
|
||||
'--to[Destination account ID to receive claimed tokens]:to_account:_wallet_account_ids' \
|
||||
'--to-label[Destination account label (alternative to --to)]:label:_wallet_account_labels'
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
@ -249,12 +255,16 @@ _wallet_token() {
|
||||
'--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'
|
||||
'--definition-account-label[Definition account label (alternative to --definition-account-id)]:label:_wallet_account_labels' \
|
||||
'--supply-account-id[Account ID to receive initial supply]:supply_account:_wallet_account_ids' \
|
||||
'--supply-account-label[Supply account label (alternative to --supply-account-id)]:label:_wallet_account_labels'
|
||||
;;
|
||||
send)
|
||||
_arguments \
|
||||
'--from[Source holding account ID]:from_account:_wallet_account_ids' \
|
||||
'--from-label[Source account label (alternative to --from)]:label:_wallet_account_labels' \
|
||||
'--to[Destination holding account ID (for owned accounts)]:to_account:_wallet_account_ids' \
|
||||
'--to-label[Destination account label (alternative to --to)]:label:_wallet_account_labels' \
|
||||
'--to-npk[Destination nullifier public key (for foreign private accounts)]:npk:' \
|
||||
'--to-vpk[Destination viewing public key (for foreign private accounts)]:vpk:' \
|
||||
'--amount[Amount of tokens to send]:amount:'
|
||||
@ -262,13 +272,17 @@ _wallet_token() {
|
||||
burn)
|
||||
_arguments \
|
||||
'--definition[Definition account ID]:definition_account:_wallet_account_ids' \
|
||||
'--definition-label[Definition account label (alternative to --definition)]:label:_wallet_account_labels' \
|
||||
'--holder[Holder account ID]:holder_account:_wallet_account_ids' \
|
||||
'--holder-label[Holder account label (alternative to --holder)]:label:_wallet_account_labels' \
|
||||
'--amount[Amount of tokens to burn]:amount:'
|
||||
;;
|
||||
mint)
|
||||
_arguments \
|
||||
'--definition[Definition account ID]:definition_account:_wallet_account_ids' \
|
||||
'--definition-label[Definition account label (alternative to --definition)]:label:_wallet_account_labels' \
|
||||
'--holder[Holder account ID (for owned accounts)]:holder_account:_wallet_account_ids' \
|
||||
'--holder-label[Holder account label (alternative to --holder)]:label:_wallet_account_labels' \
|
||||
'--holder-npk[Holder nullifier public key (for foreign private accounts)]:npk:' \
|
||||
'--holder-vpk[Holder viewing public key (for foreign private accounts)]:vpk:' \
|
||||
'--amount[Amount of tokens to mint]:amount:'
|
||||
@ -302,15 +316,20 @@ _wallet_amm() {
|
||||
new)
|
||||
_arguments \
|
||||
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
|
||||
'--user-holding-a-label[User holding A account label (alternative to --user-holding-a)]:label:_wallet_account_labels' \
|
||||
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
|
||||
'--user-holding-b-label[User holding B account label (alternative to --user-holding-b)]:label:_wallet_account_labels' \
|
||||
'--user-holding-lp[User LP token holding account ID]:holding_lp:_wallet_account_ids' \
|
||||
'--user-holding-lp-label[User holding LP account label (alternative to --user-holding-lp)]:label:_wallet_account_labels' \
|
||||
'--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-a-label[User holding A account label (alternative to --user-holding-a)]:label:_wallet_account_labels' \
|
||||
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
|
||||
'--user-holding-b-label[User holding B account label (alternative to --user-holding-b)]:label:_wallet_account_labels' \
|
||||
'--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:'
|
||||
@ -318,8 +337,11 @@ _wallet_amm() {
|
||||
add-liquidity)
|
||||
_arguments \
|
||||
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
|
||||
'--user-holding-a-label[User holding A account label (alternative to --user-holding-a)]:label:_wallet_account_labels' \
|
||||
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
|
||||
'--user-holding-b-label[User holding B account label (alternative to --user-holding-b)]:label:_wallet_account_labels' \
|
||||
'--user-holding-lp[User LP token holding account ID]:holding_lp:_wallet_account_ids' \
|
||||
'--user-holding-lp-label[User holding LP account label (alternative to --user-holding-lp)]:label:_wallet_account_labels' \
|
||||
'--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:'
|
||||
@ -327,8 +349,11 @@ _wallet_amm() {
|
||||
remove-liquidity)
|
||||
_arguments \
|
||||
'--user-holding-a[User token A holding account ID]:holding_a:_wallet_account_ids' \
|
||||
'--user-holding-a-label[User holding A account label (alternative to --user-holding-a)]:label:_wallet_account_labels' \
|
||||
'--user-holding-b[User token B holding account ID]:holding_b:_wallet_account_ids' \
|
||||
'--user-holding-b-label[User holding B account label (alternative to --user-holding-b)]:label:_wallet_account_labels' \
|
||||
'--user-holding-lp[User LP token holding account ID]:holding_lp:_wallet_account_ids' \
|
||||
'--user-holding-lp-label[User holding LP account label (alternative to --user-holding-lp)]:label:_wallet_account_labels' \
|
||||
'--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:'
|
||||
@ -424,7 +449,7 @@ _wallet_help() {
|
||||
_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
|
||||
@ -433,14 +458,35 @@ _wallet_account_ids() {
|
||||
[[ -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
|
||||
}
|
||||
|
||||
# Helper function to complete account labels
|
||||
# Uses `wallet account list` to get available labels
|
||||
_wallet_account_labels() {
|
||||
local -a labels
|
||||
local line
|
||||
|
||||
if command -v wallet &>/dev/null; then
|
||||
while IFS= read -r line; do
|
||||
local label
|
||||
# Extract label from [...] at end of line
|
||||
label="${line##*\[}"
|
||||
label="${label%\]}"
|
||||
[[ -n "$label" && "$label" != "$line" ]] && labels+=("$label")
|
||||
done < <(wallet account list 2>/dev/null)
|
||||
fi
|
||||
|
||||
if (( ${#labels} > 0 )); then
|
||||
compadd -a labels
|
||||
fi
|
||||
}
|
||||
|
||||
_wallet "$@"
|
||||
|
||||
@ -10,7 +10,10 @@ use crate::{
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
config::Label,
|
||||
helperfunctions::{AccountPrivacyKind, HumanReadableAccount, parse_addr_with_privacy_prefix},
|
||||
helperfunctions::{
|
||||
AccountPrivacyKind, HumanReadableAccount, parse_addr_with_privacy_prefix,
|
||||
resolve_id_or_label,
|
||||
},
|
||||
};
|
||||
|
||||
/// Represents generic chain CLI subcommand.
|
||||
@ -25,8 +28,16 @@ pub enum AccountSubcommand {
|
||||
#[arg(short, long)]
|
||||
keys: bool,
|
||||
/// Valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(short, long)]
|
||||
account_id: String,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
conflicts_with = "account_label",
|
||||
required_unless_present = "account_label"
|
||||
)]
|
||||
account_id: Option<String>,
|
||||
/// Account label (alternative to --account-id).
|
||||
#[arg(long, conflicts_with = "account_id")]
|
||||
account_label: Option<String>,
|
||||
},
|
||||
/// Produce new public or private account.
|
||||
#[command(subcommand)]
|
||||
@ -43,8 +54,16 @@ pub enum AccountSubcommand {
|
||||
/// Set a label for an account.
|
||||
Label {
|
||||
/// Valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(short, long)]
|
||||
account_id: String,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
conflicts_with = "account_label",
|
||||
required_unless_present = "account_label"
|
||||
)]
|
||||
account_id: Option<String>,
|
||||
/// Account label (alternative to --account-id).
|
||||
#[arg(long = "account-label", conflicts_with = "account_id")]
|
||||
account_label: Option<String>,
|
||||
/// The label to assign to the account.
|
||||
#[arg(short, long)]
|
||||
label: String,
|
||||
@ -171,8 +190,15 @@ impl WalletSubcommand for AccountSubcommand {
|
||||
raw,
|
||||
keys,
|
||||
account_id,
|
||||
account_label,
|
||||
} => {
|
||||
let (account_id_str, addr_kind) = parse_addr_with_privacy_prefix(&account_id)?;
|
||||
let resolved = resolve_id_or_label(
|
||||
account_id,
|
||||
account_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (account_id_str, addr_kind) = parse_addr_with_privacy_prefix(&resolved)?;
|
||||
|
||||
let account_id: nssa::AccountId = account_id_str.parse()?;
|
||||
|
||||
@ -371,8 +397,18 @@ impl WalletSubcommand for AccountSubcommand {
|
||||
|
||||
Ok(SubcommandReturnValue::Empty)
|
||||
}
|
||||
Self::Label { account_id, label } => {
|
||||
let (account_id_str, _) = parse_addr_with_privacy_prefix(&account_id)?;
|
||||
Self::Label {
|
||||
account_id,
|
||||
account_label,
|
||||
label,
|
||||
} => {
|
||||
let resolved = resolve_id_or_label(
|
||||
account_id,
|
||||
account_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (account_id_str, _) = parse_addr_with_privacy_prefix(&resolved)?;
|
||||
|
||||
// Check if label is already used by a different account
|
||||
if let Some(existing_account) = wallet_core
|
||||
|
||||
@ -5,7 +5,7 @@ use nssa::AccountId;
|
||||
use crate::{
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix, resolve_id_or_label},
|
||||
program_facades::amm::Amm,
|
||||
};
|
||||
|
||||
@ -19,14 +19,35 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Only public execution allowed.
|
||||
New {
|
||||
/// `user_holding_a` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_a_label",
|
||||
required_unless_present = "user_holding_a_label"
|
||||
)]
|
||||
user_holding_a: Option<String>,
|
||||
/// User holding A account label (alternative to --user-holding-a).
|
||||
#[arg(long, conflicts_with = "user_holding_a")]
|
||||
user_holding_a_label: Option<String>,
|
||||
/// `user_holding_b` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_b: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_b_label",
|
||||
required_unless_present = "user_holding_b_label"
|
||||
)]
|
||||
user_holding_b: Option<String>,
|
||||
/// User holding B account label (alternative to --user-holding-b).
|
||||
#[arg(long, conflicts_with = "user_holding_b")]
|
||||
user_holding_b_label: Option<String>,
|
||||
/// `user_holding_lp` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_lp: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_lp_label",
|
||||
required_unless_present = "user_holding_lp_label"
|
||||
)]
|
||||
user_holding_lp: Option<String>,
|
||||
/// User holding LP account label (alternative to --user-holding-lp).
|
||||
#[arg(long, conflicts_with = "user_holding_lp")]
|
||||
user_holding_lp_label: Option<String>,
|
||||
#[arg(long)]
|
||||
balance_a: u128,
|
||||
#[arg(long)]
|
||||
@ -39,11 +60,25 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Only public execution allowed.
|
||||
Swap {
|
||||
/// `user_holding_a` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_a_label",
|
||||
required_unless_present = "user_holding_a_label"
|
||||
)]
|
||||
user_holding_a: Option<String>,
|
||||
/// User holding A account label (alternative to --user-holding-a).
|
||||
#[arg(long, conflicts_with = "user_holding_a")]
|
||||
user_holding_a_label: Option<String>,
|
||||
/// `user_holding_b` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_b: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_b_label",
|
||||
required_unless_present = "user_holding_b_label"
|
||||
)]
|
||||
user_holding_b: Option<String>,
|
||||
/// User holding B account label (alternative to --user-holding-b).
|
||||
#[arg(long, conflicts_with = "user_holding_b")]
|
||||
user_holding_b_label: Option<String>,
|
||||
#[arg(long)]
|
||||
amount_in: u128,
|
||||
#[arg(long)]
|
||||
@ -59,14 +94,35 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Only public execution allowed.
|
||||
AddLiquidity {
|
||||
/// `user_holding_a` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_a_label",
|
||||
required_unless_present = "user_holding_a_label"
|
||||
)]
|
||||
user_holding_a: Option<String>,
|
||||
/// User holding A account label (alternative to --user-holding-a).
|
||||
#[arg(long, conflicts_with = "user_holding_a")]
|
||||
user_holding_a_label: Option<String>,
|
||||
/// `user_holding_b` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_b: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_b_label",
|
||||
required_unless_present = "user_holding_b_label"
|
||||
)]
|
||||
user_holding_b: Option<String>,
|
||||
/// User holding B account label (alternative to --user-holding-b).
|
||||
#[arg(long, conflicts_with = "user_holding_b")]
|
||||
user_holding_b_label: Option<String>,
|
||||
/// `user_holding_lp` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_lp: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_lp_label",
|
||||
required_unless_present = "user_holding_lp_label"
|
||||
)]
|
||||
user_holding_lp: Option<String>,
|
||||
/// User holding LP account label (alternative to --user-holding-lp).
|
||||
#[arg(long, conflicts_with = "user_holding_lp")]
|
||||
user_holding_lp_label: Option<String>,
|
||||
#[arg(long)]
|
||||
min_amount_lp: u128,
|
||||
#[arg(long)]
|
||||
@ -81,14 +137,35 @@ pub enum AmmProgramAgnosticSubcommand {
|
||||
/// Only public execution allowed.
|
||||
RemoveLiquidity {
|
||||
/// `user_holding_a` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_a: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_a_label",
|
||||
required_unless_present = "user_holding_a_label"
|
||||
)]
|
||||
user_holding_a: Option<String>,
|
||||
/// User holding A account label (alternative to --user-holding-a).
|
||||
#[arg(long, conflicts_with = "user_holding_a")]
|
||||
user_holding_a_label: Option<String>,
|
||||
/// `user_holding_b` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_b: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_b_label",
|
||||
required_unless_present = "user_holding_b_label"
|
||||
)]
|
||||
user_holding_b: Option<String>,
|
||||
/// User holding B account label (alternative to --user-holding-b).
|
||||
#[arg(long, conflicts_with = "user_holding_b")]
|
||||
user_holding_b_label: Option<String>,
|
||||
/// `user_holding_lp` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
user_holding_lp: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "user_holding_lp_label",
|
||||
required_unless_present = "user_holding_lp_label"
|
||||
)]
|
||||
user_holding_lp: Option<String>,
|
||||
/// User holding LP account label (alternative to --user-holding-lp).
|
||||
#[arg(long, conflicts_with = "user_holding_lp")]
|
||||
user_holding_lp_label: Option<String>,
|
||||
#[arg(long)]
|
||||
balance_lp: u128,
|
||||
#[arg(long)]
|
||||
@ -106,11 +183,32 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
match self {
|
||||
Self::New {
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
user_holding_lp,
|
||||
user_holding_lp_label,
|
||||
balance_a,
|
||||
balance_b,
|
||||
} => {
|
||||
let user_holding_a = resolve_id_or_label(
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_b = resolve_id_or_label(
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_lp = resolve_id_or_label(
|
||||
user_holding_lp,
|
||||
user_holding_lp_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
@ -152,11 +250,25 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
}
|
||||
Self::Swap {
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
amount_in,
|
||||
min_amount_out,
|
||||
token_definition,
|
||||
} => {
|
||||
let user_holding_a = resolve_id_or_label(
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_b = resolve_id_or_label(
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
@ -187,12 +299,33 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
}
|
||||
Self::AddLiquidity {
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
user_holding_lp,
|
||||
user_holding_lp_label,
|
||||
min_amount_lp,
|
||||
max_amount_a,
|
||||
max_amount_b,
|
||||
} => {
|
||||
let user_holding_a = resolve_id_or_label(
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_b = resolve_id_or_label(
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_lp = resolve_id_or_label(
|
||||
user_holding_lp,
|
||||
user_holding_lp_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
@ -235,12 +368,33 @@ impl WalletSubcommand for AmmProgramAgnosticSubcommand {
|
||||
}
|
||||
Self::RemoveLiquidity {
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
user_holding_lp,
|
||||
user_holding_lp_label,
|
||||
balance_lp,
|
||||
min_amount_a,
|
||||
min_amount_b,
|
||||
} => {
|
||||
let user_holding_a = resolve_id_or_label(
|
||||
user_holding_a,
|
||||
user_holding_a_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_b = resolve_id_or_label(
|
||||
user_holding_b,
|
||||
user_holding_b_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let user_holding_lp = resolve_id_or_label(
|
||||
user_holding_lp,
|
||||
user_holding_lp_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (user_holding_a, user_holding_a_privacy) =
|
||||
parse_addr_with_privacy_prefix(&user_holding_a)?;
|
||||
let (user_holding_b, user_holding_b_privacy) =
|
||||
|
||||
@ -7,7 +7,10 @@ use crate::{
|
||||
AccDecodeData::Decode,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
helperfunctions::{
|
||||
AccountPrivacyKind, parse_addr_with_privacy_prefix, resolve_account_label,
|
||||
resolve_id_or_label,
|
||||
},
|
||||
program_facades::native_token_transfer::NativeTokenTransfer,
|
||||
};
|
||||
|
||||
@ -17,8 +20,15 @@ pub enum AuthTransferSubcommand {
|
||||
/// Initialize account under authenticated transfer program.
|
||||
Init {
|
||||
/// `account_id` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
account_id: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "account_label",
|
||||
required_unless_present = "account_label"
|
||||
)]
|
||||
account_id: Option<String>,
|
||||
/// Account label (alternative to --account-id).
|
||||
#[arg(long, conflicts_with = "account_id")]
|
||||
account_label: Option<String>,
|
||||
},
|
||||
/// Send native tokens from one account to another with variable privacy.
|
||||
///
|
||||
@ -28,11 +38,21 @@ pub enum AuthTransferSubcommand {
|
||||
/// First is used for owned accounts, second otherwise.
|
||||
Send {
|
||||
/// from - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
from: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "from_label",
|
||||
required_unless_present = "from_label"
|
||||
)]
|
||||
from: Option<String>,
|
||||
/// From account label (alternative to --from).
|
||||
#[arg(long, conflicts_with = "from")]
|
||||
from_label: Option<String>,
|
||||
/// to - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
#[arg(long, conflicts_with = "to_label")]
|
||||
to: Option<String>,
|
||||
/// To account label (alternative to --to).
|
||||
#[arg(long, conflicts_with = "to")]
|
||||
to_label: Option<String>,
|
||||
/// `to_npk` - valid 32 byte hex string.
|
||||
#[arg(long)]
|
||||
to_npk: Option<String>,
|
||||
@ -51,8 +71,17 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
wallet_core: &mut WalletCore,
|
||||
) -> Result<SubcommandReturnValue> {
|
||||
match self {
|
||||
Self::Init { account_id } => {
|
||||
let (account_id, addr_privacy) = parse_addr_with_privacy_prefix(&account_id)?;
|
||||
Self::Init {
|
||||
account_id,
|
||||
account_label,
|
||||
} => {
|
||||
let resolved = resolve_id_or_label(
|
||||
account_id,
|
||||
account_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (account_id, addr_privacy) = parse_addr_with_privacy_prefix(&resolved)?;
|
||||
|
||||
match addr_privacy {
|
||||
AccountPrivacyKind::Public => {
|
||||
@ -98,11 +127,30 @@ impl WalletSubcommand for AuthTransferSubcommand {
|
||||
}
|
||||
Self::Send {
|
||||
from,
|
||||
from_label,
|
||||
to,
|
||||
to_label,
|
||||
to_npk,
|
||||
to_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let from = resolve_id_or_label(
|
||||
from,
|
||||
from_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let to = match (to, to_label) {
|
||||
(v, None) => v,
|
||||
(None, Some(label)) => Some(resolve_account_label(
|
||||
&label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?),
|
||||
(Some(_), Some(_)) => {
|
||||
anyhow::bail!("Provide only one of --to or --to-label")
|
||||
}
|
||||
};
|
||||
let underlying_subcommand = match (to, to_npk, to_vpk) {
|
||||
(None, None, None) => {
|
||||
anyhow::bail!(
|
||||
|
||||
@ -7,7 +7,7 @@ use crate::{
|
||||
AccDecodeData::Decode,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix, resolve_id_or_label},
|
||||
program_facades::pinata::Pinata,
|
||||
};
|
||||
|
||||
@ -17,8 +17,15 @@ pub enum PinataProgramAgnosticSubcommand {
|
||||
/// Claim pinata.
|
||||
Claim {
|
||||
/// to - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
to: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "to_label",
|
||||
required_unless_present = "to_label"
|
||||
)]
|
||||
to: Option<String>,
|
||||
/// To account label (alternative to --to).
|
||||
#[arg(long, conflicts_with = "to")]
|
||||
to_label: Option<String>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -28,7 +35,13 @@ impl WalletSubcommand for PinataProgramAgnosticSubcommand {
|
||||
wallet_core: &mut WalletCore,
|
||||
) -> Result<SubcommandReturnValue> {
|
||||
let underlying_subcommand = match self {
|
||||
Self::Claim { to } => {
|
||||
Self::Claim { to, to_label } => {
|
||||
let to = resolve_id_or_label(
|
||||
to,
|
||||
to_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (to, to_addr_privacy) = parse_addr_with_privacy_prefix(&to)?;
|
||||
|
||||
match to_addr_privacy {
|
||||
|
||||
@ -7,7 +7,10 @@ use crate::{
|
||||
AccDecodeData::Decode,
|
||||
WalletCore,
|
||||
cli::{SubcommandReturnValue, WalletSubcommand},
|
||||
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
|
||||
helperfunctions::{
|
||||
AccountPrivacyKind, parse_addr_with_privacy_prefix, resolve_account_label,
|
||||
resolve_id_or_label,
|
||||
},
|
||||
program_facades::token::Token,
|
||||
};
|
||||
|
||||
@ -17,11 +20,25 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
/// Produce a new token.
|
||||
New {
|
||||
/// `definition_account_id` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
definition_account_id: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "definition_account_label",
|
||||
required_unless_present = "definition_account_label"
|
||||
)]
|
||||
definition_account_id: Option<String>,
|
||||
/// Definition account label (alternative to --definition-account-id).
|
||||
#[arg(long, conflicts_with = "definition_account_id")]
|
||||
definition_account_label: Option<String>,
|
||||
/// `supply_account_id` - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
supply_account_id: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "supply_account_label",
|
||||
required_unless_present = "supply_account_label"
|
||||
)]
|
||||
supply_account_id: Option<String>,
|
||||
/// Supply account label (alternative to --supply-account-id).
|
||||
#[arg(long, conflicts_with = "supply_account_id")]
|
||||
supply_account_label: Option<String>,
|
||||
#[arg(short, long)]
|
||||
name: String,
|
||||
#[arg(short, long)]
|
||||
@ -35,11 +52,21 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
/// First is used for owned accounts, second otherwise.
|
||||
Send {
|
||||
/// from - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
from: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "from_label",
|
||||
required_unless_present = "from_label"
|
||||
)]
|
||||
from: Option<String>,
|
||||
/// From account label (alternative to --from).
|
||||
#[arg(long, conflicts_with = "from")]
|
||||
from_label: Option<String>,
|
||||
/// to - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
#[arg(long, conflicts_with = "to_label")]
|
||||
to: Option<String>,
|
||||
/// To account label (alternative to --to).
|
||||
#[arg(long, conflicts_with = "to")]
|
||||
to_label: Option<String>,
|
||||
/// `to_npk` - valid 32 byte hex string.
|
||||
#[arg(long)]
|
||||
to_npk: Option<String>,
|
||||
@ -58,11 +85,25 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
/// we can not modify foreign accounts.
|
||||
Burn {
|
||||
/// definition - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
definition: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "definition_label",
|
||||
required_unless_present = "definition_label"
|
||||
)]
|
||||
definition: Option<String>,
|
||||
/// Definition account label (alternative to --definition).
|
||||
#[arg(long, conflicts_with = "definition")]
|
||||
definition_label: Option<String>,
|
||||
/// holder - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
holder: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "holder_label",
|
||||
required_unless_present = "holder_label"
|
||||
)]
|
||||
holder: Option<String>,
|
||||
/// Holder account label (alternative to --holder).
|
||||
#[arg(long, conflicts_with = "holder")]
|
||||
holder_label: Option<String>,
|
||||
/// amount - amount of balance to burn.
|
||||
#[arg(long)]
|
||||
amount: u128,
|
||||
@ -77,11 +118,21 @@ pub enum TokenProgramAgnosticSubcommand {
|
||||
/// First is used for owned accounts, second otherwise.
|
||||
Mint {
|
||||
/// definition - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
definition: String,
|
||||
#[arg(
|
||||
long,
|
||||
conflicts_with = "definition_label",
|
||||
required_unless_present = "definition_label"
|
||||
)]
|
||||
definition: Option<String>,
|
||||
/// Definition account label (alternative to --definition).
|
||||
#[arg(long, conflicts_with = "definition")]
|
||||
definition_label: Option<String>,
|
||||
/// holder - valid 32 byte base58 string with privacy prefix.
|
||||
#[arg(long)]
|
||||
#[arg(long, conflicts_with = "holder_label")]
|
||||
holder: Option<String>,
|
||||
/// Holder account label (alternative to --holder).
|
||||
#[arg(long, conflicts_with = "holder")]
|
||||
holder_label: Option<String>,
|
||||
/// `holder_npk` - valid 32 byte hex string.
|
||||
#[arg(long)]
|
||||
holder_npk: Option<String>,
|
||||
@ -102,10 +153,24 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
match self {
|
||||
Self::New {
|
||||
definition_account_id,
|
||||
definition_account_label,
|
||||
supply_account_id,
|
||||
supply_account_label,
|
||||
name,
|
||||
total_supply,
|
||||
} => {
|
||||
let definition_account_id = resolve_id_or_label(
|
||||
definition_account_id,
|
||||
definition_account_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let supply_account_id = resolve_id_or_label(
|
||||
supply_account_id,
|
||||
supply_account_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let (definition_account_id, definition_addr_privacy) =
|
||||
parse_addr_with_privacy_prefix(&definition_account_id)?;
|
||||
let (supply_account_id, supply_addr_privacy) =
|
||||
@ -158,11 +223,30 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
}
|
||||
Self::Send {
|
||||
from,
|
||||
from_label,
|
||||
to,
|
||||
to_label,
|
||||
to_npk,
|
||||
to_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let from = resolve_id_or_label(
|
||||
from,
|
||||
from_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let to = match (to, to_label) {
|
||||
(v, None) => v,
|
||||
(None, Some(label)) => Some(resolve_account_label(
|
||||
&label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?),
|
||||
(Some(_), Some(_)) => {
|
||||
anyhow::bail!("Provide only one of --to or --to-label")
|
||||
}
|
||||
};
|
||||
let underlying_subcommand = match (to, to_npk, to_vpk) {
|
||||
(None, None, None) => {
|
||||
anyhow::bail!(
|
||||
@ -248,9 +332,23 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
}
|
||||
Self::Burn {
|
||||
definition,
|
||||
definition_label,
|
||||
holder,
|
||||
holder_label,
|
||||
amount,
|
||||
} => {
|
||||
let definition = resolve_id_or_label(
|
||||
definition,
|
||||
definition_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let holder = resolve_id_or_label(
|
||||
holder,
|
||||
holder_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let underlying_subcommand = {
|
||||
let (definition, definition_privacy) =
|
||||
parse_addr_with_privacy_prefix(&definition)?;
|
||||
@ -300,11 +398,30 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
|
||||
}
|
||||
Self::Mint {
|
||||
definition,
|
||||
definition_label,
|
||||
holder,
|
||||
holder_label,
|
||||
holder_npk,
|
||||
holder_vpk,
|
||||
amount,
|
||||
} => {
|
||||
let definition = resolve_id_or_label(
|
||||
definition,
|
||||
definition_label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?;
|
||||
let holder = match (holder, holder_label) {
|
||||
(v, None) => v,
|
||||
(None, Some(label)) => Some(resolve_account_label(
|
||||
&label,
|
||||
&wallet_core.storage.labels,
|
||||
&wallet_core.storage.user_data,
|
||||
)?),
|
||||
(Some(_), Some(_)) => {
|
||||
anyhow::bail!("Provide only one of --holder or --holder-label")
|
||||
}
|
||||
};
|
||||
let underlying_subcommand = match (holder, holder_npk, holder_vpk) {
|
||||
(None, None, None) => {
|
||||
anyhow::bail!(
|
||||
|
||||
@ -49,6 +49,66 @@ impl From<Account> for HumanReadableAccount {
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve an account id-or-label pair to a `Privacy/id` string.
|
||||
///
|
||||
/// Exactly one of `id` or `label` must be `Some`. If `id` is provided it is
|
||||
/// returned as-is; if `label` is provided it is resolved via
|
||||
/// [`resolve_account_label`]. Any other combination returns an error.
|
||||
pub fn resolve_id_or_label(
|
||||
id: Option<String>,
|
||||
label: Option<String>,
|
||||
labels: &HashMap<String, Label>,
|
||||
user_data: &NSSAUserData,
|
||||
) -> Result<String> {
|
||||
match (id, label) {
|
||||
(Some(id), None) => Ok(id),
|
||||
(None, Some(label)) => resolve_account_label(&label, labels, user_data),
|
||||
_ => anyhow::bail!("provide exactly one of account id or account label"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve an account label to its full `Privacy/id` string representation.
|
||||
///
|
||||
/// Looks up the label in the labels map and determines whether the account is
|
||||
/// public or private by checking the user data key trees.
|
||||
pub fn resolve_account_label(
|
||||
label: &str,
|
||||
labels: &HashMap<String, Label>,
|
||||
user_data: &NSSAUserData,
|
||||
) -> Result<String> {
|
||||
let account_id_str = labels
|
||||
.iter()
|
||||
.find(|(_, l)| l.to_string() == label)
|
||||
.map(|(k, _)| k.clone())
|
||||
.ok_or_else(|| anyhow::anyhow!("No account found with label '{label}'"))?;
|
||||
|
||||
let account_id: nssa::AccountId = account_id_str.parse()?;
|
||||
|
||||
let privacy = if user_data
|
||||
.public_key_tree
|
||||
.account_id_map
|
||||
.contains_key(&account_id)
|
||||
|| user_data
|
||||
.default_pub_account_signing_keys
|
||||
.contains_key(&account_id)
|
||||
{
|
||||
"Public"
|
||||
} else if user_data
|
||||
.private_key_tree
|
||||
.account_id_map
|
||||
.contains_key(&account_id)
|
||||
|| user_data
|
||||
.default_user_private_accounts
|
||||
.contains_key(&account_id)
|
||||
{
|
||||
"Private"
|
||||
} else {
|
||||
anyhow::bail!("Account with label '{label}' not found in wallet");
|
||||
};
|
||||
|
||||
Ok(format!("{privacy}/{account_id_str}"))
|
||||
}
|
||||
|
||||
/// Get home dir for wallet. Env var `NSSA_WALLET_HOME_DIR` must be set before execution to succeed.
|
||||
fn get_home_nssa_var() -> Result<PathBuf> {
|
||||
Ok(PathBuf::from_str(&std::env::var(HOME_DIR_ENV_VAR)?)?)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user