fix: integration tests

This commit is contained in:
Pravdyvy 2025-12-12 13:40:56 +02:00
parent 0be88d4343
commit 5212d456ab
3 changed files with 575 additions and 507 deletions

View File

@ -434,6 +434,90 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
7
);
// Burn 3 tokens from `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: make_public_account_input_from_str(&definition_account_id.to_string()),
holder: make_public_account_input_from_str(&recipient_account_id.to_string()),
amount: 3,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = seq_client
.get_account(recipient_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
4
);
// Mint 10 tokens at `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()),
holder: Some(make_public_account_input_from_str(
&recipient_account_id.to_string(),
)),
holder_npk: None,
holder_ipk: None,
amount: 10,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = seq_client
.get_account(recipient_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
14
);
}
/// This test creates a new private token using the token program. After creating the token, the
@ -590,6 +674,188 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
.get_private_account_commitment(&recipient_account_id)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Burn 3 tokens from `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: make_public_account_input_from_str(&definition_account_id.to_string()),
holder: make_private_account_input_from_str(&recipient_account_id.to_string()),
amount: 3,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
let new_commitment2 = wallet_storage
.get_private_account_commitment(&recipient_account_id)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = wallet_storage
.get_account_private(&recipient_account_id)
.unwrap();
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
11
);
// Mint 10 tokens at `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()),
holder: Some(make_private_account_input_from_str(
&recipient_account_id.to_string(),
)),
holder_npk: None,
holder_ipk: None,
amount: 10,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
let new_commitment2 = wallet_storage
.get_private_account_commitment(&recipient_account_id)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = wallet_storage
.get_account_private(&recipient_account_id)
.unwrap();
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
21
);
// Now the same mint, but in foreign way
// Create new account for receiving a mint transaction
let SubcommandReturnValue::RegisterAccount {
account_id: recipient_account_id2,
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
NewSubcommand::Private { cci: None },
)))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
let (holder_keys, _) = wallet_storage
.storage
.user_data
.get_private_account(&recipient_account_id2)
.unwrap();
// Mint 9 tokens at `recipient_acc2`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()),
holder: None,
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
holder_ipk: Some(hex::encode(
holder_keys.incoming_viewing_public_key.0.clone(),
)),
amount: 9,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Sync to claim holder
let command = Command::Account(AccountSubcommand::SyncPrivate {});
wallet::cli::execute_subcommand(command).await.unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
let new_commitment2 = wallet_storage
.get_private_account_commitment(&recipient_account_id2)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Check the status of the account at `recipient_account_id2` is the expected after the
// execution
let recipient_acc = wallet_storage
.get_account_private(&recipient_account_id2)
.unwrap();
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
9
);
}
/// This test creates a new private token using the token program. All accounts are private
@ -673,6 +939,277 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Create new account for receiving a mint transaction
let SubcommandReturnValue::RegisterAccount {
account_id: recipient_account_id_pr,
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
NewSubcommand::Private { cci: None },
)))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};
// Create new account for receiving a mint transaction
let SubcommandReturnValue::RegisterAccount {
account_id: recipient_account_id_pub,
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
NewSubcommand::Public { cci: None },
)))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};
// Mint 10 tokens at `recipient_acc_pub`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_private_account_input_from_str(&definition_account_id.to_string()),
holder: Some(make_public_account_input_from_str(
&recipient_account_id_pub.to_string(),
)),
holder_npk: None,
holder_ipk: None,
amount: 10,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = wallet_storage
.get_account_private(&definition_account_id)
.unwrap();
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the account at `recipient_account_id_pub` is the expected after the
// execution
let recipient_acc_pub = seq_client
.get_account(recipient_account_id_pub.to_string())
.await
.unwrap()
.account;
assert_eq!(
u128::from_le_bytes(recipient_acc_pub.data[33..].try_into().unwrap()),
10
);
let (holder_keys, _) = wallet_storage
.storage
.user_data
.get_private_account(&recipient_account_id_pr)
.unwrap();
// Mint 5 tokens at `recipient_acc_pr`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_private_account_input_from_str(&definition_account_id.to_string()),
holder: None,
holder_npk: Some(hex::encode(holder_keys.nullifer_public_key.0)),
holder_ipk: Some(hex::encode(
holder_keys.incoming_viewing_public_key.0.clone(),
)),
amount: 5,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Sync to claim holder
let command = Command::Account(AccountSubcommand::SyncPrivate {});
wallet::cli::execute_subcommand(command).await.unwrap();
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = wallet_storage
.get_account_private(&definition_account_id)
.unwrap();
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
let new_commitment2 = wallet_storage
.get_private_account_commitment(&recipient_account_id_pr)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Check the status of the account at `recipient_account_id_pr` is the expected after the
// execution
let recipient_acc_pr = wallet_storage
.get_account_private(&recipient_account_id_pr)
.unwrap();
assert_eq!(
u128::from_le_bytes(recipient_acc_pr.data[33..].try_into().unwrap()),
5
);
// Mint 5 tokens at `recipient_acc_pr`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_private_account_input_from_str(&definition_account_id.to_string()),
holder: Some(make_private_account_input_from_str(
&recipient_account_id_pr.to_string(),
)),
holder_npk: None,
holder_ipk: None,
amount: 5,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = wallet_storage
.get_account_private(&definition_account_id)
.unwrap();
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
let new_commitment2 = wallet_storage
.get_private_account_commitment(&recipient_account_id_pr)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Check the status of the account at `recipient_account_id_pr` is the expected after the
// execution
let recipient_acc = wallet_storage
.get_account_private(&recipient_account_id_pr)
.unwrap();
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
10
);
// Burn 5 tokens at `recipient_acc_pub`
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: make_private_account_input_from_str(&definition_account_id.to_string()),
holder: make_public_account_input_from_str(&recipient_account_id_pub.to_string()),
amount: 5,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = wallet_storage
.get_account_private(&definition_account_id)
.unwrap();
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the account at `recipient_account_id_pub` is the expected after the
// execution
let recipient_acc_pub = seq_client
.get_account(recipient_account_id_pub.to_string())
.await
.unwrap()
.account;
assert_eq!(
u128::from_le_bytes(recipient_acc_pub.data[33..].try_into().unwrap()),
5
);
// Burn 5 tokens at `recipient_acc_pr`
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: make_private_account_input_from_str(&definition_account_id.to_string()),
holder: make_private_account_input_from_str(&recipient_account_id_pr.to_string()),
amount: 5,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let wallet_config = fetch_config().await.unwrap();
let wallet_storage = WalletCore::start_from_config_update_chain(wallet_config)
.await
.unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = wallet_storage
.get_account_private(&definition_account_id)
.unwrap();
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 47, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
let new_commitment2 = wallet_storage
.get_private_account_commitment(&recipient_account_id_pr)
.unwrap();
assert!(verify_commitment_is_in_state(new_commitment2, &seq_client).await);
// Check the status of the account at `recipient_account_id_pr` is the expected after the
// execution
let recipient_acc = wallet_storage
.get_account_private(&recipient_account_id_pr)
.unwrap();
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
5
);
}
/// This test creates a new private token using the token program. All accounts are private
@ -1548,250 +2085,6 @@ pub fn prepare_function_map() -> HashMap<String, TestFunction> {
info!("Success!");
}
/// This test creates a new token using the token program. After creating the token, the test
/// executes a token transfer to a new account then mint, then burn.
#[nssa_integration_test]
pub async fn test_success_token_program_burn_mint() {
info!("########## test_success_token_program_burn_mint ##########");
let wallet_config = fetch_config().await.unwrap();
// Create new account for the token definition
let SubcommandReturnValue::RegisterAccount {
account_id: definition_account_id,
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
NewSubcommand::Public { cci: None },
)))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};
// Create new account for the token supply holder
let SubcommandReturnValue::RegisterAccount {
account_id: supply_account_id,
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
NewSubcommand::Public { cci: None },
)))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};
// Create new account for receiving a token transaction
let SubcommandReturnValue::RegisterAccount {
account_id: recipient_account_id,
} = wallet::cli::execute_subcommand(Command::Account(AccountSubcommand::New(
NewSubcommand::Public { cci: None },
)))
.await
.unwrap()
else {
panic!("invalid subcommand return value");
};
// Create new token
let subcommand = TokenProgramAgnosticSubcommand::New {
definition_account_id: make_public_account_input_from_str(
&definition_account_id.to_string(),
),
supply_account_id: make_public_account_input_from_str(&supply_account_id.to_string()),
name: "A NAME".to_string(),
total_supply: 37,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
let seq_client = SequencerClient::new(wallet_config.sequencer_addr.clone()).unwrap();
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(definition_acc.program_owner, Program::token().id());
// The data of a token definition account has the following layout:
// [ 0x00 || name (6 bytes) || total supply (little endian 16 bytes) ]
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 37, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the token holding account with the total supply is the expected after
// the execution
let supply_acc = seq_client
.get_account(supply_account_id.to_string())
.await
.unwrap()
.account;
// The account must be owned by the token program
assert_eq!(supply_acc.program_owner, Program::token().id());
// The data of a token definition account has the following layout:
// [ 0x01 || corresponding_token_definition_id (32 bytes) || balance (little endian 16
// bytes) ] First byte of the data equal to 1 means it's a token holding account
assert_eq!(supply_acc.data.as_ref()[0], 1);
// Bytes from 1 to 33 represent the id of the token this account is associated with.
// In this example, this is a token account of the newly created token, so it is expected
// to be equal to the account_id of the token definition account.
assert_eq!(
&supply_acc.data.as_ref()[1..33],
definition_account_id.to_bytes()
);
assert_eq!(
u128::from_le_bytes(supply_acc.data[33..].try_into().unwrap()),
37
);
// Transfer 7 tokens from `supply_acc` to the account at account_id `recipient_account_id`
let subcommand = TokenProgramAgnosticSubcommand::Send {
from: make_public_account_input_from_str(&supply_account_id.to_string()),
to: Some(make_public_account_input_from_str(
&recipient_account_id.to_string(),
)),
to_npk: None,
to_ipk: None,
amount: 7,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the account at `supply_account_id` is the expected after the
// execution
let supply_acc = seq_client
.get_account(supply_account_id.to_string())
.await
.unwrap()
.account;
// The account must be owned by the token program
assert_eq!(supply_acc.program_owner, Program::token().id());
// First byte equal to 1 means it's a token holding account
assert_eq!(supply_acc.data[0], 1);
// Bytes from 1 to 33 represent the id of the token this account is associated with.
assert_eq!(&supply_acc.data[1..33], definition_account_id.to_bytes());
assert_eq!(
u128::from_le_bytes(supply_acc.data[33..].try_into().unwrap()),
30
);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = seq_client
.get_account(recipient_account_id.to_string())
.await
.unwrap()
.account;
// The account must be owned by the token program
assert_eq!(recipient_acc.program_owner, Program::token().id());
// First byte equal to 1 means it's a token holding account
assert_eq!(recipient_acc.data[0], 1);
// Bytes from 1 to 33 represent the id of the token this account is associated with.
assert_eq!(&recipient_acc.data[1..33], definition_account_id.to_bytes());
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
7
);
// Burn 3 tokens from `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Burn {
definition: Some(make_public_account_input_from_str(
&definition_account_id.to_string(),
)),
definition_npk: None,
definition_ipk: None,
holder: make_public_account_input_from_str(&recipient_account_id.to_string()),
amount: 3,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = seq_client
.get_account(recipient_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
4
);
// Mint 10 tokens at `recipient_acc`
let subcommand = TokenProgramAgnosticSubcommand::Mint {
definition: make_public_account_input_from_str(&definition_account_id.to_string()),
holder: Some(make_public_account_input_from_str(
&recipient_account_id.to_string(),
)),
holder_npk: None,
holder_ipk: None,
amount: 10,
};
wallet::cli::execute_subcommand(Command::Token(subcommand))
.await
.unwrap();
info!("Waiting for next block creation");
tokio::time::sleep(Duration::from_secs(TIME_TO_WAIT_FOR_BLOCK_SECONDS)).await;
// Check the status of the token definition account is the expected after the execution
let definition_acc = seq_client
.get_account(definition_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
definition_acc.data.as_ref(),
&[
0, 65, 32, 78, 65, 77, 69, 44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
);
// Check the status of the account at `recipient_account_id` is the expected after the
// execution
let recipient_acc = seq_client
.get_account(recipient_account_id.to_string())
.await
.unwrap()
.account;
assert_eq!(
u128::from_le_bytes(recipient_acc.data[33..].try_into().unwrap()),
14
);
}
#[nssa_integration_test]
pub async fn test_pinata() {
info!("########## test_pinata ##########");

View File

@ -4,7 +4,7 @@ use common::transaction::NSSATransaction;
use nssa::AccountId;
use crate::{
AccDecodeData::{Decode, Skip},
AccDecodeData::Decode,
WalletCore,
cli::{SubcommandReturnValue, WalletSubcommand},
helperfunctions::{AccountPrivacyKind, parse_addr_with_privacy_prefix},
@ -54,20 +54,14 @@ pub enum TokenProgramAgnosticSubcommand {
///
/// `holder` is owned
///
/// If `definition` is private, then `definition` and (`definition_npk` , `definition_ipk`) is a
/// mutually exclusive patterns.
/// Also if `definition` is private then it is owned, because
/// we can not modify foreign accounts.
///
/// First is used for owned accounts, second otherwise.
/// ToDo: Return and add foreign variant when we could modify foreign accounts
Burn {
/// definition - valid 32 byte base58 string with privacy prefix
#[arg(long)]
definition: Option<String>,
/// definition_npk - valid 32 byte hex string
#[arg(long)]
definition_npk: Option<String>,
/// definition_ipk - valid 33 byte hex string
#[arg(long)]
definition_ipk: Option<String>,
definition: String,
/// holder - valid 32 byte base58 string with privacy prefix
#[arg(long)]
holder: String,
@ -256,89 +250,50 @@ impl WalletSubcommand for TokenProgramAgnosticSubcommand {
}
TokenProgramAgnosticSubcommand::Burn {
definition,
definition_npk,
definition_ipk,
holder,
amount,
} => {
let underlying_subcommand = match (definition, definition_npk, definition_ipk) {
(None, None, None) => {
anyhow::bail!(
"Provide either account account_id of definition or their public keys"
);
}
(Some(_), Some(_), Some(_)) => {
anyhow::bail!(
"Provide only one variant: either account_id of definition or their public keys"
);
}
(_, Some(_), None) | (_, None, Some(_)) => {
anyhow::bail!("List of public keys is uncomplete");
}
(Some(definition), None, None) => {
let (definition, definition_privacy) =
parse_addr_with_privacy_prefix(&definition)?;
let (holder, holder_privacy) = parse_addr_with_privacy_prefix(&holder)?;
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,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::BurnTokenPrivateOwned {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Deshielded(
TokenProgramSubcommandDeshielded::BurnTokenDeshieldedOwned {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Shielded(
TokenProgramSubcommandShielded::BurnTokenShielded {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
match (definition_privacy, holder_privacy) {
(AccountPrivacyKind::Public, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Public(
TokenProgramSubcommandPublic::BurnToken {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
}
(None, Some(definition_npk), Some(definition_ipk)) => {
let (holder, holder_privacy) = parse_addr_with_privacy_prefix(&holder)?;
match holder_privacy {
AccountPrivacyKind::Private => TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::BurnTokenPrivateForeign {
definition_npk,
definition_ipk,
(AccountPrivacyKind::Private, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Private(
TokenProgramSubcommandPrivate::BurnTokenPrivateOwned {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
),
AccountPrivacyKind::Public => TokenProgramSubcommand::Deshielded(
TokenProgramSubcommandDeshielded::BurnTokenDeshieldedForeign {
definition_npk,
definition_ipk,
)
}
(AccountPrivacyKind::Private, AccountPrivacyKind::Public) => {
TokenProgramSubcommand::Deshielded(
TokenProgramSubcommandDeshielded::BurnTokenDeshieldedOwned {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
),
)
}
(AccountPrivacyKind::Public, AccountPrivacyKind::Private) => {
TokenProgramSubcommand::Shielded(
TokenProgramSubcommandShielded::BurnTokenShielded {
definition_account_id: definition,
holder_account_id: holder,
amount,
},
)
}
}
};
@ -536,17 +491,6 @@ pub enum TokenProgramSubcommandPrivate {
#[arg(short, long)]
amount: u128,
},
// Burn tokens using the token program
BurnTokenPrivateForeign {
#[arg(short, long)]
definition_npk: String,
#[arg(short, long)]
definition_ipk: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
// Transfer tokens using the token program
MintTokenPrivateForeign {
#[arg(short, long)]
@ -590,17 +534,6 @@ pub enum TokenProgramSubcommandDeshielded {
#[arg(short, long)]
amount: u128,
},
// Burn tokens using the token program
BurnTokenDeshieldedForeign {
#[arg(short, long)]
definition_npk: String,
#[arg(short, long)]
definition_ipk: String,
#[arg(short, long)]
holder_account_id: String,
#[arg(short, long)]
amount: u128,
},
}
/// Represents generic shielded CLI subcommand for a wallet working with token_program
@ -906,57 +839,6 @@ impl WalletSubcommand for TokenProgramSubcommandPrivate {
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommandPrivate::BurnTokenPrivateForeign {
definition_npk,
definition_ipk,
holder_account_id,
amount,
} => {
let definition_npk_res = hex::decode(definition_npk)?;
let mut definition_npk = [0; 32];
definition_npk.copy_from_slice(&definition_npk_res);
let definition_npk = nssa_core::NullifierPublicKey(definition_npk);
let definition_ipk_res = hex::decode(definition_ipk)?;
let mut definition_ipk = [0u8; 33];
definition_ipk.copy_from_slice(&definition_ipk_res);
let definition_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
definition_ipk.to_vec(),
);
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (res, [_, secret_holder]) = Token(wallet_core)
.send_burn_transaction_private_foreign_account(
definition_npk,
definition_ipk,
holder_account_id,
amount,
)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
let acc_decode_data = vec![Skip, Decode(secret_holder, holder_account_id)];
wallet_core.decode_insert_privacy_preserving_transaction_results(
tx,
&acc_decode_data,
)?;
}
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommandPrivate::MintTokenPrivateOwned {
definition_account_id,
holder_account_id,
@ -1135,52 +1017,6 @@ impl WalletSubcommand for TokenProgramSubcommandDeshielded {
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommandDeshielded::BurnTokenDeshieldedForeign {
definition_npk,
definition_ipk,
holder_account_id,
amount,
} => {
let definition_npk_res = hex::decode(definition_npk)?;
let mut definition_npk = [0; 32];
definition_npk.copy_from_slice(&definition_npk_res);
let definition_npk = nssa_core::NullifierPublicKey(definition_npk);
let definition_ipk_res = hex::decode(definition_ipk)?;
let mut definition_ipk = [0u8; 33];
definition_ipk.copy_from_slice(&definition_ipk_res);
let definition_ipk = nssa_core::encryption::shared_key_derivation::Secp256k1Point(
definition_ipk.to_vec(),
);
let holder_account_id: AccountId = holder_account_id.parse().unwrap();
let (res, _) = Token(wallet_core)
.send_burn_transaction_deshielded_foreign_account(
definition_npk,
definition_ipk,
holder_account_id,
amount,
)
.await?;
println!("Results of tx send are {res:#?}");
let tx_hash = res.tx_hash;
let transfer_tx = wallet_core
.poll_native_token_transfer(tx_hash.clone())
.await?;
if let NSSATransaction::PrivacyPreserving(tx) = transfer_tx {
println!("Transaction data is {:?}", tx.message);
}
let path = wallet_core.store_persistent_data().await?;
println!("Stored persistent accounts at {path:#?}");
Ok(SubcommandReturnValue::PrivacyPreservingTransfer { tx_hash })
}
TokenProgramSubcommandDeshielded::MintTokenDeshielded {
definition_account_id,
holder_account_id,

View File

@ -367,36 +367,6 @@ impl Token<'_> {
})
}
pub async fn send_burn_transaction_private_foreign_account(
&self,
definition_npk: NullifierPublicKey,
definition_ipk: IncomingViewingPublicKey,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, [SharedSecretKey; 2]), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_burn(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateForeign {
npk: definition_npk,
ipk: definition_ipk,
},
PrivacyPreservingAccount::PrivateOwned(holder_account_id),
],
&instruction_data,
&program,
)
.await
.map(|(resp, secrets)| {
let mut iter = secrets.into_iter();
let first = iter.next().expect("expected definition's secret");
let second = iter.next().expect("expected holder's secret");
(resp, [first, second])
})
}
pub async fn send_burn_transaction_deshielded_owned_account(
&self,
definition_account_id: AccountId,
@ -451,37 +421,6 @@ impl Token<'_> {
})
}
pub async fn send_burn_transaction_deshielded_foreign_account(
&self,
definition_npk: NullifierPublicKey,
definition_ipk: IncomingViewingPublicKey,
holder_account_id: AccountId,
amount: u128,
) -> Result<(SendTxResponse, SharedSecretKey), ExecutionFailureKind> {
let (instruction_data, program) = token_program_preparation_burn(amount);
self.0
.send_privacy_preserving_tx(
vec![
PrivacyPreservingAccount::PrivateForeign {
npk: definition_npk,
ipk: definition_ipk,
},
PrivacyPreservingAccount::Public(holder_account_id),
],
&instruction_data,
&program,
)
.await
.map(|(resp, secrets)| {
let first = secrets
.into_iter()
.next()
.expect("expected definition's secret");
(resp, first)
})
}
pub async fn send_mint_transaction(
&self,
definition_account_id: AccountId,