mirror of
https://github.com/logos-blockchain/logos-execution-zone.git
synced 2026-03-24 03:03:09 +00:00
Merge 86bfa20af9c13fdb952dd69b9343842f57d5ea13 into fb083ce91ec10487fc17137a48c47f4322f9c768
This commit is contained in:
commit
7f8225f566
@ -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 "$@"
|
||||
|
||||
@ -113,9 +113,12 @@ async fn amm_public() -> Result<()> {
|
||||
|
||||
// Create new token
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_public_account_id(definition_account_id_1),
|
||||
supply_account_id: format_public_account_id(supply_account_id_1),
|
||||
name: "A NAM1".to_owned(),
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id_1)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id_1)),
|
||||
supply_account_label: None,
|
||||
name: "A NAM1".to_string(),
|
||||
|
||||
total_supply: 37,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
@ -124,8 +127,10 @@ async fn amm_public() -> Result<()> {
|
||||
|
||||
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_1`
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_public_account_id(supply_account_id_1),
|
||||
from: Some(format_public_account_id(supply_account_id_1)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(recipient_account_id_1)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 7,
|
||||
@ -137,9 +142,12 @@ async fn amm_public() -> Result<()> {
|
||||
|
||||
// Create new token
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_public_account_id(definition_account_id_2),
|
||||
supply_account_id: format_public_account_id(supply_account_id_2),
|
||||
name: "A NAM2".to_owned(),
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id_2)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id_2)),
|
||||
supply_account_label: None,
|
||||
name: "A NAM2".to_string(),
|
||||
|
||||
total_supply: 37,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
@ -148,8 +156,10 @@ async fn amm_public() -> Result<()> {
|
||||
|
||||
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id_2`
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_public_account_id(supply_account_id_2),
|
||||
from: Some(format_public_account_id(supply_account_id_2)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(recipient_account_id_2)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 7,
|
||||
@ -181,9 +191,12 @@ async fn amm_public() -> Result<()> {
|
||||
|
||||
// Send creation tx
|
||||
let subcommand = AmmProgramAgnosticSubcommand::New {
|
||||
user_holding_a: format_public_account_id(recipient_account_id_1),
|
||||
user_holding_b: format_public_account_id(recipient_account_id_2),
|
||||
user_holding_lp: format_public_account_id(user_holding_lp),
|
||||
user_holding_a: Some(format_public_account_id(recipient_account_id_1)),
|
||||
user_holding_a_label: None,
|
||||
user_holding_b: Some(format_public_account_id(recipient_account_id_2)),
|
||||
user_holding_b_label: None,
|
||||
user_holding_lp: Some(format_public_account_id(user_holding_lp)),
|
||||
user_holding_lp_label: None,
|
||||
balance_a: 3,
|
||||
balance_b: 3,
|
||||
};
|
||||
@ -224,8 +237,10 @@ async fn amm_public() -> Result<()> {
|
||||
// Make swap
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::Swap {
|
||||
user_holding_a: format_public_account_id(recipient_account_id_1),
|
||||
user_holding_b: format_public_account_id(recipient_account_id_2),
|
||||
user_holding_a: Some(format_public_account_id(recipient_account_id_1)),
|
||||
user_holding_a_label: None,
|
||||
user_holding_b: Some(format_public_account_id(recipient_account_id_2)),
|
||||
user_holding_b_label: None,
|
||||
amount_in: 2,
|
||||
min_amount_out: 1,
|
||||
token_definition: definition_account_id_1.to_string(),
|
||||
@ -267,8 +282,10 @@ async fn amm_public() -> Result<()> {
|
||||
// Make swap
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::Swap {
|
||||
user_holding_a: format_public_account_id(recipient_account_id_1),
|
||||
user_holding_b: format_public_account_id(recipient_account_id_2),
|
||||
user_holding_a: Some(format_public_account_id(recipient_account_id_1)),
|
||||
user_holding_a_label: None,
|
||||
user_holding_b: Some(format_public_account_id(recipient_account_id_2)),
|
||||
user_holding_b_label: None,
|
||||
amount_in: 2,
|
||||
min_amount_out: 1,
|
||||
token_definition: definition_account_id_2.to_string(),
|
||||
@ -310,9 +327,12 @@ async fn amm_public() -> Result<()> {
|
||||
// Add liquidity
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::AddLiquidity {
|
||||
user_holding_a: format_public_account_id(recipient_account_id_1),
|
||||
user_holding_b: format_public_account_id(recipient_account_id_2),
|
||||
user_holding_lp: format_public_account_id(user_holding_lp),
|
||||
user_holding_a: Some(format_public_account_id(recipient_account_id_1)),
|
||||
user_holding_a_label: None,
|
||||
user_holding_b: Some(format_public_account_id(recipient_account_id_2)),
|
||||
user_holding_b_label: None,
|
||||
user_holding_lp: Some(format_public_account_id(user_holding_lp)),
|
||||
user_holding_lp_label: None,
|
||||
min_amount_lp: 1,
|
||||
max_amount_a: 2,
|
||||
max_amount_b: 2,
|
||||
@ -354,9 +374,12 @@ async fn amm_public() -> Result<()> {
|
||||
// Remove liquidity
|
||||
|
||||
let subcommand = AmmProgramAgnosticSubcommand::RemoveLiquidity {
|
||||
user_holding_a: format_public_account_id(recipient_account_id_1),
|
||||
user_holding_b: format_public_account_id(recipient_account_id_2),
|
||||
user_holding_lp: format_public_account_id(user_holding_lp),
|
||||
user_holding_a: Some(format_public_account_id(recipient_account_id_1)),
|
||||
user_holding_a_label: None,
|
||||
user_holding_b: Some(format_public_account_id(recipient_account_id_2)),
|
||||
user_holding_b_label: None,
|
||||
user_holding_lp: Some(format_public_account_id(user_holding_lp)),
|
||||
user_holding_lp_label: None,
|
||||
balance_lp: 2,
|
||||
min_amount_a: 1,
|
||||
min_amount_b: 1,
|
||||
@ -397,3 +420,188 @@ async fn amm_public() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn amm_new_pool_using_labels() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Create token 1 accounts
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: definition_account_id_1,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: supply_account_id_1,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create holding_a with a label
|
||||
let holding_a_label = "amm-holding-a-label".to_owned();
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: holding_a_id,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: Some(holding_a_label.clone()),
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create token 2 accounts
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: definition_account_id_2,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: supply_account_id_2,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create holding_b with a label
|
||||
let holding_b_label = "amm-holding-b-label".to_owned();
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: holding_b_id,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: Some(holding_b_label.clone()),
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create holding_lp with a label
|
||||
let holding_lp_label = "amm-holding-lp-label".to_owned();
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: holding_lp_id,
|
||||
} = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: Some(holding_lp_label.clone()),
|
||||
})),
|
||||
)
|
||||
.await?
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create token 1 and distribute to holding_a
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id_1)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id_1)),
|
||||
supply_account_label: None,
|
||||
name: "TOKEN1".to_string(),
|
||||
total_supply: 10,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: Some(format_public_account_id(supply_account_id_1)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(holding_a_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 5,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Create token 2 and distribute to holding_b
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id_2)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id_2)),
|
||||
supply_account_label: None,
|
||||
name: "TOKEN2".to_string(),
|
||||
total_supply: 10,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: Some(format_public_account_id(supply_account_id_2)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(holding_b_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 5,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Create AMM pool using account labels instead of IDs
|
||||
let subcommand = AmmProgramAgnosticSubcommand::New {
|
||||
user_holding_a: None,
|
||||
user_holding_a_label: Some(holding_a_label),
|
||||
user_holding_b: None,
|
||||
user_holding_b_label: Some(holding_b_label),
|
||||
user_holding_lp: None,
|
||||
user_holding_lp_label: Some(holding_lp_label),
|
||||
balance_a: 3,
|
||||
balance_b: 3,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::AMM(subcommand)).await?;
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let holding_lp_acc = ctx.sequencer_client().get_account(holding_lp_id).await?;
|
||||
|
||||
// LP balance should be 3 (geometric mean of 3, 3)
|
||||
assert_eq!(
|
||||
u128::from_le_bytes(holding_lp_acc.data[33..].try_into().unwrap()),
|
||||
3
|
||||
);
|
||||
|
||||
info!("Successfully created AMM pool using account labels");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -24,8 +24,10 @@ async fn private_transfer_to_owned_account() -> Result<()> {
|
||||
let to: AccountId = ctx.existing_private_accounts()[1];
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -63,8 +65,10 @@ async fn private_transfer_to_foreign_account() -> Result<()> {
|
||||
let to_vpk = Secp256k1Point::from_scalar(to_npk.0);
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: None,
|
||||
to_label: None,
|
||||
to_npk: Some(to_npk_string),
|
||||
to_vpk: Some(hex::encode(to_vpk.0)),
|
||||
amount: 100,
|
||||
@ -87,7 +91,7 @@ async fn private_transfer_to_foreign_account() -> Result<()> {
|
||||
assert_eq!(tx.message.new_commitments[0], new_commitment1);
|
||||
|
||||
assert_eq!(tx.message.new_commitments.len(), 2);
|
||||
for commitment in tx.message.new_commitments {
|
||||
for commitment in tx.message.new_commitments.into_iter() {
|
||||
assert!(verify_commitment_is_in_state(commitment, ctx.sequencer_client()).await);
|
||||
}
|
||||
|
||||
@ -111,8 +115,10 @@ async fn deshielded_transfer_to_public_account() -> Result<()> {
|
||||
assert_eq!(from_acc.balance, 10000);
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(to)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -174,8 +180,10 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
|
||||
|
||||
// Send to this account using claiming path (using npk and vpk instead of account ID)
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: None,
|
||||
to_label: None,
|
||||
to_npk: Some(hex::encode(to_keys.nullifier_public_key.0)),
|
||||
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||
amount: 100,
|
||||
@ -199,7 +207,7 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
|
||||
assert_eq!(tx.message.new_commitments[0], new_commitment1);
|
||||
|
||||
assert_eq!(tx.message.new_commitments.len(), 2);
|
||||
for commitment in tx.message.new_commitments {
|
||||
for commitment in tx.message.new_commitments.into_iter() {
|
||||
assert!(verify_commitment_is_in_state(commitment, ctx.sequencer_client()).await);
|
||||
}
|
||||
|
||||
@ -222,8 +230,10 @@ async fn shielded_transfer_to_owned_private_account() -> Result<()> {
|
||||
let to: AccountId = ctx.existing_private_accounts()[1];
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(from),
|
||||
from: Some(format_public_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -264,8 +274,10 @@ async fn shielded_transfer_to_foreign_account() -> Result<()> {
|
||||
let from: AccountId = ctx.existing_public_accounts()[0];
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(from),
|
||||
from: Some(format_public_account_id(from)),
|
||||
from_label: None,
|
||||
to: None,
|
||||
to_label: None,
|
||||
to_npk: Some(to_npk_string),
|
||||
to_vpk: Some(hex::encode(to_vpk.0)),
|
||||
amount: 100,
|
||||
@ -334,8 +346,10 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
|
||||
|
||||
// Send transfer using nullifier and viewing public keys
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: None,
|
||||
to_label: None,
|
||||
to_npk: Some(hex::encode(to_keys.nullifier_public_key.0)),
|
||||
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||
amount: 100,
|
||||
@ -354,7 +368,7 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
|
||||
|
||||
// Verify commitments are in state
|
||||
assert_eq!(tx.message.new_commitments.len(), 2);
|
||||
for commitment in tx.message.new_commitments {
|
||||
for commitment in tx.message.new_commitments.into_iter() {
|
||||
assert!(verify_commitment_is_in_state(commitment, ctx.sequencer_client()).await);
|
||||
}
|
||||
|
||||
@ -383,7 +397,8 @@ async fn initialize_private_account() -> Result<()> {
|
||||
};
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
|
||||
account_id: format_private_account_id(account_id),
|
||||
account_id: Some(format_private_account_id(account_id)),
|
||||
account_label: None,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
@ -415,3 +430,100 @@ async fn initialize_private_account() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn private_transfer_using_from_label() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
let to: AccountId = ctx.existing_private_accounts()[1];
|
||||
|
||||
// Assign a label to the sender account
|
||||
let label = "private-sender-label".to_owned();
|
||||
let command = Command::Account(AccountSubcommand::Label {
|
||||
account_id: Some(format_private_account_id(from)),
|
||||
account_label: None,
|
||||
label: label.clone(),
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
// Send using the label instead of account ID
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: None,
|
||||
from_label: Some(label),
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let new_commitment1 = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(from)
|
||||
.context("Failed to get private account commitment for sender")?;
|
||||
assert!(verify_commitment_is_in_state(new_commitment1, ctx.sequencer_client()).await);
|
||||
|
||||
let new_commitment2 = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(to)
|
||||
.context("Failed to get private account commitment for receiver")?;
|
||||
assert!(verify_commitment_is_in_state(new_commitment2, ctx.sequencer_client()).await);
|
||||
|
||||
info!("Successfully transferred privately using from_label");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn initialize_private_account_using_label() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Create a new private account with a label
|
||||
let label = "init-private-label".to_owned();
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: Some(label.clone()),
|
||||
}));
|
||||
let result = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
let SubcommandReturnValue::RegisterAccount { account_id } = result else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Initialize using the label instead of account ID
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
|
||||
account_id: None,
|
||||
account_label: Some(label),
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let command = Command::Account(AccountSubcommand::SyncPrivate {});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
let new_commitment = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(account_id)
|
||||
.context("Failed to get private account commitment")?;
|
||||
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
|
||||
|
||||
let account = ctx
|
||||
.wallet()
|
||||
.get_account_private(account_id)
|
||||
.context("Failed to get private account")?;
|
||||
|
||||
assert_eq!(
|
||||
account.program_owner,
|
||||
Program::authenticated_transfer_program().id()
|
||||
);
|
||||
|
||||
info!("Successfully initialized private account using label");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -17,8 +17,10 @@ async fn successful_transfer_to_existing_account() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -73,8 +75,10 @@ pub async fn successful_transfer_to_new_account() -> Result<()> {
|
||||
.expect("Failed to find newly created account in the wallet storage");
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(new_persistent_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -109,8 +113,10 @@ async fn failed_transfer_with_insufficient_balance() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 1_000_000,
|
||||
@ -147,8 +153,10 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
|
||||
|
||||
// First transfer
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -179,8 +187,10 @@ async fn two_consecutive_successful_transfers() -> Result<()> {
|
||||
|
||||
// Second transfer
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -226,7 +236,8 @@ async fn initialize_public_account() -> Result<()> {
|
||||
};
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
|
||||
account_id: format_public_account_id(account_id),
|
||||
account_id: Some(format_public_account_id(account_id)),
|
||||
account_label: None,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
@ -245,3 +256,97 @@ async fn initialize_public_account() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn successful_transfer_using_from_label() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Assign a label to the sender account
|
||||
let label = "sender-label".to_owned();
|
||||
let command = Command::Account(AccountSubcommand::Label {
|
||||
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
account_label: None,
|
||||
label: label.clone(),
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
// Send using the label instead of account ID
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: None,
|
||||
from_label: Some(label),
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
info!("Checking correct balance move");
|
||||
let acc_1_balance = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(ctx.existing_public_accounts()[0])
|
||||
.await?;
|
||||
let acc_2_balance = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(ctx.existing_public_accounts()[1])
|
||||
.await?;
|
||||
|
||||
assert_eq!(acc_1_balance, 9900);
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
info!("Successfully transferred using from_label");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn successful_transfer_using_to_label() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Assign a label to the receiver account
|
||||
let label = "receiver-label".to_owned();
|
||||
let command = Command::Account(AccountSubcommand::Label {
|
||||
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
account_label: None,
|
||||
label: label.clone(),
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
// Send using the label for the recipient
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: None,
|
||||
to_label: Some(label),
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
info!("Checking correct balance move");
|
||||
let acc_1_balance = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(ctx.existing_public_accounts()[0])
|
||||
.await?;
|
||||
let acc_2_balance = ctx
|
||||
.sequencer_client()
|
||||
.get_account_balance(ctx.existing_public_accounts()[1])
|
||||
.await?;
|
||||
|
||||
assert_eq!(acc_1_balance, 9900);
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
info!("Successfully transferred using to_label");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
#![expect(
|
||||
clippy::shadow_unrelated,
|
||||
clippy::tests_outside_test_module,
|
||||
reason = "We don't care about these in tests"
|
||||
)]
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Result;
|
||||
use anyhow::{Context as _, Result};
|
||||
use indexer_service_rpc::RpcClient as _;
|
||||
use integration_tests::{TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_public_account_id};
|
||||
use integration_tests::{
|
||||
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_private_account_id,
|
||||
format_public_account_id, verify_commitment_is_in_state,
|
||||
};
|
||||
use log::info;
|
||||
use nssa::AccountId;
|
||||
use tokio::test;
|
||||
use wallet::cli::{Command, programs::native_token_transfer::AuthTransferSubcommand};
|
||||
|
||||
@ -83,8 +88,10 @@ async fn indexer_state_consistency() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -113,6 +120,38 @@ async fn indexer_state_consistency() -> Result<()> {
|
||||
assert_eq!(acc_1_balance, 9900);
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
let to: AccountId = ctx.existing_private_accounts()[1];
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let new_commitment1 = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(from)
|
||||
.context("Failed to get private account commitment for sender")?;
|
||||
assert!(verify_commitment_is_in_state(new_commitment1, ctx.sequencer_client()).await);
|
||||
|
||||
let new_commitment2 = ctx
|
||||
.wallet()
|
||||
.get_private_account_commitment(to)
|
||||
.context("Failed to get private account commitment for receiver")?;
|
||||
assert!(verify_commitment_is_in_state(new_commitment2, ctx.sequencer_client()).await);
|
||||
|
||||
info!("Successfully transferred privately to owned account");
|
||||
|
||||
// WAIT
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
||||
@ -147,3 +186,76 @@ async fn indexer_state_consistency() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn indexer_state_consistency_with_labels() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Assign labels to both accounts
|
||||
let from_label = "idx-sender-label".to_owned();
|
||||
let to_label_str = "idx-receiver-label".to_owned();
|
||||
|
||||
let label_cmd = Command::Account(wallet::cli::account::AccountSubcommand::Label {
|
||||
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
account_label: None,
|
||||
label: from_label.clone(),
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), label_cmd).await?;
|
||||
|
||||
let label_cmd = Command::Account(wallet::cli::account::AccountSubcommand::Label {
|
||||
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
|
||||
account_label: None,
|
||||
label: to_label_str.clone(),
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), label_cmd).await?;
|
||||
|
||||
// Send using labels instead of account IDs
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: None,
|
||||
from_label: Some(from_label),
|
||||
to: None,
|
||||
to_label: Some(to_label_str),
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
});
|
||||
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let acc_1_balance = sequencer_service_rpc::RpcClient::get_account_balance(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[0],
|
||||
)
|
||||
.await?;
|
||||
let acc_2_balance = sequencer_service_rpc::RpcClient::get_account_balance(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[1],
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_eq!(acc_1_balance, 9900);
|
||||
assert_eq!(acc_2_balance, 20100);
|
||||
|
||||
info!("Waiting for indexer to parse blocks");
|
||||
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
|
||||
|
||||
let acc1_ind_state = ctx
|
||||
.indexer_client()
|
||||
.get_account(ctx.existing_public_accounts()[0].into())
|
||||
.await
|
||||
.unwrap();
|
||||
let acc1_seq_state = sequencer_service_rpc::RpcClient::get_account(
|
||||
ctx.sequencer_client(),
|
||||
ctx.existing_public_accounts()[0],
|
||||
)
|
||||
.await?;
|
||||
|
||||
assert_eq!(acc1_ind_state, acc1_seq_state.into());
|
||||
|
||||
info!("Indexer state is consistent after label-based transfer");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -69,8 +69,10 @@ async fn sync_private_account_with_non_zero_chain_index() -> Result<()> {
|
||||
|
||||
// Send to this account using claiming path (using npk and vpk instead of account ID)
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: None,
|
||||
to_label: None,
|
||||
to_npk: Some(hex::encode(to_keys.nullifier_public_key.0)),
|
||||
to_vpk: Some(hex::encode(to_keys.viewing_public_key.0)),
|
||||
amount: 100,
|
||||
@ -143,8 +145,10 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
|
||||
// Send to first private account
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to_account_id1)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 100,
|
||||
@ -153,8 +157,10 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
|
||||
// Send to second private account
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(from),
|
||||
from: Some(format_private_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to_account_id2)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 101,
|
||||
@ -191,8 +197,10 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
|
||||
// Send to first public account
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(from),
|
||||
from: Some(format_public_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(to_account_id3)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 102,
|
||||
@ -201,8 +209,10 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
|
||||
// Send to second public account
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(from),
|
||||
from: Some(format_public_account_id(from)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(to_account_id4)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 103,
|
||||
@ -264,8 +274,10 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
|
||||
// Test that restored accounts can send transactions
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_private_account_id(to_account_id1),
|
||||
from: Some(format_private_account_id(to_account_id1)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(to_account_id2)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 10,
|
||||
@ -273,8 +285,10 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
|
||||
from: format_public_account_id(to_account_id3),
|
||||
from: Some(format_public_account_id(to_account_id3)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(to_account_id4)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: 11,
|
||||
|
||||
@ -52,7 +52,8 @@ async fn claim_pinata_to_uninitialized_public_account_fails_fast() -> Result<()>
|
||||
let claim_result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
|
||||
to: winner_account_id_formatted,
|
||||
to: Some(winner_account_id_formatted),
|
||||
to_label: None,
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
@ -106,7 +107,8 @@ async fn claim_pinata_to_uninitialized_private_account_fails_fast() -> Result<()
|
||||
let claim_result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
|
||||
to: winner_account_id_formatted,
|
||||
to: Some(winner_account_id_formatted),
|
||||
to_label: None,
|
||||
}),
|
||||
)
|
||||
.await;
|
||||
@ -137,7 +139,8 @@ async fn claim_pinata_to_existing_public_account() -> Result<()> {
|
||||
|
||||
let pinata_prize = 150;
|
||||
let command = Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
|
||||
to: format_public_account_id(ctx.existing_public_accounts()[0]),
|
||||
to: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
|
||||
to_label: None,
|
||||
});
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
@ -175,7 +178,10 @@ async fn claim_pinata_to_existing_private_account() -> Result<()> {
|
||||
|
||||
let pinata_prize = 150;
|
||||
let command = Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
|
||||
to: format_private_account_id(ctx.existing_private_accounts()[0]),
|
||||
to: Some(format_private_account_id(
|
||||
ctx.existing_private_accounts()[0],
|
||||
)),
|
||||
to_label: None,
|
||||
});
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
@ -239,7 +245,8 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
|
||||
|
||||
// Initialize account under auth transfer program
|
||||
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
|
||||
account_id: winner_account_id_formatted.clone(),
|
||||
account_id: Some(winner_account_id_formatted.clone()),
|
||||
account_label: None,
|
||||
});
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
@ -254,7 +261,8 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
|
||||
|
||||
// Claim pinata to the new private account
|
||||
let command = Command::Pinata(PinataProgramAgnosticSubcommand::Claim {
|
||||
to: winner_account_id_formatted,
|
||||
to: Some(winner_account_id_formatted),
|
||||
to_label: None,
|
||||
});
|
||||
|
||||
let pinata_balance_pre = ctx
|
||||
|
||||
@ -76,11 +76,13 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create new token
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_public_account_id(definition_account_id),
|
||||
supply_account_id: format_public_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name: name.clone(),
|
||||
total_supply,
|
||||
};
|
||||
@ -126,8 +128,10 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
// Transfer 7 tokens from supply_acc to recipient_account_id
|
||||
let transfer_amount = 7;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_public_account_id(supply_account_id),
|
||||
from: Some(format_public_account_id(supply_account_id)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(recipient_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
@ -171,8 +175,10 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
// Burn 3 tokens from recipient_acc
|
||||
let burn_amount = 3;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Burn {
|
||||
definition: format_public_account_id(definition_account_id),
|
||||
holder: format_public_account_id(recipient_account_id),
|
||||
definition: Some(format_public_account_id(definition_account_id)),
|
||||
definition_label: None,
|
||||
holder: Some(format_public_account_id(recipient_account_id)),
|
||||
holder_label: None,
|
||||
amount: burn_amount,
|
||||
};
|
||||
|
||||
@ -215,8 +221,10 @@ async fn create_and_transfer_public_token() -> Result<()> {
|
||||
// Mint 10 tokens at recipient_acc
|
||||
let mint_amount = 10;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Mint {
|
||||
definition: format_public_account_id(definition_account_id),
|
||||
definition: Some(format_public_account_id(definition_account_id)),
|
||||
definition_label: None,
|
||||
holder: Some(format_public_account_id(recipient_account_id)),
|
||||
holder_label: None,
|
||||
holder_npk: None,
|
||||
holder_vpk: None,
|
||||
amount: mint_amount,
|
||||
@ -316,11 +324,13 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create new token
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_public_account_id(definition_account_id),
|
||||
supply_account_id: format_private_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_private_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name: name.clone(),
|
||||
total_supply,
|
||||
};
|
||||
@ -356,8 +366,10 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
// Transfer 7 tokens from supply_acc to recipient_account_id
|
||||
let transfer_amount = 7;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_private_account_id(supply_account_id),
|
||||
from: Some(format_private_account_id(supply_account_id)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(recipient_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
@ -383,8 +395,10 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
// Burn 3 tokens from recipient_acc
|
||||
let burn_amount = 3;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Burn {
|
||||
definition: format_public_account_id(definition_account_id),
|
||||
holder: format_private_account_id(recipient_account_id),
|
||||
definition: Some(format_public_account_id(definition_account_id)),
|
||||
definition_label: None,
|
||||
holder: Some(format_private_account_id(recipient_account_id)),
|
||||
holder_label: None,
|
||||
amount: burn_amount,
|
||||
};
|
||||
|
||||
@ -472,11 +486,13 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create token with private definition
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_private_account_id(definition_account_id),
|
||||
supply_account_id: format_public_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_private_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name: name.clone(),
|
||||
total_supply,
|
||||
};
|
||||
@ -544,8 +560,10 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
// Mint to public account
|
||||
let mint_amount_public = 10;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Mint {
|
||||
definition: format_private_account_id(definition_account_id),
|
||||
definition: Some(format_private_account_id(definition_account_id)),
|
||||
definition_label: None,
|
||||
holder: Some(format_public_account_id(recipient_account_id_public)),
|
||||
holder_label: None,
|
||||
holder_npk: None,
|
||||
holder_vpk: None,
|
||||
amount: mint_amount_public,
|
||||
@ -590,8 +608,10 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
// Mint to private account
|
||||
let mint_amount_private = 5;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Mint {
|
||||
definition: format_private_account_id(definition_account_id),
|
||||
definition: Some(format_private_account_id(definition_account_id)),
|
||||
definition_label: None,
|
||||
holder: Some(format_private_account_id(recipient_account_id_private)),
|
||||
holder_label: None,
|
||||
holder_npk: None,
|
||||
holder_vpk: None,
|
||||
amount: mint_amount_private,
|
||||
@ -666,11 +686,13 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create token with both private definition and supply
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_private_account_id(definition_account_id),
|
||||
supply_account_id: format_private_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_private_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_private_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name,
|
||||
total_supply,
|
||||
};
|
||||
@ -728,8 +750,10 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
||||
// Transfer tokens
|
||||
let transfer_amount = 7;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_private_account_id(supply_account_id),
|
||||
from: Some(format_private_account_id(supply_account_id)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(recipient_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
@ -838,11 +862,13 @@ async fn shielded_token_transfer() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create token
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_public_account_id(definition_account_id),
|
||||
supply_account_id: format_public_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name,
|
||||
total_supply,
|
||||
};
|
||||
@ -855,8 +881,10 @@ async fn shielded_token_transfer() -> Result<()> {
|
||||
// Perform shielded transfer: public supply -> private recipient
|
||||
let transfer_amount = 7;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_public_account_id(supply_account_id),
|
||||
from: Some(format_public_account_id(supply_account_id)),
|
||||
from_label: None,
|
||||
to: Some(format_private_account_id(recipient_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
@ -960,11 +988,13 @@ async fn deshielded_token_transfer() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create token with private supply
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_public_account_id(definition_account_id),
|
||||
supply_account_id: format_private_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_private_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name,
|
||||
total_supply,
|
||||
};
|
||||
@ -977,8 +1007,10 @@ async fn deshielded_token_transfer() -> Result<()> {
|
||||
// Perform deshielded transfer: private supply -> public recipient
|
||||
let transfer_amount = 7;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: format_private_account_id(supply_account_id),
|
||||
from: Some(format_private_account_id(supply_account_id)),
|
||||
from_label: None,
|
||||
to: Some(format_public_account_id(recipient_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
@ -1066,11 +1098,13 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create token
|
||||
let name = "A NAME".to_owned();
|
||||
let name = "A NAME".to_string();
|
||||
let total_supply = 37;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: format_private_account_id(definition_account_id),
|
||||
supply_account_id: format_private_account_id(supply_account_id),
|
||||
definition_account_id: Some(format_private_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_private_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name,
|
||||
total_supply,
|
||||
};
|
||||
@ -1108,8 +1142,10 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
// Mint using claiming path (foreign account)
|
||||
let mint_amount = 9;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Mint {
|
||||
definition: format_private_account_id(definition_account_id),
|
||||
definition: Some(format_private_account_id(definition_account_id)),
|
||||
definition_label: None,
|
||||
holder: None,
|
||||
holder_label: None,
|
||||
holder_npk: Some(hex::encode(holder_keys.nullifier_public_key.0)),
|
||||
holder_vpk: Some(hex::encode(holder_keys.viewing_public_key.0)),
|
||||
amount: mint_amount,
|
||||
@ -1149,3 +1185,193 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn create_token_using_labels() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Create definition and supply accounts with labels
|
||||
let def_label = "token-definition-label".to_owned();
|
||||
let supply_label = "token-supply-label".to_owned();
|
||||
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: Some(def_label.clone()),
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: definition_account_id,
|
||||
} = result
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: Some(supply_label.clone()),
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: supply_account_id,
|
||||
} = result
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create token using account labels instead of IDs
|
||||
let name = "LABELED TOKEN".to_string();
|
||||
let total_supply = 100;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: None,
|
||||
definition_account_label: Some(def_label),
|
||||
supply_account_id: None,
|
||||
supply_account_label: Some(supply_label),
|
||||
name: name.clone(),
|
||||
total_supply,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let definition_acc = ctx
|
||||
.sequencer_client()
|
||||
.get_account(definition_account_id)
|
||||
.await?;
|
||||
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
|
||||
|
||||
assert_eq!(definition_acc.program_owner, Program::token().id());
|
||||
assert_eq!(
|
||||
token_definition,
|
||||
TokenDefinition::Fungible {
|
||||
name,
|
||||
total_supply,
|
||||
metadata_id: None
|
||||
}
|
||||
);
|
||||
|
||||
let supply_acc = ctx
|
||||
.sequencer_client()
|
||||
.get_account(supply_account_id)
|
||||
.await?;
|
||||
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
|
||||
assert_eq!(
|
||||
token_holding,
|
||||
TokenHolding::Fungible {
|
||||
definition_id: definition_account_id,
|
||||
balance: total_supply
|
||||
}
|
||||
);
|
||||
|
||||
info!("Successfully created token using definition and supply account labels");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
async fn transfer_token_using_from_label() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
// Create definition account
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: definition_account_id,
|
||||
} = result
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create supply account with a label
|
||||
let supply_label = "token-supply-sender".to_owned();
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: Some(supply_label.clone()),
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: supply_account_id,
|
||||
} = result
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create recipient account
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
account_id: recipient_account_id,
|
||||
} = result
|
||||
else {
|
||||
anyhow::bail!("Expected RegisterAccount return value");
|
||||
};
|
||||
|
||||
// Create token
|
||||
let total_supply = 50;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::New {
|
||||
definition_account_id: Some(format_public_account_id(definition_account_id)),
|
||||
definition_account_label: None,
|
||||
supply_account_id: Some(format_public_account_id(supply_account_id)),
|
||||
supply_account_label: None,
|
||||
name: "LABEL TEST TOKEN".to_string(),
|
||||
total_supply,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
// Transfer token using from_label instead of from
|
||||
let transfer_amount = 20;
|
||||
let subcommand = TokenProgramAgnosticSubcommand::Send {
|
||||
from: None,
|
||||
from_label: Some(supply_label),
|
||||
to: Some(format_public_account_id(recipient_account_id)),
|
||||
to_label: None,
|
||||
to_npk: None,
|
||||
to_vpk: None,
|
||||
amount: transfer_amount,
|
||||
};
|
||||
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
|
||||
|
||||
info!("Waiting for next block creation");
|
||||
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
|
||||
|
||||
let recipient_acc = ctx
|
||||
.sequencer_client()
|
||||
.get_account(recipient_account_id)
|
||||
.await?;
|
||||
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
|
||||
assert_eq!(
|
||||
token_holding,
|
||||
TokenHolding::Fungible {
|
||||
definition_id: definition_account_id,
|
||||
balance: transfer_amount
|
||||
}
|
||||
);
|
||||
|
||||
info!("Successfully transferred token using from_label");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -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