mirror of
https://github.com/logos-blockchain/lssa.git
synced 2026-05-12 12:49:36 +00:00
bring back new private account command for simplicity
This commit is contained in:
parent
42842dfbb1
commit
3ec166ff7c
@ -5,6 +5,7 @@ This tutorial walks through native token transfers between public and private ac
|
||||
4. Private account creation.
|
||||
5. Native token transfer from a public account to a private account.
|
||||
6. Native token transfer from a public account to a private account owned by someone else.
|
||||
7. Sending to a private accounts key from multiple independent senders.
|
||||
|
||||
---
|
||||
|
||||
@ -12,7 +13,7 @@ The CLI provides commands to manage accounts. Run `wallet account` to see the op
|
||||
```bash
|
||||
Commands:
|
||||
get Get account data
|
||||
new Create a new public account or private accounts key
|
||||
new Produce new public or private account
|
||||
sync-private Sync private accounts
|
||||
help Print this message or the help of the given subcommand(s)
|
||||
```
|
||||
@ -136,69 +137,62 @@ Account owned by authenticated-transfer program
|
||||
{"balance":37}
|
||||
```
|
||||
|
||||
## 4. Private accounts key creation
|
||||
## 4. Private account creation
|
||||
|
||||
> [!Important]
|
||||
> Private accounts are structurally identical to public accounts, but their values are stored off-chain. On-chain, only a 32-byte commitment is recorded.
|
||||
> Transactions include encrypted private values so the owner can recover them, and the decryption keys are never shared.
|
||||
> Private accounts use two keypairs: nullifier keys for privacy-preserving executions and viewing keys for encrypting and decrypting values.
|
||||
> A private account ID is derived from the nullifier public key and an identifier chosen by the sender at the time of the first transfer.
|
||||
> The private account ID is derived from the nullifier public key.
|
||||
> Private accounts can be initialized by anyone, but once initialized they can only be modified by the owner’s keys.
|
||||
> Updates include a new commitment and a nullifier for the old state, which prevents linkage between versions.
|
||||
|
||||
### a. Create a private accounts key
|
||||
### a. Create a private account
|
||||
|
||||
```bash
|
||||
wallet account new private-accounts-key
|
||||
wallet account new private
|
||||
|
||||
# Output:
|
||||
Generated new private accounts key at path /0
|
||||
Generated new account with account_id Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
||||
With npk e6366f79d026c8bd64ae6b3d601f0506832ec682ab54897f205fffe64ec0d951
|
||||
With vpk 02ddc96d0eb56e00ce14994cfdaec5ae1f76244180a919545983156e3519940a17
|
||||
```
|
||||
|
||||
> [!Tip]
|
||||
> Share `npk` and `vpk` with anyone who wants to send you tokens. The account ID for a given payment is determined by the sender when they create the transaction. Run `wallet account sync-private` after receiving a transfer to discover new account IDs under your key.
|
||||
> Save this account ID. You will use it in later commands.
|
||||
|
||||
### b. Check the account status
|
||||
|
||||
Just like public accounts, new private accounts start out uninitialized:
|
||||
|
||||
```bash
|
||||
wallet account get --account-id Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
||||
|
||||
# Output:
|
||||
Account is Uninitialized
|
||||
```
|
||||
|
||||
> [!Important]
|
||||
> Private account data is never visible to the network. It exists only in your local wallet storage.
|
||||
> Private accounts are never visible to the network. They exist only in your local wallet storage.
|
||||
|
||||
## 5. Native token transfer from a public account to a private account
|
||||
|
||||
> [!Important]
|
||||
> Sending tokens to an uninitialized private account causes the authenticated-transfer program to claim it, just like with public accounts. Program logic is the same regardless of account type.
|
||||
> When sending to a private account, use the recipient’s `npk` and `vpk`. The sender chooses an identifier for the payment; the recipient’s account ID is derived from `(npk, identifier)` and is only known after the recipient syncs.
|
||||
|
||||
### a. Send 17 tokens to the private account
|
||||
|
||||
> [!Note]
|
||||
> The syntax matches public-to-public transfers, but the recipient is identified by `npk` and `vpk`. This runs locally, generates a proof, and submits it to the sequencer. It may take 30 seconds to 4 minutes.
|
||||
> The syntax matches public-to-public transfers, but the recipient is a private ID. This runs locally, generates a proof, and submits it to the sequencer. It may take 30 seconds to 4 minutes.
|
||||
|
||||
```bash
|
||||
wallet auth-transfer send \
|
||||
--from Public/Ev1JprP9BmhbFVQyBcbznU8bAXcwrzwRoPTetXdQPAWS \
|
||||
--to-npk e6366f79d026c8bd64ae6b3d601f0506832ec682ab54897f205fffe64ec0d951 \
|
||||
--to-vpk 02ddc96d0eb56e00ce14994cfdaec5ae1f76244180a919545983156e3519940a17 \
|
||||
--to Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL \
|
||||
--amount 17
|
||||
```
|
||||
|
||||
### b. Sync to discover the private account ID
|
||||
|
||||
```bash
|
||||
wallet account sync-private
|
||||
```
|
||||
|
||||
```bash
|
||||
wallet account list
|
||||
|
||||
# Output (private account entry):
|
||||
/0 Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
||||
```
|
||||
|
||||
> [!Tip]
|
||||
> Save this account ID. You will use it in later commands.
|
||||
|
||||
### c. Check both accounts
|
||||
### b. Check both accounts
|
||||
|
||||
```bash
|
||||
# Public sender account
|
||||
@ -210,7 +204,7 @@ Account owned by authenticated-transfer program
|
||||
```
|
||||
|
||||
```bash
|
||||
# Private recipient account (use the ID discovered after sync)
|
||||
# Private recipient account
|
||||
wallet account get --account-id Private/HacPU3hakLYzWtSqUPw6TUr8fqoMieVWovsUR6sJf7cL
|
||||
|
||||
# Output:
|
||||
@ -227,7 +221,7 @@ Account owned by authenticated-transfer program
|
||||
## 6. Native token transfer from a public account to a private account owned by someone else
|
||||
|
||||
> [!Important]
|
||||
> When the recipient is someone else, you only have their `npk` and `vpk` — never their account ID. The flow is identical to section 5.
|
||||
> We’ll simulate transferring to someone else by creating a new private accounts key and treating it as if it belonged to another user. When the recipient is someone else, you only have their `npk` and `vpk` — not an account ID.
|
||||
|
||||
### a. Create a new private accounts key to simulate a foreign recipient
|
||||
|
||||
@ -240,6 +234,9 @@ With npk 0c95ebc4b3830f53da77bb0b80a276a776cdcf6410932acc718dcdb3f788a00e
|
||||
With vpk 039fd12a3674a880d3e917804129141e4170d419d1f9e28a3dcf979c1f2369cb72
|
||||
```
|
||||
|
||||
> [!Tip]
|
||||
> Ignore the account ID here and use the `npk` and `vpk` values to send to a foreign private account.
|
||||
|
||||
### b. Send 3 tokens using the recipient’s npk and vpk
|
||||
|
||||
```bash
|
||||
@ -256,3 +253,65 @@ wallet auth-transfer send \
|
||||
|
||||
> [!Note]
|
||||
> You have seen transfers between two public accounts and from a public sender to a private recipient. Transfers from a private sender, whether to a public account or to another private account, follow the same pattern.
|
||||
|
||||
## 7. Sending to a private accounts key from multiple independent senders
|
||||
|
||||
> [!Important]
|
||||
> A private accounts key (`npk` + `vpk`) can be shared with multiple senders. Each sender independently chooses an identifier; the recipient's account ID is derived from `(npk, identifier)`. Two senders using different identifiers produce two separate private accounts under the same key.
|
||||
|
||||
### a. Alice creates a private accounts key
|
||||
|
||||
```bash
|
||||
wallet account new private-accounts-key
|
||||
|
||||
# Output:
|
||||
Generated new private accounts key at path /2
|
||||
With npk a3f7c21b8e905d4f6a1bc783d0e2f94c1d5a6b7e8f9012345678abcdef012345
|
||||
With vpk 03b1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6071819202122232425262728292a2b2c
|
||||
```
|
||||
|
||||
Alice shares the `npk` and `vpk` values with Bob and Charlie out of band.
|
||||
|
||||
### b. Bob sends 10 tokens to Alice using identifier 1
|
||||
|
||||
```bash
|
||||
wallet auth-transfer send \
|
||||
--from Public/BobXqJprP9BmhbFVQyBcbznU8bAXcwrzwRoPTetXdQPA \
|
||||
--to-npk a3f7c21b8e905d4f6a1bc783d0e2f94c1d5a6b7e8f9012345678abcdef012345 \
|
||||
--to-vpk 03b1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6071819202122232425262728292a2b2c \
|
||||
--to-identifier 1 \
|
||||
--amount 10
|
||||
```
|
||||
|
||||
### c. Charlie sends 5 tokens to Alice using identifier 2
|
||||
|
||||
```bash
|
||||
wallet auth-transfer send \
|
||||
--from Public/CharlieYrP9BmhbFVQyBcbznU8bAXcwrzwRoPTetXdQPB \
|
||||
--to-npk a3f7c21b8e905d4f6a1bc783d0e2f94c1d5a6b7e8f9012345678abcdef012345 \
|
||||
--to-vpk 03b1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6071819202122232425262728292a2b2c \
|
||||
--to-identifier 2 \
|
||||
--amount 5
|
||||
```
|
||||
|
||||
> [!Note]
|
||||
> Bob and Charlie each chose a different identifier. They do not need to coordinate — any two distinct values work.
|
||||
|
||||
### d. Alice syncs to discover the new accounts
|
||||
|
||||
```bash
|
||||
wallet account sync-private
|
||||
```
|
||||
|
||||
```bash
|
||||
wallet account list
|
||||
|
||||
# Output (private account entries under key /2):
|
||||
/2 Private/AliceBobAcctXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
/2 Private/AliceCharlieAcctXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
```
|
||||
|
||||
Alice now has two separate private accounts, one funded by Bob and one by Charlie, both controlled by the same key at path `/2`.
|
||||
|
||||
> [!Tip]
|
||||
> Alice can check each account balance with `wallet account get --account-id Private/...`. Neither balance is visible on-chain.
|
||||
|
||||
@ -43,8 +43,9 @@ async fn new_public_account(ctx: &mut TestContext) -> Result<nssa::AccountId> {
|
||||
async fn new_private_account(ctx: &mut TestContext) -> Result<nssa::AccountId> {
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -159,8 +159,9 @@ async fn private_transfer_to_owned_account_using_claiming_path() -> Result<()> {
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
|
||||
// Create a new private account
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
}));
|
||||
|
||||
let sub_ret = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
@ -326,8 +327,9 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
|
||||
// Create a new private account
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
}));
|
||||
let sub_ret = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
|
||||
@ -390,8 +392,9 @@ async fn private_transfer_to_owned_account_continuous_run_path() -> Result<()> {
|
||||
async fn initialize_private_account() -> Result<()> {
|
||||
let mut ctx = TestContext::new().await?;
|
||||
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
}));
|
||||
let result = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
let SubcommandReturnValue::RegisterAccount { account_id } = result else {
|
||||
@ -489,8 +492,9 @@ async fn initialize_private_account_using_label() -> Result<()> {
|
||||
|
||||
// Create a new private account with a label
|
||||
let label = "init-private-label".to_owned();
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
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 {
|
||||
|
||||
@ -29,8 +29,9 @@ async fn sync_private_account_with_non_zero_chain_index() -> Result<()> {
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
|
||||
// Create a new private account
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
}));
|
||||
|
||||
for _ in 0..3 {
|
||||
@ -38,8 +39,9 @@ async fn sync_private_account_with_non_zero_chain_index() -> Result<()> {
|
||||
// This way we have account with child index > 0.
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -116,8 +118,9 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
let from: AccountId = ctx.existing_private_accounts()[0];
|
||||
|
||||
// Create first private account at root
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: Some(ChainIndex::root()),
|
||||
label: None,
|
||||
}));
|
||||
let result = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
@ -128,8 +131,9 @@ async fn restore_keys_from_seed() -> Result<()> {
|
||||
};
|
||||
|
||||
// Create second private account at /0
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: Some(ChainIndex::from_str("/0")?),
|
||||
label: None,
|
||||
}));
|
||||
let result = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
|
||||
let SubcommandReturnValue::RegisterAccount {
|
||||
|
||||
@ -84,8 +84,9 @@ async fn claim_pinata_to_uninitialized_private_account_fails_fast() -> Result<()
|
||||
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -227,8 +228,9 @@ async fn claim_pinata_to_new_private_account() -> Result<()> {
|
||||
// Create new private account
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -296,8 +296,9 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
// Create new account for the token supply holder (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -311,8 +312,9 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
|
||||
// Create new account for receiving a token transaction (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -457,8 +459,9 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
// Create token definition account (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: Some(ChainIndex::root()),
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -528,8 +531,9 @@ async fn create_token_with_private_definition() -> Result<()> {
|
||||
// Create private recipient account
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -657,8 +661,9 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
||||
// Create token definition account (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -672,8 +677,9 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
||||
// Create supply account (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -733,8 +739,9 @@ async fn create_token_with_private_definition_and_supply() -> Result<()> {
|
||||
// Create recipient account
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -847,8 +854,9 @@ async fn shielded_token_transfer() -> Result<()> {
|
||||
// Create recipient account (private) for shielded transfer
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -957,8 +965,9 @@ async fn deshielded_token_transfer() -> Result<()> {
|
||||
// Create supply account (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -1067,8 +1076,9 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
// Create token definition account (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -1082,8 +1092,9 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
// Create supply account (private)
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
@ -1114,8 +1125,9 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
|
||||
// Create new private account for claiming path
|
||||
let result = wallet::cli::execute_subcommand(
|
||||
ctx.wallet_mut(),
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::PrivateAccountsKey {
|
||||
Command::Account(AccountSubcommand::New(NewSubcommand::Private {
|
||||
cci: None,
|
||||
label: None,
|
||||
})),
|
||||
)
|
||||
.await?;
|
||||
|
||||
@ -82,6 +82,15 @@ pub enum NewSubcommand {
|
||||
/// Label to assign to the new account.
|
||||
label: Option<String>,
|
||||
},
|
||||
/// Register new private account with a random identifier.
|
||||
Private {
|
||||
#[arg(long)]
|
||||
/// Chain index of a parent node.
|
||||
cci: Option<ChainIndex>,
|
||||
#[arg(short, long)]
|
||||
/// Label to assign to the new account.
|
||||
label: Option<String>,
|
||||
},
|
||||
/// Create a new receiving key (npk + vpk) to share with senders.
|
||||
PrivateAccountsKey {
|
||||
#[arg(long)]
|
||||
@ -133,6 +142,48 @@ impl WalletSubcommand for NewSubcommand {
|
||||
|
||||
Ok(SubcommandReturnValue::RegisterAccount { account_id })
|
||||
}
|
||||
Self::Private { cci, label } => {
|
||||
if let Some(label) = &label
|
||||
&& wallet_core
|
||||
.storage
|
||||
.labels
|
||||
.values()
|
||||
.any(|l| l.to_string() == *label)
|
||||
{
|
||||
anyhow::bail!("Label '{label}' is already in use by another account");
|
||||
}
|
||||
|
||||
let (account_id, chain_index) = wallet_core.create_new_account_private(cci);
|
||||
|
||||
let node = wallet_core
|
||||
.storage
|
||||
.user_data
|
||||
.private_key_tree
|
||||
.key_map
|
||||
.get(&chain_index)
|
||||
.expect("Node was just inserted");
|
||||
let key = &node.value.0;
|
||||
|
||||
if let Some(label) = label {
|
||||
wallet_core
|
||||
.storage
|
||||
.labels
|
||||
.insert(account_id.to_string(), Label::new(label));
|
||||
}
|
||||
|
||||
println!(
|
||||
"Generated new account with account_id Private/{account_id} at path {chain_index}"
|
||||
);
|
||||
println!("With npk {}", hex::encode(key.nullifier_public_key.0));
|
||||
println!(
|
||||
"With vpk {}",
|
||||
hex::encode(key.viewing_public_key.to_bytes())
|
||||
);
|
||||
|
||||
wallet_core.store_persistent_data().await?;
|
||||
|
||||
Ok(SubcommandReturnValue::RegisterAccount { account_id })
|
||||
}
|
||||
Self::PrivateAccountsKey { cci } => {
|
||||
let chain_index = wallet_core.create_private_accounts_key(cci);
|
||||
|
||||
|
||||
@ -262,6 +262,32 @@ impl WalletCore {
|
||||
.create_private_accounts_key(chain_index)
|
||||
}
|
||||
|
||||
pub fn create_new_account_private(
|
||||
&mut self,
|
||||
chain_index: Option<ChainIndex>,
|
||||
) -> (AccountId, ChainIndex) {
|
||||
let cci = self
|
||||
.storage
|
||||
.user_data
|
||||
.create_private_accounts_key(chain_index);
|
||||
let identifier: nssa_core::Identifier = rand::random();
|
||||
let npk = self
|
||||
.storage
|
||||
.user_data
|
||||
.private_key_tree
|
||||
.key_map
|
||||
.get(&cci)
|
||||
.expect("Node was just inserted")
|
||||
.value
|
||||
.0
|
||||
.nullifier_public_key
|
||||
.clone();
|
||||
let account_id = AccountId::from((&npk, identifier));
|
||||
self.storage
|
||||
.insert_private_account_data(account_id, identifier, Account::default());
|
||||
(account_id, cci)
|
||||
}
|
||||
|
||||
/// Get account balance.
|
||||
pub async fn get_account_balance(&self, acc: AccountId) -> Result<u128> {
|
||||
Ok(self.sequencer_client.get_account_balance(acc).await?)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user