1485 lines
57 KiB
Rust
Raw Normal View History

2025-10-13 17:25:36 +03:00
use anyhow::Result;
use clap::Subcommand;
use common::transaction::NSSATransaction;
use nssa::AccountId;
2025-10-13 17:25:36 +03:00
2025-10-27 14:32:28 +02:00
use crate::{
2025-12-12 13:40:56 +02:00
AccDecodeData::Decode,
WalletCore,
cli::{SubcommandReturnValue, WalletSubcommand},
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
helperfunctions::{
AccountPrivacyKind, parse_addr_with_privacy_prefix, resolve_account_label,
resolve_id_or_label,
},
program_facades::token::Token,
2025-10-27 14:32:28 +02:00
};
2026-03-10 00:17:43 +03:00
/// Represents generic CLI subcommand for a wallet working with token program.
2025-10-27 14:32:28 +02:00
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramAgnosticSubcommand {
2026-03-10 00:17:43 +03:00
/// Produce a new token.
2025-10-27 14:32:28 +02:00
New {
2026-03-10 00:17:43 +03:00
/// `definition_account_id` - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[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>,
2026-03-10 00:17:43 +03:00
/// `supply_account_id` - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[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>,
2025-10-27 14:32:28 +02:00
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
2026-03-10 00:17:43 +03:00
/// Send tokens from one account to another with variable privacy.
2025-10-29 12:02:41 +02:00
///
2026-01-21 17:58:45 -05:00
/// If receiver is private, then `to` and (`to_npk` , `to_vpk`) is a mutually exclusive
2025-11-26 00:27:20 +03:00
/// patterns.
2025-10-29 12:02:41 +02:00
///
2025-11-26 00:27:20 +03:00
/// First is used for owned accounts, second otherwise.
2025-10-27 14:32:28 +02:00
Send {
2026-03-10 00:17:43 +03:00
/// from - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[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>,
2026-03-10 00:17:43 +03:00
/// to - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[arg(long, conflicts_with = "to_label")]
2025-10-27 14:32:28 +02:00
to: Option<String>,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
/// To account label (alternative to --to).
#[arg(long, conflicts_with = "to")]
to_label: Option<String>,
2026-03-10 00:17:43 +03:00
/// `to_npk` - valid 32 byte hex string.
2025-10-27 14:32:28 +02:00
#[arg(long)]
to_npk: Option<String>,
2026-03-10 00:17:43 +03:00
/// `to_vpk` - valid 33 byte hex string.
2025-10-27 14:32:28 +02:00
#[arg(long)]
2026-01-21 17:58:45 -05:00
to_vpk: Option<String>,
2026-03-10 00:17:43 +03:00
/// amount - amount of balance to move.
2025-10-27 14:32:28 +02:00
#[arg(long)]
amount: u128,
},
2025-12-11 14:46:16 +02:00
/// Burn tokens on `holder`, modify `definition`.
///
2026-03-10 00:17:43 +03:00
/// `holder` is owned.
2025-12-11 14:46:16 +02:00
///
2025-12-12 13:40:56 +02:00
/// Also if `definition` is private then it is owned, because
/// we can not modify foreign accounts.
2025-12-11 14:46:16 +02:00
Burn {
2026-03-10 00:17:43 +03:00
/// definition - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[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>,
2026-03-10 00:17:43 +03:00
/// holder - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[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>,
2026-03-10 00:17:43 +03:00
/// amount - amount of balance to burn.
2025-12-11 14:46:16 +02:00
#[arg(long)]
amount: u128,
},
/// Mint tokens on `holder`, modify `definition`.
///
2026-03-10 00:17:43 +03:00
/// `definition` is owned.
2025-12-11 14:46:16 +02:00
///
2026-01-21 17:58:45 -05:00
/// If `holder` is private, then `holder` and (`holder_npk` , `holder_vpk`) is a mutually
2025-12-11 14:46:16 +02:00
/// exclusive patterns.
///
/// First is used for owned accounts, second otherwise.
Mint {
2026-03-10 00:17:43 +03:00
/// definition - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[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>,
2026-03-10 00:17:43 +03:00
/// holder - valid 32 byte base58 string with privacy prefix.
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
#[arg(long, conflicts_with = "holder_label")]
2025-12-11 14:46:16 +02:00
holder: Option<String>,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
/// Holder account label (alternative to --holder).
#[arg(long, conflicts_with = "holder")]
holder_label: Option<String>,
2026-03-10 00:17:43 +03:00
/// `holder_npk` - valid 32 byte hex string.
2025-12-11 14:46:16 +02:00
#[arg(long)]
holder_npk: Option<String>,
2026-03-10 00:17:43 +03:00
/// `to_vpk` - valid 33 byte hex string.
2025-12-11 14:46:16 +02:00
#[arg(long)]
2026-01-21 17:58:45 -05:00
holder_vpk: Option<String>,
2026-03-10 00:17:43 +03:00
/// amount - amount of balance to mint.
2025-12-11 14:46:16 +02:00
#[arg(long)]
amount: u128,
},
2025-10-27 14:32:28 +02:00
}
impl WalletSubcommand for TokenProgramAgnosticSubcommand {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::New {
definition_account_id,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
definition_account_label,
supply_account_id,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
supply_account_label,
2025-10-27 14:32:28 +02:00
name,
total_supply,
} => {
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
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) =
parse_addr_with_privacy_prefix(&supply_account_id)?;
2025-10-27 14:32:28 +02:00
let underlying_subcommand = match (definition_addr_privacy, supply_addr_privacy) {
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
2025-12-02 15:27:20 +02:00
TokenProgramSubcommand::Create(
CreateNewTokenProgramSubcommand::NewPublicDefPublicSupp {
definition_account_id,
supply_account_id,
2025-10-27 14:32:28 +02:00
name,
total_supply,
},
)
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
2025-12-02 15:27:20 +02:00
TokenProgramSubcommand::Create(
CreateNewTokenProgramSubcommand::NewPublicDefPrivateSupp {
definition_account_id,
supply_account_id,
2025-10-27 14:32:28 +02:00
name,
total_supply,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
2025-12-02 15:27:20 +02:00
TokenProgramSubcommand::Create(
CreateNewTokenProgramSubcommand::NewPrivateDefPrivateSupp {
definition_account_id,
supply_account_id,
name,
total_supply,
},
)
2025-10-27 14:32:28 +02:00
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
2025-12-02 15:27:20 +02:00
TokenProgramSubcommand::Create(
CreateNewTokenProgramSubcommand::NewPrivateDefPublicSupp {
definition_account_id,
supply_account_id,
name,
total_supply,
},
)
2025-10-27 14:32:28 +02:00
}
};
underlying_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Send {
2025-10-27 14:32:28 +02:00
from,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
from_label,
2025-10-27 14:32:28 +02:00
to,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
to_label,
2025-10-27 14:32:28 +02:00
to_npk,
2026-01-21 17:58:45 -05:00
to_vpk,
2025-10-27 14:32:28 +02:00
amount,
} => {
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
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")
}
};
2026-01-21 17:58:45 -05:00
let underlying_subcommand = match (to, to_npk, to_vpk) {
2025-10-27 14:32:28 +02:00
(None, None, None) => {
anyhow::bail!(
"Provide either account account_id of receiver or their public keys"
2025-10-27 14:32:28 +02:00
);
}
(Some(_), Some(_), Some(_)) => {
anyhow::bail!(
"Provide only one variant: either account account_id of receiver or their public keys"
2025-10-27 14:32:28 +02:00
);
}
(_, Some(_), None) | (_, None, Some(_)) => {
anyhow::bail!("List of public keys is uncomplete");
}
(Some(to), None, None) => {
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
let (to, to_privacy) = parse_addr_with_privacy_prefix(&to)?;
match (from_privacy, to_privacy) {
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
2025-10-27 14:32:28 +02:00
TokenProgramSubcommand::Public(
TokenProgramSubcommandPublic::TransferToken {
sender_account_id: from,
recipient_account_id: to,
2025-10-27 14:32:28 +02:00
balance_to_move: amount,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
2025-10-27 14:32:28 +02:00
TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::TransferTokenPrivateOwned {
sender_account_id: from,
recipient_account_id: to,
2025-10-27 14:32:28 +02:00
balance_to_move: amount,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
2025-10-27 14:32:28 +02:00
TokenProgramSubcommand::Deshielded(
TokenProgramSubcommandDeshielded::TransferTokenDeshielded {
sender_account_id: from,
recipient_account_id: to,
2025-10-27 14:32:28 +02:00
balance_to_move: amount,
},
)
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
2025-10-27 14:32:28 +02:00
TokenProgramSubcommand::Shielded(
TokenProgramSubcommandShielded::TransferTokenShieldedOwned {
sender_account_id: from,
recipient_account_id: to,
2025-10-27 14:32:28 +02:00
balance_to_move: amount,
},
)
}
}
}
2026-01-21 17:58:45 -05:00
(None, Some(to_npk), Some(to_vpk)) => {
2025-10-27 14:32:28 +02:00
let (from, from_privacy) = parse_addr_with_privacy_prefix(&from)?;
match from_privacy {
AccountPrivacyKind::Private => TokenProgramSubcommand::Private(
2025-10-27 14:32:28 +02:00
TokenProgramSubcommandPrivate::TransferTokenPrivateForeign {
sender_account_id: from,
2025-10-27 14:32:28 +02:00
recipient_npk: to_npk,
2026-01-21 17:58:45 -05:00
recipient_vpk: to_vpk,
2025-10-27 14:32:28 +02:00
balance_to_move: amount,
},
),
AccountPrivacyKind::Public => TokenProgramSubcommand::Shielded(
2025-10-27 14:32:28 +02:00
TokenProgramSubcommandShielded::TransferTokenShieldedForeign {
sender_account_id: from,
2025-10-27 14:32:28 +02:00
recipient_npk: to_npk,
2026-01-21 17:58:45 -05:00
recipient_vpk: to_vpk,
2025-10-27 14:32:28 +02:00
balance_to_move: amount,
},
),
}
}
};
2025-12-11 14:46:16 +02:00
underlying_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Burn {
2025-12-11 14:46:16 +02:00
definition,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
definition_label,
2025-12-11 14:46:16 +02:00
holder,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
holder_label,
2025-12-11 14:46:16 +02:00
amount,
} => {
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
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,
)?;
2025-12-12 13:40:56 +02:00
let underlying_subcommand = {
let (definition, definition_privacy) =
parse_addr_with_privacy_prefix(&definition)?;
let (holder, holder_privacy) = parse_addr_with_privacy_prefix(&holder)?;
match (definition_privacy, holder_privacy) {
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Public(
TokenProgramSubcommandPublic::BurnToken {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
2025-12-11 14:46:16 +02:00
}
2025-12-12 13:40:56 +02:00
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::BurnTokenPrivateOwned {
definition_account_id: definition,
2025-12-11 14:46:16 +02:00
holder_account_id: holder,
amount,
},
2025-12-12 13:40:56 +02:00
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Deshielded(
TokenProgramSubcommandDeshielded::BurnTokenDeshieldedOwned {
definition_account_id: definition,
2025-12-11 14:46:16 +02:00
holder_account_id: holder,
amount,
},
2025-12-12 13:40:56 +02:00
)
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Shielded(
TokenProgramSubcommandShielded::BurnTokenShielded {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
2025-12-11 14:46:16 +02:00
}
}
};
underlying_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Mint {
2025-12-11 14:46:16 +02:00
definition,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
definition_label,
2025-12-11 14:46:16 +02:00
holder,
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
holder_label,
2025-12-11 14:46:16 +02:00
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
} => {
feat: add --account-label as alternative to --account-id across all wallet subcommands Allow users to identify accounts by their human-readable label instead of the full `Privacy/base58` account ID. This makes the CLI much more ergonomic for users who have labeled their accounts. - [x] Add `resolve_account_label()` in `helperfunctions.rs` that looks up a label, determines account privacy (public/private), and returns the full `Privacy/id` string - [x] Add `--account-label` (or `--from-label`, `--to-label`, `--definition-label`, `--holder-label`, `--user-holding-*-label`) as mutually exclusive alternative to every `--account-id`-style flag across all subcommands: - `account get`, `account label` - `auth-transfer init`, `auth-transfer send` - `token new`, `token send`, `token burn`, `token mint` - `pinata claim` - `amm new`, `amm swap`, `amm add-liquidity`, `amm remove-liquidity` - [x] Update zsh completion script with `_wallet_account_labels()` helper - [x] Add bash completion script with `_wallet_get_account_labels()` helper 1. Start a local sequencer 2. Create accounts and label them: `wallet account new public --label alice` 3. Use labels in commands: `wallet account get --account-label alice` 4. Verify mutual exclusivity: `wallet account get --account-id <id> --account-label alice` should error 5. Test shell completions: `wallet account get --account-label <TAB>` should list labels None None - [x] Complete PR description - [x] Implement the core functionality - [ ] Add/update tests - [x] Add/update documentation and inline comments Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:33:51 +11:00
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")
}
};
2026-01-21 17:58:45 -05:00
let underlying_subcommand = match (holder, holder_npk, holder_vpk) {
2025-12-11 14:46:16 +02:00
(None, None, None) => {
anyhow::bail!(
"Provide either account account_id of holder or their public keys"
);
}
(Some(_), Some(_), Some(_)) => {
anyhow::bail!(
"Provide only one variant: either account_id of holder or their public keys"
);
}
(_, Some(_), None) | (_, None, Some(_)) => {
anyhow::bail!("List of public keys is uncomplete");
}
(Some(holder), None, None) => {
let (definition, definition_privacy) =
parse_addr_with_privacy_prefix(&definition)?;
let (holder, holder_privacy) = parse_addr_with_privacy_prefix(&holder)?;
match (definition_privacy, holder_privacy) {
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Public(
TokenProgramSubcommandPublic::MintToken {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::MintTokenPrivateOwned {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Deshielded(
TokenProgramSubcommandDeshielded::MintTokenDeshielded {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Shielded(
TokenProgramSubcommandShielded::MintTokenShieldedOwned {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
}
}
2026-01-21 17:58:45 -05:00
(None, Some(holder_npk), Some(holder_vpk)) => {
2025-12-11 14:46:16 +02:00
let (definition, definition_privacy) =
parse_addr_with_privacy_prefix(&definition)?;
match definition_privacy {
AccountPrivacyKind::Private => TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::MintTokenPrivateForeign {
definition_account_id: definition,
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
},
),
AccountPrivacyKind::Public => TokenProgramSubcommand::Shielded(
TokenProgramSubcommandShielded::MintTokenShieldedForeign {
definition_account_id: definition,
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
},
),
}
}
};
2025-10-27 14:32:28 +02:00
underlying_subcommand.handle_subcommand(wallet_core).await
}
}
}
}
2025-10-13 17:25:36 +03:00
2026-03-10 00:17:43 +03:00
/// Represents generic CLI subcommand for a wallet working with `token_program`.
2025-10-13 17:25:36 +03:00
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramSubcommand {
2026-03-10 00:17:43 +03:00
/// Creation of new token.
2025-12-02 15:27:20 +02:00
#[command(subcommand)]
Create(CreateNewTokenProgramSubcommand),
2026-03-10 00:17:43 +03:00
/// Public execution.
2025-10-14 10:18:54 +03:00
#[command(subcommand)]
Public(TokenProgramSubcommandPublic),
2026-03-10 00:17:43 +03:00
/// Private execution.
2025-10-14 10:18:54 +03:00
#[command(subcommand)]
Private(TokenProgramSubcommandPrivate),
2026-03-10 00:17:43 +03:00
/// Deshielded execution.
2025-10-20 09:10:54 +03:00
#[command(subcommand)]
Deshielded(TokenProgramSubcommandDeshielded),
2026-03-10 00:17:43 +03:00
/// Shielded execution.
2025-10-20 09:10:54 +03:00
#[command(subcommand)]
Shielded(TokenProgramSubcommandShielded),
2025-10-14 10:18:54 +03:00
}
2026-03-10 00:17:43 +03:00
/// Represents generic public CLI subcommand for a wallet working with `token_program`.
2025-10-14 10:18:54 +03:00
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramSubcommandPublic {
2025-11-26 00:27:20 +03:00
// Transfer tokens using the token program
2025-10-13 17:25:36 +03:00
TransferToken {
#[arg(short, long)]
sender_account_id: String,
2025-10-13 17:25:36 +03:00
#[arg(short, long)]
recipient_account_id: String,
2025-10-13 17:25:36 +03:00
#[arg(short, long)]
balance_to_move: u128,
},
2025-12-11 14:46:16 +02:00
// Burn tokens using the token program
BurnToken {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintToken {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
2025-10-14 10:18:54 +03:00
}
2026-03-10 00:17:43 +03:00
/// Represents generic private CLI subcommand for a wallet working with `token_program`.
2025-10-14 10:18:54 +03:00
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramSubcommandPrivate {
2025-11-26 00:27:20 +03:00
// Transfer tokens using the token program
2025-10-14 10:18:54 +03:00
TransferTokenPrivateOwned {
2025-10-13 17:25:36 +03:00
#[arg(short, long)]
sender_account_id: String,
2025-10-13 17:25:36 +03:00
#[arg(short, long)]
recipient_account_id: String,
2025-10-13 17:25:36 +03:00
#[arg(short, long)]
balance_to_move: u128,
},
2025-11-26 00:27:20 +03:00
// Transfer tokens using the token program
2025-10-13 17:25:36 +03:00
TransferTokenPrivateForeign {
#[arg(short, long)]
sender_account_id: String,
2026-03-10 00:17:43 +03:00
/// `recipient_npk` - valid 32 byte hex string.
2025-10-13 17:25:36 +03:00
#[arg(long)]
recipient_npk: String,
2026-03-10 00:17:43 +03:00
/// `recipient_vpk` - valid 33 byte hex string.
2025-10-13 17:25:36 +03:00
#[arg(long)]
2026-01-21 17:58:45 -05:00
recipient_vpk: String,
2025-10-13 17:25:36 +03:00
#[arg(short, long)]
balance_to_move: u128,
},
2025-12-11 14:46:16 +02:00
// Burn tokens using the token program
BurnTokenPrivateOwned {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintTokenPrivateOwned {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintTokenPrivateForeign {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_npk: String,
#[arg(short, long)]
2026-01-21 17:58:45 -05:00
holder_vpk: String,
2025-12-11 14:46:16 +02:00
#[arg(short, long)]
amount: u128,
},
2025-10-13 17:25:36 +03:00
}
2026-03-10 00:17:43 +03:00
/// Represents deshielded public CLI subcommand for a wallet working with `token_program`.
2025-10-20 09:10:54 +03:00
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramSubcommandDeshielded {
2025-11-26 00:27:20 +03:00
// Transfer tokens using the token program
2025-10-20 09:10:54 +03:00
TransferTokenDeshielded {
#[arg(short, long)]
sender_account_id: String,
2025-10-20 09:10:54 +03:00
#[arg(short, long)]
recipient_account_id: String,
2025-10-20 09:10:54 +03:00
#[arg(short, long)]
balance_to_move: u128,
},
2025-12-11 14:46:16 +02:00
// Burn tokens using the token program
BurnTokenDeshieldedOwned {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintTokenDeshielded {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
2025-10-20 09:10:54 +03:00
}
2026-03-10 00:17:43 +03:00
/// Represents generic shielded CLI subcommand for a wallet working with `token_program`.
2025-10-20 09:10:54 +03:00
#[derive(Subcommand, Debug, Clone)]
pub enum TokenProgramSubcommandShielded {
2025-11-26 00:27:20 +03:00
// Transfer tokens using the token program
2025-10-20 09:10:54 +03:00
TransferTokenShieldedOwned {
#[arg(short, long)]
sender_account_id: String,
2025-10-20 09:10:54 +03:00
#[arg(short, long)]
recipient_account_id: String,
2025-10-20 09:10:54 +03:00
#[arg(short, long)]
balance_to_move: u128,
},
2025-11-26 00:27:20 +03:00
// Transfer tokens using the token program
2025-10-20 09:10:54 +03:00
TransferTokenShieldedForeign {
#[arg(short, long)]
sender_account_id: String,
2026-03-10 00:17:43 +03:00
/// `recipient_npk` - valid 32 byte hex string.
2025-10-20 09:10:54 +03:00
#[arg(long)]
recipient_npk: String,
2026-03-10 00:17:43 +03:00
/// `recipient_vpk` - valid 33 byte hex string.
2025-10-20 09:10:54 +03:00
#[arg(long)]
2026-01-21 17:58:45 -05:00
recipient_vpk: String,
2025-10-20 09:10:54 +03:00
#[arg(short, long)]
balance_to_move: u128,
},
2025-12-11 14:46:16 +02:00
// Burn tokens using the token program
BurnTokenShielded {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintTokenShieldedOwned {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintTokenShieldedForeign {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
holder_npk: String,
#[arg(short, long)]
2026-01-21 17:58:45 -05:00
holder_vpk: String,
2025-12-11 14:46:16 +02:00
#[arg(short, long)]
amount: u128,
},
2025-10-20 09:10:54 +03:00
}
2026-03-10 00:17:43 +03:00
/// Represents generic initialization subcommand for a wallet working with `token_program`.
2025-12-02 15:27:20 +02:00
#[derive(Subcommand, Debug, Clone)]
pub enum CreateNewTokenProgramSubcommand {
2026-03-10 00:17:43 +03:00
/// Create a new token using the token program.
2025-12-02 15:27:20 +02:00
///
2026-03-10 00:17:43 +03:00
/// Definition - public, supply - public.
2025-12-02 15:27:20 +02:00
NewPublicDefPublicSupp {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
supply_account_id: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
2026-03-10 00:17:43 +03:00
/// Create a new token using the token program.
2025-12-02 15:27:20 +02:00
///
2026-03-10 00:17:43 +03:00
/// Definition - public, supply - private.
2025-12-02 15:27:20 +02:00
NewPublicDefPrivateSupp {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
supply_account_id: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
2026-03-10 00:17:43 +03:00
/// Create a new token using the token program.
2025-12-02 15:27:20 +02:00
///
2026-03-10 00:17:43 +03:00
/// Definition - private, supply - public.
2025-12-02 15:27:20 +02:00
NewPrivateDefPublicSupp {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
supply_account_id: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
2026-03-10 00:17:43 +03:00
/// Create a new token using the token program.
2025-12-02 15:27:20 +02:00
///
2026-03-10 00:17:43 +03:00
/// Definition - private, supply - private.
2025-12-02 15:27:20 +02:00
NewPrivateDefPrivateSupp {
#[arg(short, long)]
definition_account_id: String,
#[arg(short, long)]
supply_account_id: String,
#[arg(short, long)]
name: String,
#[arg(short, long)]
total_supply: u128,
},
}
2025-10-14 10:18:54 +03:00
impl WalletSubcommand for TokenProgramSubcommandPublic {
2025-10-13 17:25:36 +03:00
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::TransferToken {
sender_account_id,
recipient_account_id,
2025-10-14 10:18:54 +03:00
balance_to_move,
} => {
Token(wallet_core)
.send_transfer_transaction(
sender_account_id.parse().unwrap(),
recipient_account_id.parse().unwrap(),
2025-10-14 10:18:54 +03:00
balance_to_move,
)
.await?;
Ok(SubcommandReturnValue::Empty)
}
2026-03-09 18:27:56 +03:00
Self::BurnToken {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
Token(wallet_core)
.send_burn_transaction(
definition_account_id.parse().unwrap(),
holder_account_id.parse().unwrap(),
amount,
)
.await?;
Ok(SubcommandReturnValue::Empty)
}
2026-03-09 18:27:56 +03:00
Self::MintToken {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
Token(wallet_core)
.send_mint_transaction(
definition_account_id.parse().unwrap(),
holder_account_id.parse().unwrap(),
amount,
)
.await?;
Ok(SubcommandReturnValue::Empty)
}
2025-10-14 10:18:54 +03:00
}
}
}
impl WalletSubcommand for TokenProgramSubcommandPrivate {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::TransferTokenPrivateOwned {
sender_account_id,
recipient_account_id,
2025-10-13 17:25:36 +03:00
balance_to_move,
} => {
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
2025-10-13 17:25:36 +03:00
let (tx_hash, [secret_sender, secret_recipient]) = Token(wallet_core)
.send_transfer_transaction_private_owned_account(
sender_account_id,
recipient_account_id,
balance_to_move,
)
2025-10-15 15:29:28 +03:00
.await?;
2025-10-13 17:25:36 +03:00
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-10-13 17:25:36 +03:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-10-13 17:25:36 +03:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
2025-10-14 10:18:54 +03:00
let acc_decode_data = vec![
2025-12-11 14:46:16 +02:00
Decode(secret_sender, sender_account_id),
Decode(secret_recipient, recipient_account_id),
2025-10-14 10:18:54 +03:00
];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-10-14 10:18:54 +03:00
&acc_decode_data,
)?;
2025-10-13 17:25:36 +03:00
}
wallet_core.store_persistent_data().await?;
2025-10-13 17:25:36 +03:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::TransferTokenPrivateForeign {
sender_account_id,
2025-10-13 17:25:36 +03:00
recipient_npk,
2026-01-21 17:58:45 -05:00
recipient_vpk,
2025-10-13 17:25:36 +03:00
balance_to_move,
} => {
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
2025-10-13 17:25:36 +03:00
let recipient_npk_res = hex::decode(recipient_npk)?;
let mut recipient_npk = [0; 32];
recipient_npk.copy_from_slice(&recipient_npk_res);
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
2026-01-21 17:58:45 -05:00
let recipient_vpk_res = hex::decode(recipient_vpk)?;
2026-03-04 18:42:33 +03:00
let mut recipient_vpk = [0_u8; 33];
2026-01-21 17:58:45 -05:00
recipient_vpk.copy_from_slice(&recipient_vpk_res);
let recipient_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
recipient_vpk.to_vec(),
2025-10-13 17:25:36 +03:00
);
let (tx_hash, [secret_sender, _]) = Token(wallet_core)
.send_transfer_transaction_private_foreign_account(
sender_account_id,
2025-10-13 17:25:36 +03:00
recipient_npk,
2026-01-21 17:58:45 -05:00
recipient_vpk,
2025-10-13 17:25:36 +03:00
balance_to_move,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-10-13 17:25:36 +03:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-10-13 17:25:36 +03:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
2025-12-11 14:46:16 +02:00
let acc_decode_data = vec![Decode(secret_sender, sender_account_id)];
2025-10-13 17:25:36 +03:00
2025-10-14 10:18:54 +03:00
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-10-14 10:18:54 +03:00
&acc_decode_data,
)?;
2025-10-13 17:25:36 +03:00
}
wallet_core.store_persistent_data().await?;
2025-10-13 17:25:36 +03:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::BurnTokenPrivateOwned {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
2025-10-20 09:10:54 +03:00
} => {
2025-12-11 14:46:16 +02:00
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
2025-10-20 09:10:54 +03:00
let (tx_hash, [secret_definition, secret_holder]) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_burn_transaction_private_owned_account(
definition_account_id,
holder_account_id,
amount,
2025-10-20 09:10:54 +03:00
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-10-20 09:10:54 +03:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-10-20 09:10:54 +03:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
2025-12-11 14:46:16 +02:00
let acc_decode_data = vec![
Decode(secret_definition, definition_account_id),
Decode(secret_holder, holder_account_id),
];
2025-10-20 09:10:54 +03:00
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-10-20 09:10:54 +03:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-10-20 09:10:54 +03:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::MintTokenPrivateOwned {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (tx_hash, [secret_definition, secret_holder]) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_mint_transaction_private_owned_account(
definition_account_id,
holder_account_id,
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![
Decode(secret_definition, definition_account_id),
Decode(secret_holder, holder_account_id),
];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::MintTokenPrivateForeign {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_npk_res = hex::decode(holder_npk)?;
let mut holder_npk = [0; 32];
holder_npk.copy_from_slice(&holder_npk_res);
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
2026-01-21 17:58:45 -05:00
let holder_vpk_res = hex::decode(holder_vpk)?;
2026-03-04 18:42:33 +03:00
let mut holder_vpk = [0_u8; 33];
2026-01-21 17:58:45 -05:00
holder_vpk.copy_from_slice(&holder_vpk_res);
let holder_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
holder_vpk.to_vec(),
2025-12-11 14:46:16 +02:00
);
let (tx_hash, [secret_definition, _]) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_mint_transaction_private_foreign_account(
definition_account_id,
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret_definition, definition_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
}
}
}
impl WalletSubcommand for TokenProgramSubcommandDeshielded {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::TransferTokenDeshielded {
2025-12-11 14:46:16 +02:00
sender_account_id,
recipient_account_id,
balance_to_move,
} => {
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
let (tx_hash, secret_sender) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_transfer_transaction_deshielded(
sender_account_id,
recipient_account_id,
balance_to_move,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret_sender, sender_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::BurnTokenDeshieldedOwned {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (tx_hash, secret_definition) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_burn_transaction_deshielded_owned_account(
definition_account_id,
holder_account_id,
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret_definition, definition_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::MintTokenDeshielded {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (tx_hash, secret_definition) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_mint_transaction_deshielded(
definition_account_id,
holder_account_id,
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret_definition, definition_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
}
}
}
impl WalletSubcommand for TokenProgramSubcommandShielded {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::TransferTokenShieldedForeign {
sender_account_id,
2025-10-20 09:10:54 +03:00
recipient_npk,
2026-01-21 17:58:45 -05:00
recipient_vpk,
2025-10-20 09:10:54 +03:00
balance_to_move,
} => {
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
2025-10-20 09:10:54 +03:00
let recipient_npk_res = hex::decode(recipient_npk)?;
let mut recipient_npk = [0; 32];
recipient_npk.copy_from_slice(&recipient_npk_res);
let recipient_npk = nssa_core::NullifierPublicKey(recipient_npk);
2026-01-21 17:58:45 -05:00
let recipient_vpk_res = hex::decode(recipient_vpk)?;
2026-03-04 18:42:33 +03:00
let mut recipient_vpk = [0_u8; 33];
2026-01-21 17:58:45 -05:00
recipient_vpk.copy_from_slice(&recipient_vpk_res);
let recipient_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
recipient_vpk.to_vec(),
2025-10-20 09:10:54 +03:00
);
let (tx_hash, _) = Token(wallet_core)
.send_transfer_transaction_shielded_foreign_account(
sender_account_id,
2025-10-20 09:10:54 +03:00
recipient_npk,
2026-01-21 17:58:45 -05:00
recipient_vpk,
2025-10-20 09:10:54 +03:00
balance_to_move,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-10-20 09:10:54 +03:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-10-20 09:10:54 +03:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
println!("Transaction data is {:?}", tx.message);
}
wallet_core.store_persistent_data().await?;
2025-10-20 09:10:54 +03:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::TransferTokenShieldedOwned {
sender_account_id,
recipient_account_id,
2025-10-20 09:10:54 +03:00
balance_to_move,
} => {
let sender_account_id: AccountId = sender_account_id.parse().unwrap();
let recipient_account_id: AccountId = recipient_account_id.parse().unwrap();
2025-10-20 09:10:54 +03:00
let (tx_hash, secret_recipient) = Token(wallet_core)
.send_transfer_transaction_shielded_owned_account(
sender_account_id,
recipient_account_id,
balance_to_move,
)
2025-10-20 09:10:54 +03:00
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-10-20 09:10:54 +03:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-10-20 09:10:54 +03:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
2025-12-11 14:46:16 +02:00
let acc_decode_data = vec![Decode(secret_recipient, recipient_account_id)];
2025-10-20 09:10:54 +03:00
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-10-20 09:10:54 +03:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-10-20 09:10:54 +03:00
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::BurnTokenShielded {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (tx_hash, secret_holder) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_burn_transaction_shielded(
definition_account_id,
holder_account_id,
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret_holder, holder_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::MintTokenShieldedOwned {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_account_id,
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (tx_hash, secret_holder) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_mint_transaction_shielded_owned_account(
definition_account_id,
holder_account_id,
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Decode(secret_holder, holder_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-11 14:46:16 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::MintTokenShieldedForeign {
2025-12-11 14:46:16 +02:00
definition_account_id,
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let holder_npk_res = hex::decode(holder_npk)?;
let mut holder_npk = [0; 32];
holder_npk.copy_from_slice(&holder_npk_res);
let holder_npk = nssa_core::NullifierPublicKey(holder_npk);
2026-01-21 17:58:45 -05:00
let holder_vpk_res = hex::decode(holder_vpk)?;
2026-03-04 18:42:33 +03:00
let mut holder_vpk = [0_u8; 33];
2026-01-21 17:58:45 -05:00
holder_vpk.copy_from_slice(&holder_vpk_res);
let holder_vpk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
holder_vpk.to_vec(),
2025-12-11 14:46:16 +02:00
);
let (tx_hash, _) = Token(wallet_core)
2025-12-11 14:46:16 +02:00
.send_mint_transaction_shielded_foreign_account(
definition_account_id,
holder_npk,
2026-01-21 17:58:45 -05:00
holder_vpk,
2025-12-11 14:46:16 +02:00
amount,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-11 14:46:16 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-11 14:46:16 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
println!("Transaction data is {:?}", tx.message);
}
wallet_core.store_persistent_data().await?;
2025-12-11 14:46:16 +02:00
2025-10-20 09:10:54 +03:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
}
}
}
2025-12-02 15:27:20 +02:00
impl WalletSubcommand for CreateNewTokenProgramSubcommand {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::NewPrivateDefPrivateSupp {
2025-12-02 15:27:20 +02:00
definition_account_id,
supply_account_id,
name,
total_supply,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let supply_account_id: AccountId = supply_account_id.parse().unwrap();
let (tx_hash, [secret_definition, secret_supply]) = Token(wallet_core)
2025-12-02 15:27:20 +02:00
.send_new_definition_private_owned_definiton_and_supply(
definition_account_id,
supply_account_id,
name,
2025-12-02 15:27:20 +02:00
total_supply,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-02 15:27:20 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-02 15:27:20 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![
2025-12-11 14:46:16 +02:00
Decode(secret_definition, definition_account_id),
Decode(secret_supply, supply_account_id),
2025-12-02 15:27:20 +02:00
];
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-02 15:27:20 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-02 15:27:20 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::NewPrivateDefPublicSupp {
2025-12-02 15:27:20 +02:00
definition_account_id,
supply_account_id,
name,
total_supply,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let supply_account_id: AccountId = supply_account_id.parse().unwrap();
let (tx_hash, secret_definition) = Token(wallet_core)
2025-12-02 15:27:20 +02:00
.send_new_definition_private_owned_definiton(
definition_account_id,
supply_account_id,
name,
2025-12-02 15:27:20 +02:00
total_supply,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-02 15:27:20 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-02 15:27:20 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
2025-12-11 14:46:16 +02:00
let acc_decode_data = vec![Decode(secret_definition, definition_account_id)];
2025-12-02 15:27:20 +02:00
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-02 15:27:20 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-02 15:27:20 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::NewPublicDefPrivateSupp {
2025-12-02 15:27:20 +02:00
definition_account_id,
supply_account_id,
name,
total_supply,
} => {
let definition_account_id: AccountId = definition_account_id.parse().unwrap();
let supply_account_id: AccountId = supply_account_id.parse().unwrap();
let (tx_hash, secret_supply) = Token(wallet_core)
2025-12-02 15:27:20 +02:00
.send_new_definition_private_owned_supply(
definition_account_id,
supply_account_id,
name,
2025-12-02 15:27:20 +02:00
total_supply,
)
.await?;
2026-03-14 03:20:37 +03:00
println!("Transaction hash is {tx_hash}");
2025-12-02 15:27:20 +02:00
let transfer_tx = wallet_core.poll_native_token_transfer(tx_hash).await?;
2025-12-02 15:27:20 +02:00
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
2025-12-11 14:46:16 +02:00
let acc_decode_data = vec![Decode(secret_supply, supply_account_id)];
2025-12-02 15:27:20 +02:00
wallet_core.decode_insert_privacy_preserving_transaction_results(
2026-03-03 23:21:08 +03:00
&tx,
2025-12-02 15:27:20 +02:00
&acc_decode_data,
)?;
}
wallet_core.store_persistent_data().await?;
2025-12-02 15:27:20 +02:00
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
2026-03-09 18:27:56 +03:00
Self::NewPublicDefPublicSupp {
2025-12-02 15:27:20 +02:00
definition_account_id,
supply_account_id,
name,
total_supply,
} => {
Token(wallet_core)
.send_new_definition(
definition_account_id.parse().unwrap(),
supply_account_id.parse().unwrap(),
name,
2025-12-02 15:27:20 +02:00
total_supply,
)
.await?;
Ok(SubcommandReturnValue::Empty)
}
}
}
}
2025-10-14 10:18:54 +03:00
impl WalletSubcommand for TokenProgramSubcommand {
async fn handle_subcommand(
self,
wallet_core: &mut WalletCore,
) -> Result<SubcommandReturnValue> {
match self {
2026-03-09 18:27:56 +03:00
Self::Create(creation_subcommand) => {
2025-12-02 15:27:20 +02:00
creation_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Private(private_subcommand) => {
2025-10-14 10:18:54 +03:00
private_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Public(public_subcommand) => {
2025-10-14 10:18:54 +03:00
public_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Deshielded(deshielded_subcommand) => {
2025-10-20 09:10:54 +03:00
deshielded_subcommand.handle_subcommand(wallet_core).await
}
2026-03-09 18:27:56 +03:00
Self::Shielded(shielded_subcommand) => {
2025-10-20 09:10:54 +03:00
shielded_subcommand.handle_subcommand(wallet_core).await
}
2025-10-14 10:18:54 +03:00
}
}
}