|
8 | 8 | pubkey::Pubkey,
|
9 | 9 | signature::Signer,
|
10 | 10 | signer::{keypair::Keypair, signers::Signers},
|
11 |
| - transaction::TransactionError, |
| 11 | + system_instruction, |
| 12 | + transaction::{Transaction, TransactionError}, |
12 | 13 | transport::TransportError,
|
13 | 14 | },
|
| 15 | + spl_elgamal_registry::state::ELGAMAL_REGISTRY_ACCOUNT_LEN, |
14 | 16 | spl_record::state::RecordData,
|
15 | 17 | spl_token_2022::{
|
16 | 18 | error::TokenError,
|
17 | 19 | extension::{
|
18 | 20 | confidential_transfer::{
|
19 |
| - ConfidentialTransferAccount, ConfidentialTransferMint, DecryptableBalance, |
| 21 | + self, ConfidentialTransferAccount, ConfidentialTransferMint, DecryptableBalance, |
20 | 22 | },
|
21 | 23 | confidential_transfer_fee::{
|
22 | 24 | account_info::WithheldTokensInfo, ConfidentialTransferFeeAmount,
|
23 | 25 | ConfidentialTransferFeeConfig,
|
24 | 26 | },
|
25 |
| - transfer_fee::TransferFee, |
| 27 | + transfer_fee::{TransferFee, TransferFeeAmount}, |
26 | 28 | BaseStateWithExtensions, ExtensionType,
|
27 | 29 | },
|
28 | 30 | instruction,
|
|
37 | 39 | TokenResult,
|
38 | 40 | },
|
39 | 41 | },
|
| 42 | + spl_token_confidential_transfer_proof_extraction::instruction::{ProofData, ProofLocation}, |
40 | 43 | std::convert::TryInto,
|
41 | 44 | };
|
42 | 45 |
|
@@ -1207,3 +1210,126 @@ async fn confidential_transfer_harvest_withheld_tokens_to_mint() {
|
1207 | 1210 |
|
1208 | 1211 | check_withheld_amount_in_mint(&token, &withdraw_withheld_authority_elgamal_keypair, fee).await;
|
1209 | 1212 | }
|
| 1213 | + |
| 1214 | +#[tokio::test] |
| 1215 | +async fn confidential_transfer_configure_token_account_with_fee_with_registry() { |
| 1216 | + let transfer_fee_authority = Keypair::new(); |
| 1217 | + let withdraw_withheld_authority = Keypair::new(); |
| 1218 | + |
| 1219 | + let confidential_transfer_authority = Keypair::new(); |
| 1220 | + let auto_approve_new_accounts = true; |
| 1221 | + let auditor_elgamal_keypair = ElGamalKeypair::new_rand(); |
| 1222 | + let auditor_elgamal_pubkey = (*auditor_elgamal_keypair.pubkey()).into(); |
| 1223 | + |
| 1224 | + let confidential_transfer_fee_authority = Keypair::new(); |
| 1225 | + let withdraw_withheld_authority_elgamal_keypair = ElGamalKeypair::new_rand(); |
| 1226 | + let withdraw_withheld_authority_elgamal_pubkey = |
| 1227 | + (*withdraw_withheld_authority_elgamal_keypair.pubkey()).into(); |
| 1228 | + |
| 1229 | + let mut context = TestContext::new().await; |
| 1230 | + context |
| 1231 | + .init_token_with_mint(vec![ |
| 1232 | + ExtensionInitializationParams::TransferFeeConfig { |
| 1233 | + transfer_fee_config_authority: Some(transfer_fee_authority.pubkey()), |
| 1234 | + withdraw_withheld_authority: Some(withdraw_withheld_authority.pubkey()), |
| 1235 | + transfer_fee_basis_points: TEST_FEE_BASIS_POINTS, |
| 1236 | + maximum_fee: TEST_MAXIMUM_FEE, |
| 1237 | + }, |
| 1238 | + ExtensionInitializationParams::ConfidentialTransferMint { |
| 1239 | + authority: Some(confidential_transfer_authority.pubkey()), |
| 1240 | + auto_approve_new_accounts, |
| 1241 | + auditor_elgamal_pubkey: Some(auditor_elgamal_pubkey), |
| 1242 | + }, |
| 1243 | + ExtensionInitializationParams::ConfidentialTransferFeeConfig { |
| 1244 | + authority: Some(confidential_transfer_fee_authority.pubkey()), |
| 1245 | + withdraw_withheld_authority_elgamal_pubkey, |
| 1246 | + }, |
| 1247 | + ]) |
| 1248 | + .await |
| 1249 | + .unwrap(); |
| 1250 | + |
| 1251 | + let TokenContext { token, alice, .. } = context.token_context.unwrap(); |
| 1252 | + let elgamal_keypair = ElGamalKeypair::new_rand(); |
| 1253 | + |
| 1254 | + // create ElGamal registry |
| 1255 | + let ctx = context.context.lock().await; |
| 1256 | + let proof_data = |
| 1257 | + confidential_transfer::instruction::PubkeyValidityProofData::new(&elgamal_keypair).unwrap(); |
| 1258 | + let proof_location = ProofLocation::InstructionOffset( |
| 1259 | + 1.try_into().unwrap(), |
| 1260 | + ProofData::InstructionData(&proof_data), |
| 1261 | + ); |
| 1262 | + |
| 1263 | + let elgamal_registry_address = spl_elgamal_registry::get_elgamal_registry_address( |
| 1264 | + &alice.pubkey(), |
| 1265 | + &spl_elgamal_registry::id(), |
| 1266 | + ); |
| 1267 | + |
| 1268 | + let rent = ctx.banks_client.get_rent().await.unwrap(); |
| 1269 | + let space = ELGAMAL_REGISTRY_ACCOUNT_LEN; |
| 1270 | + let system_instruction = system_instruction::transfer( |
| 1271 | + &ctx.payer.pubkey(), |
| 1272 | + &elgamal_registry_address, |
| 1273 | + rent.minimum_balance(space), |
| 1274 | + ); |
| 1275 | + let create_registry_instructions = |
| 1276 | + spl_elgamal_registry::instruction::create_registry(&alice.pubkey(), proof_location) |
| 1277 | + .unwrap(); |
| 1278 | + |
| 1279 | + let instructions = [&[system_instruction], &create_registry_instructions[..]].concat(); |
| 1280 | + let tx = Transaction::new_signed_with_payer( |
| 1281 | + &instructions, |
| 1282 | + Some(&ctx.payer.pubkey()), |
| 1283 | + &[&ctx.payer, &alice], |
| 1284 | + ctx.last_blockhash, |
| 1285 | + ); |
| 1286 | + ctx.banks_client.process_transaction(tx).await.unwrap(); |
| 1287 | + |
| 1288 | + let payer_pubkey = ctx.payer.pubkey(); |
| 1289 | + drop(ctx); |
| 1290 | + |
| 1291 | + // configure account using ElGamal registry |
| 1292 | + let alice_account_keypair = Keypair::new(); |
| 1293 | + let alice_token_account = alice_account_keypair.pubkey(); |
| 1294 | + token |
| 1295 | + .create_auxiliary_token_account_with_extension_space( |
| 1296 | + &alice_account_keypair, |
| 1297 | + &alice.pubkey(), |
| 1298 | + vec![], // do not allocate space for confidential transfer fees |
| 1299 | + ) |
| 1300 | + .await |
| 1301 | + .unwrap(); |
| 1302 | + |
| 1303 | + token |
| 1304 | + .confidential_transfer_configure_token_account_with_registry( |
| 1305 | + &alice_account_keypair.pubkey(), |
| 1306 | + &elgamal_registry_address, |
| 1307 | + Some(&payer_pubkey), // test account allocation |
| 1308 | + ) |
| 1309 | + .await |
| 1310 | + .unwrap(); |
| 1311 | + |
| 1312 | + let state = token.get_account_info(&alice_token_account).await.unwrap(); |
| 1313 | + let confidential_transfer_account = state |
| 1314 | + .get_extension::<ConfidentialTransferAccount>() |
| 1315 | + .unwrap(); |
| 1316 | + assert!(bool::from(&confidential_transfer_account.approved)); |
| 1317 | + assert!(bool::from( |
| 1318 | + &confidential_transfer_account.allow_confidential_credits |
| 1319 | + )); |
| 1320 | + assert_eq!( |
| 1321 | + confidential_transfer_account.elgamal_pubkey, |
| 1322 | + (*elgamal_keypair.pubkey()).into() |
| 1323 | + ); |
| 1324 | + |
| 1325 | + let transfer_fee = state.get_extension::<TransferFeeAmount>().unwrap(); |
| 1326 | + assert_eq!(transfer_fee.withheld_amount, 0.into()); |
| 1327 | + |
| 1328 | + let confidential_transfer_fee = state |
| 1329 | + .get_extension::<ConfidentialTransferFeeAmount>() |
| 1330 | + .unwrap(); |
| 1331 | + assert_eq!( |
| 1332 | + confidential_transfer_fee.withheld_amount, |
| 1333 | + PodElGamalCiphertext::default(), |
| 1334 | + ); |
| 1335 | +} |
0 commit comments