revert changes and add tests

This commit is contained in:
fryorcraken 2026-03-24 12:04:13 +11:00
parent c7704050a8
commit c7a2e78df1
No known key found for this signature in database
GPG Key ID: A82ED75A8DFC50A4
6 changed files with 679 additions and 35 deletions

View File

@ -420,3 +420,188 @@ async fn amm_public() -> Result<()> {
Ok(())
}
#[test]
async fn amm_new_pool_using_labels() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Create token 1 accounts
let SubcommandReturnValue::RegisterAccount {
account_id: definition_account_id_1,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: None,
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
let SubcommandReturnValue::RegisterAccount {
account_id: supply_account_id_1,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: None,
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create holding_a with a label
let holding_a_label = "amm-holding-a-label".to_owned();
let SubcommandReturnValue::RegisterAccount {
account_id: holding_a_id,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: Some(holding_a_label.clone()),
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create token 2 accounts
let SubcommandReturnValue::RegisterAccount {
account_id: definition_account_id_2,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: None,
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
let SubcommandReturnValue::RegisterAccount {
account_id: supply_account_id_2,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: None,
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create holding_b with a label
let holding_b_label = "amm-holding-b-label".to_owned();
let SubcommandReturnValue::RegisterAccount {
account_id: holding_b_id,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: Some(holding_b_label.clone()),
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create holding_lp with a label
let holding_lp_label = "amm-holding-lp-label".to_owned();
let SubcommandReturnValue::RegisterAccount {
account_id: holding_lp_id,
} = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: Some(holding_lp_label.clone()),
})),
)
.await?
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create token 1 and distribute to holding_a
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: Some(format_public_account_id(definition_account_id_1)),
definition_account_label: None,
supply_account_id: Some(format_public_account_id(supply_account_id_1)),
supply_account_label: None,
name: "TOKEN1".to_string(),
total_supply: 10,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: Some(format_public_account_id(supply_account_id_1)),
from_label: None,
to: Some(format_public_account_id(holding_a_id)),
to_label: None,
to_npk: None,
to_vpk: None,
amount: 5,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Create token 2 and distribute to holding_b
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: Some(format_public_account_id(definition_account_id_2)),
definition_account_label: None,
supply_account_id: Some(format_public_account_id(supply_account_id_2)),
supply_account_label: None,
name: "TOKEN2".to_string(),
total_supply: 10,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: Some(format_public_account_id(supply_account_id_2)),
from_label: None,
to: Some(format_public_account_id(holding_b_id)),
to_label: None,
to_npk: None,
to_vpk: None,
amount: 5,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Create AMM pool using account labels instead of IDs
let subcommand = AmmProgramAgnosticSubcommand::New {
user_holding_a: None,
user_holding_a_label: Some(holding_a_label),
user_holding_b: None,
user_holding_b_label: Some(holding_b_label),
user_holding_lp: None,
user_holding_lp_label: Some(holding_lp_label),
balance_a: 3,
balance_b: 3,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::AMM(subcommand)).await?;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let holding_lp_acc = ctx.sequencer_client().get_account(holding_lp_id).await?;
// LP balance should be 3 (geometric mean of 3, 3)
assert_eq!(
u128::from_le_bytes(holding_lp_acc.data[33..].try_into().unwrap()),
3
);
info!("Successfully created AMM pool using account labels");
Ok(())
}

View File

@ -8,6 +8,7 @@ use integration_tests::{
use log::info;
use nssa::{AccountId, program::Program};
use nssa_core::{NullifierPublicKey, encryption::shared_key_derivation::Secp256k1Point};
use sequencer_service_rpc::RpcClient as _;
use tokio::test;
use wallet::cli::{
Command, SubcommandReturnValue,
@ -141,7 +142,7 @@ async fn deshielded_transfer_to_public_account() -> Result<()> {
let acc_2_balance = ctx.sequencer_client().get_account_balance(to).await?;
assert_eq!(from_acc.balance, 9900);
assert_eq!(acc_2_balance.balance, 20100);
assert_eq!(acc_2_balance, 20100);
info!("Successfully deshielded transfer to public account");
@ -255,7 +256,7 @@ async fn shielded_transfer_to_owned_private_account() -> Result<()> {
let acc_from_balance = ctx.sequencer_client().get_account_balance(from).await?;
assert_eq!(acc_from_balance.balance, 9900);
assert_eq!(acc_from_balance, 9900);
assert_eq!(acc_to.balance, 20100);
info!("Successfully shielded transfer to owned private account");
@ -302,7 +303,7 @@ async fn shielded_transfer_to_foreign_account() -> Result<()> {
.await
);
assert_eq!(acc_1_balance.balance, 9900);
assert_eq!(acc_1_balance, 9900);
info!("Successfully shielded transfer to foreign account");
@ -429,3 +430,100 @@ async fn initialize_private_account() -> Result<()> {
Ok(())
}
#[test]
async fn private_transfer_using_from_label() -> Result<()> {
let mut ctx = TestContext::new().await?;
let from: AccountId = ctx.existing_private_accounts()[0];
let to: AccountId = ctx.existing_private_accounts()[1];
// Assign a label to the sender account
let label = "private-sender-label".to_owned();
let command = Command::Account(AccountSubcommand::Label {
account_id: Some(format_private_account_id(from)),
account_label: None,
label: label.clone(),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
// Send using the label instead of account ID
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: None,
from_label: Some(label),
to: Some(format_private_account_id(to)),
to_label: None,
to_npk: None,
to_vpk: None,
amount: 100,
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let new_commitment1 = ctx
.wallet()
.get_private_account_commitment(from)
.context("Failed to get private account commitment for sender")?;
assert!(verify_commitment_is_in_state(new_commitment1, ctx.sequencer_client()).await);
let new_commitment2 = ctx
.wallet()
.get_private_account_commitment(to)
.context("Failed to get private account commitment for receiver")?;
assert!(verify_commitment_is_in_state(new_commitment2, ctx.sequencer_client()).await);
info!("Successfully transferred privately using from_label");
Ok(())
}
#[test]
async fn initialize_private_account_using_label() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Create a new private account with a label
let label = "init-private-label".to_owned();
let command = Command::Account(AccountSubcommand::New(NewSubcommand::Private {
cci: None,
label: Some(label.clone()),
}));
let result = wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
let SubcommandReturnValue::RegisterAccount { account_id } = result else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Initialize using the label instead of account ID
let command = Command::AuthTransfer(AuthTransferSubcommand::Init {
account_id: None,
account_label: Some(label),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let command = Command::Account(AccountSubcommand::SyncPrivate {});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
let new_commitment = ctx
.wallet()
.get_private_account_commitment(account_id)
.context("Failed to get private account commitment")?;
assert!(verify_commitment_is_in_state(new_commitment, ctx.sequencer_client()).await);
let account = ctx
.wallet()
.get_account_private(account_id)
.context("Failed to get private account")?;
assert_eq!(
account.program_owner,
Program::authenticated_transfer_program().id()
);
info!("Successfully initialized private account using label");
Ok(())
}

View File

@ -256,3 +256,97 @@ async fn initialize_public_account() -> Result<()> {
Ok(())
}
#[test]
async fn successful_transfer_using_from_label() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Assign a label to the sender account
let label = "sender-label".to_owned();
let command = Command::Account(AccountSubcommand::Label {
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
account_label: None,
label: label.clone(),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
// Send using the label instead of account ID
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: None,
from_label: Some(label),
to: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
to_label: None,
to_npk: None,
to_vpk: None,
amount: 100,
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
info!("Checking correct balance move");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(ctx.existing_public_accounts()[1])
.await?;
assert_eq!(acc_1_balance, 9900);
assert_eq!(acc_2_balance, 20100);
info!("Successfully transferred using from_label");
Ok(())
}
#[test]
async fn successful_transfer_using_to_label() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Assign a label to the receiver account
let label = "receiver-label".to_owned();
let command = Command::Account(AccountSubcommand::Label {
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
account_label: None,
label: label.clone(),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
// Send using the label for the recipient
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
from_label: None,
to: None,
to_label: Some(label),
to_npk: None,
to_vpk: None,
amount: 100,
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
info!("Checking correct balance move");
let acc_1_balance = ctx
.sequencer_client()
.get_account_balance(ctx.existing_public_accounts()[0])
.await?;
let acc_2_balance = ctx
.sequencer_client()
.get_account_balance(ctx.existing_public_accounts()[1])
.await?;
assert_eq!(acc_1_balance, 9900);
assert_eq!(acc_2_balance, 20100);
info!("Successfully transferred using to_label");
Ok(())
}

View File

@ -5,10 +5,14 @@
use std::time::Duration;
use anyhow::Result;
use anyhow::{Context as _, Result};
use indexer_service_rpc::RpcClient as _;
use integration_tests::{TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_public_account_id};
use integration_tests::{
TIME_TO_WAIT_FOR_BLOCK_SECONDS, TestContext, format_private_account_id,
format_public_account_id, verify_commitment_is_in_state,
};
use log::info;
use nssa::AccountId;
use tokio::test;
use wallet::cli::{Command, programs::native_token_transfer::AuthTransferSubcommand};
@ -181,3 +185,76 @@ async fn indexer_state_consistency() -> Result<()> {
Ok(())
}
#[test]
async fn indexer_state_consistency_with_labels() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Assign labels to both accounts
let from_label = "idx-sender-label".to_owned();
let to_label_str = "idx-receiver-label".to_owned();
let label_cmd = Command::Account(wallet::cli::account::AccountSubcommand::Label {
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[0])),
account_label: None,
label: from_label.clone(),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), label_cmd).await?;
let label_cmd = Command::Account(wallet::cli::account::AccountSubcommand::Label {
account_id: Some(format_public_account_id(ctx.existing_public_accounts()[1])),
account_label: None,
label: to_label_str.clone(),
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), label_cmd).await?;
// Send using labels instead of account IDs
let command = Command::AuthTransfer(AuthTransferSubcommand::Send {
from: None,
from_label: Some(from_label),
to: None,
to_label: Some(to_label_str),
to_npk: None,
to_vpk: None,
amount: 100,
});
wallet::cli::execute_subcommand(ctx.wallet_mut(), command).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let acc_1_balance = sequencer_service_rpc::RpcClient::get_account_balance(
ctx.sequencer_client(),
ctx.existing_public_accounts()[0],
)
.await?;
let acc_2_balance = sequencer_service_rpc::RpcClient::get_account_balance(
ctx.sequencer_client(),
ctx.existing_public_accounts()[1],
)
.await?;
assert_eq!(acc_1_balance, 9900);
assert_eq!(acc_2_balance, 20100);
info!("Waiting for indexer to parse blocks");
tokio::time::sleep(std::time::Duration::from_millis(L2_TO_L1_TIMEOUT_MILLIS)).await;
let acc1_ind_state = ctx
.indexer_client()
.get_account(ctx.existing_public_accounts()[0].into())
.await
.unwrap();
let acc1_seq_state = sequencer_service_rpc::RpcClient::get_account(
ctx.sequencer_client(),
ctx.existing_public_accounts()[0],
)
.await?;
assert_eq!(acc1_ind_state, acc1_seq_state.into());
info!("Indexer state is consistent after label-based transfer");
Ok(())
}

View File

@ -1,3 +1,9 @@
#![expect(
clippy::shadow_unrelated,
clippy::tests_outside_test_module,
reason = "We don't care about these in tests"
)]
use std::{str::FromStr, time::Duration};
use anyhow::{Context, Result};
@ -8,6 +14,7 @@ use integration_tests::{
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
use log::info;
use nssa::{AccountId, program::Program};
use sequencer_service_rpc::RpcClient as _;
use tokio::test;
use wallet::cli::{
Command, SubcommandReturnValue,
@ -313,8 +320,8 @@ async fn restore_keys_from_seed() -> Result<()> {
.get_account_balance(to_account_id4)
.await?;
assert_eq!(acc3.balance, 91); // 102 - 11
assert_eq!(acc4.balance, 114); // 103 + 11
assert_eq!(acc3, 91); // 102 - 11
assert_eq!(acc4, 114); // 103 + 11
info!("Successfully restored keys and verified transactions");

View File

@ -1,3 +1,9 @@
#![expect(
clippy::shadow_unrelated,
clippy::tests_outside_test_module,
reason = "We don't care about these in tests"
)]
use std::time::Duration;
use anyhow::{Context as _, Result};
@ -8,6 +14,7 @@ use integration_tests::{
use key_protocol::key_management::key_tree::chain_index::ChainIndex;
use log::info;
use nssa::program::Program;
use sequencer_service_rpc::RpcClient as _;
use token_core::{TokenDefinition, TokenHolding};
use tokio::test;
use wallet::cli::{
@ -88,8 +95,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id)
.await?
.account;
.await?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
assert_eq!(definition_acc.program_owner, Program::token().id());
@ -106,8 +112,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id)
.await?
.account;
.await?;
// The account must be owned by the token program
assert_eq!(supply_acc.program_owner, Program::token().id());
@ -141,8 +146,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id)
.await?
.account;
.await?;
assert_eq!(supply_acc.program_owner, Program::token().id());
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
assert_eq!(
@ -157,8 +161,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id)
.await?
.account;
.await?;
assert_eq!(recipient_acc.program_owner, Program::token().id());
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
@ -188,8 +191,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id)
.await?
.account;
.await?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
assert_eq!(
@ -205,8 +207,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id)
.await?
.account;
.await?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
@ -238,8 +239,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id)
.await?
.account;
.await?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
assert_eq!(
@ -255,8 +255,7 @@ async fn create_and_transfer_public_token() -> Result<()> {
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id)
.await?
.account;
.await?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
@ -345,8 +344,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id)
.await?
.account;
.await?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
assert_eq!(definition_acc.program_owner, Program::token().id());
@ -413,8 +411,7 @@ async fn create_and_transfer_token_with_private_supply() -> Result<()> {
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id)
.await?
.account;
.await?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
assert_eq!(
@ -516,8 +513,7 @@ async fn create_token_with_private_definition() -> Result<()> {
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id)
.await?
.account;
.await?;
assert_eq!(supply_acc.program_owner, Program::token().id());
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
@ -598,8 +594,7 @@ async fn create_token_with_private_definition() -> Result<()> {
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id_public)
.await?
.account;
.await?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
@ -904,8 +899,7 @@ async fn shielded_token_transfer() -> Result<()> {
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id)
.await?
.account;
.await?;
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
assert_eq!(
token_holding,
@ -1052,8 +1046,7 @@ async fn deshielded_token_transfer() -> Result<()> {
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id)
.await?
.account;
.await?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
token_holding,
@ -1192,3 +1185,193 @@ async fn token_claiming_path_with_private_accounts() -> Result<()> {
Ok(())
}
#[test]
async fn create_token_using_labels() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Create definition and supply accounts with labels
let def_label = "token-definition-label".to_owned();
let supply_label = "token-supply-label".to_owned();
let result = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: Some(def_label.clone()),
})),
)
.await?;
let SubcommandReturnValue::RegisterAccount {
account_id: definition_account_id,
} = result
else {
anyhow::bail!("Expected RegisterAccount return value");
};
let result = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: Some(supply_label.clone()),
})),
)
.await?;
let SubcommandReturnValue::RegisterAccount {
account_id: supply_account_id,
} = result
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create token using account labels instead of IDs
let name = "LABELED TOKEN".to_string();
let total_supply = 100;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: None,
definition_account_label: Some(def_label),
supply_account_id: None,
supply_account_label: Some(supply_label),
name: name.clone(),
total_supply,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let definition_acc = ctx
.sequencer_client()
.get_account(definition_account_id)
.await?;
let token_definition = TokenDefinition::try_from(&definition_acc.data)?;
assert_eq!(definition_acc.program_owner, Program::token().id());
assert_eq!(
token_definition,
TokenDefinition::Fungible {
name,
total_supply,
metadata_id: None
}
);
let supply_acc = ctx
.sequencer_client()
.get_account(supply_account_id)
.await?;
let token_holding = TokenHolding::try_from(&supply_acc.data)?;
assert_eq!(
token_holding,
TokenHolding::Fungible {
definition_id: definition_account_id,
balance: total_supply
}
);
info!("Successfully created token using definition and supply account labels");
Ok(())
}
#[test]
async fn transfer_token_using_from_label() -> Result<()> {
let mut ctx = TestContext::new().await?;
// Create definition account
let result = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: None,
})),
)
.await?;
let SubcommandReturnValue::RegisterAccount {
account_id: definition_account_id,
} = result
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create supply account with a label
let supply_label = "token-supply-sender".to_owned();
let result = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: Some(supply_label.clone()),
})),
)
.await?;
let SubcommandReturnValue::RegisterAccount {
account_id: supply_account_id,
} = result
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create recipient account
let result = wallet::cli::execute_subcommand(
ctx.wallet_mut(),
Command::Account(AccountSubcommand::New(NewSubcommand::Public {
cci: None,
label: None,
})),
)
.await?;
let SubcommandReturnValue::RegisterAccount {
account_id: recipient_account_id,
} = result
else {
anyhow::bail!("Expected RegisterAccount return value");
};
// Create token
let total_supply = 50;
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: Some(format_public_account_id(definition_account_id)),
definition_account_label: None,
supply_account_id: Some(format_public_account_id(supply_account_id)),
supply_account_label: None,
name: "LABEL TEST TOKEN".to_string(),
total_supply,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Transfer token using from_label instead of from
let transfer_amount = 20;
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: None,
from_label: Some(supply_label),
to: Some(format_public_account_id(recipient_account_id)),
to_label: None,
to_npk: None,
to_vpk: None,
amount: transfer_amount,
};
wallet::cli::execute_subcommand(ctx.wallet_mut(), Command::Token(subcommand)).await?;
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let recipient_acc = ctx
.sequencer_client()
.get_account(recipient_account_id)
.await?;
let token_holding = TokenHolding::try_from(&recipient_acc.data)?;
assert_eq!(
token_holding,
TokenHolding::Fungible {
definition_id: definition_account_id,
balance: transfer_amount
}
);
info!("Successfully transferred token using from_label");
Ok(())
}