Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 50abadd

Browse files
token-2022: integrate memo into confidential extension (#3587)
* resolve conflict * add test for confidential extension with memo * add test for confidential transfer with memo * change proof instruction order for memo * resolve conflict * minor * rename new_with_memo to new_with_required_memo_transfers * fix failing tests due to rebase * fix failing tests due to rebase
1 parent 1f6e926 commit 50abadd

File tree

3 files changed

+280
-15
lines changed

3 files changed

+280
-15
lines changed

token/program-2022-test/tests/confidential_transfer.rs

Lines changed: 263 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,48 @@ impl ConfidentialTokenAccountMeta {
123123
}
124124
}
125125

126+
async fn new_with_required_memo_transfers<T>(token: &Token<T>, owner: &Keypair) -> Self
127+
where
128+
T: SendTransaction,
129+
{
130+
let token_account_keypair = Keypair::new();
131+
token
132+
.create_auxiliary_token_account_with_extension_space(
133+
&token_account_keypair,
134+
&owner.pubkey(),
135+
vec![
136+
ExtensionType::ConfidentialTransferAccount,
137+
ExtensionType::MemoTransfer,
138+
],
139+
)
140+
.await
141+
.unwrap();
142+
let token_account = token_account_keypair.pubkey();
143+
144+
let elgamal_keypair = ElGamalKeypair::new(owner, &token_account).unwrap();
145+
let ae_key = AeKey::new(owner, &token_account).unwrap();
146+
147+
token
148+
.confidential_transfer_configure_token_account_with_pending_counter(
149+
&token_account,
150+
owner,
151+
TEST_MAXIMUM_PENDING_BALANCE_CREDIT_COUNTER,
152+
)
153+
.await
154+
.unwrap();
155+
156+
token
157+
.enable_required_transfer_memos(&token_account, owner)
158+
.await
159+
.unwrap();
160+
161+
Self {
162+
token_account,
163+
elgamal_keypair,
164+
ae_key,
165+
}
166+
}
167+
126168
async fn with_tokens<T>(
127169
token: &Token<T>,
128170
owner: &Keypair,
@@ -774,7 +816,7 @@ async fn ct_transfer() {
774816
err,
775817
TokenClientError::Client(Box::new(TransportError::TransactionError(
776818
TransactionError::InstructionError(
777-
1,
819+
0,
778820
InstructionError::Custom(
779821
TokenError::MaximumPendingBalanceCreditCounterExceeded as u32
780822
),
@@ -846,7 +888,7 @@ async fn ct_transfer() {
846888
assert_eq!(
847889
err,
848890
TokenClientError::Client(Box::new(TransportError::TransactionError(
849-
TransactionError::InstructionError(1, InstructionError::InvalidAccountData)
891+
TransactionError::InstructionError(0, InstructionError::InvalidAccountData)
850892
)))
851893
);
852894

@@ -1049,7 +1091,7 @@ async fn ct_transfer_with_fee() {
10491091
assert_eq!(
10501092
err,
10511093
TokenClientError::Client(Box::new(TransportError::TransactionError(
1052-
TransactionError::InstructionError(1, InstructionError::InvalidAccountData)
1094+
TransactionError::InstructionError(0, InstructionError::InvalidAccountData)
10531095
)))
10541096
);
10551097

@@ -1355,3 +1397,221 @@ async fn ct_withdraw_withheld_tokens_from_accounts() {
13551397
)
13561398
.await;
13571399
}
1400+
1401+
#[tokio::test]
1402+
async fn ct_transfer_memo() {
1403+
let ConfidentialTransferMintWithKeypairs { ct_mint, .. } =
1404+
ConfidentialTransferMintWithKeypairs::new();
1405+
let mut context = TestContext::new().await;
1406+
context
1407+
.init_token_with_mint(vec![
1408+
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1409+
])
1410+
.await
1411+
.unwrap();
1412+
1413+
let TokenContext {
1414+
token,
1415+
alice,
1416+
bob,
1417+
mint_authority,
1418+
decimals,
1419+
..
1420+
} = context.token_context.unwrap();
1421+
let alice_meta =
1422+
ConfidentialTokenAccountMeta::with_tokens(&token, &alice, &mint_authority, 42, decimals)
1423+
.await;
1424+
let bob_meta =
1425+
ConfidentialTokenAccountMeta::new_with_required_memo_transfers(&token, &bob).await;
1426+
1427+
let state = token
1428+
.get_account_info(&alice_meta.token_account)
1429+
.await
1430+
.unwrap();
1431+
let extension = state
1432+
.get_extension::<ConfidentialTransferAccount>()
1433+
.unwrap();
1434+
1435+
// transfer without memo
1436+
let err = token
1437+
.confidential_transfer_transfer(
1438+
&alice_meta.token_account,
1439+
&bob_meta.token_account,
1440+
&alice,
1441+
42, // amount
1442+
42,
1443+
&extension.available_balance.try_into().unwrap(),
1444+
&bob_meta.elgamal_keypair.public,
1445+
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
1446+
)
1447+
.await
1448+
.unwrap_err();
1449+
1450+
assert_eq!(
1451+
err,
1452+
TokenClientError::Client(Box::new(TransportError::TransactionError(
1453+
TransactionError::InstructionError(
1454+
0,
1455+
InstructionError::Custom(TokenError::NoMemo as u32)
1456+
)
1457+
)))
1458+
);
1459+
1460+
// transfer with memo
1461+
token
1462+
.with_memo("🦖", vec![alice.pubkey()])
1463+
.confidential_transfer_transfer(
1464+
&alice_meta.token_account,
1465+
&bob_meta.token_account,
1466+
&alice,
1467+
42, // amount
1468+
42,
1469+
&extension.available_balance.try_into().unwrap(),
1470+
&bob_meta.elgamal_keypair.public,
1471+
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
1472+
)
1473+
.await
1474+
.unwrap();
1475+
1476+
alice_meta
1477+
.check_balances(
1478+
&token,
1479+
ConfidentialTokenAccountBalances {
1480+
pending_balance_lo: 0,
1481+
pending_balance_hi: 0,
1482+
available_balance: 0,
1483+
decryptable_available_balance: 0,
1484+
},
1485+
)
1486+
.await;
1487+
1488+
bob_meta
1489+
.check_balances(
1490+
&token,
1491+
ConfidentialTokenAccountBalances {
1492+
pending_balance_lo: 42,
1493+
pending_balance_hi: 0,
1494+
available_balance: 0,
1495+
decryptable_available_balance: 0,
1496+
},
1497+
)
1498+
.await;
1499+
}
1500+
1501+
#[tokio::test]
1502+
async fn ct_transfer_with_fee_memo() {
1503+
let ConfidentialTransferMintWithKeypairs { ct_mint, .. } =
1504+
ConfidentialTransferMintWithKeypairs::new();
1505+
1506+
let mut context = TestContext::new().await;
1507+
context
1508+
.init_token_with_mint(vec![
1509+
ExtensionInitializationParams::TransferFeeConfig {
1510+
transfer_fee_config_authority: Some(Pubkey::new_unique()),
1511+
withdraw_withheld_authority: Some(Pubkey::new_unique()),
1512+
transfer_fee_basis_points: TEST_FEE_BASIS_POINTS,
1513+
maximum_fee: TEST_MAXIMUM_FEE,
1514+
},
1515+
ExtensionInitializationParams::ConfidentialTransferMint { ct_mint },
1516+
])
1517+
.await
1518+
.unwrap();
1519+
1520+
let TokenContext {
1521+
token,
1522+
alice,
1523+
bob,
1524+
mint_authority,
1525+
decimals,
1526+
..
1527+
} = context.token_context.unwrap();
1528+
1529+
let epoch_info = test_epoch_info();
1530+
1531+
let alice_meta =
1532+
ConfidentialTokenAccountMeta::with_tokens(&token, &alice, &mint_authority, 100, decimals)
1533+
.await;
1534+
let bob_meta =
1535+
ConfidentialTokenAccountMeta::new_with_required_memo_transfers(&token, &bob).await;
1536+
1537+
let state = token
1538+
.get_account_info(&alice_meta.token_account)
1539+
.await
1540+
.unwrap();
1541+
let extension = state
1542+
.get_extension::<ConfidentialTransferAccount>()
1543+
.unwrap();
1544+
1545+
let err = token
1546+
.confidential_transfer_transfer_with_fee(
1547+
&alice_meta.token_account,
1548+
&bob_meta.token_account,
1549+
&alice,
1550+
100,
1551+
100,
1552+
&extension.available_balance.try_into().unwrap(),
1553+
&bob_meta.elgamal_keypair.public,
1554+
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
1555+
&ct_mint
1556+
.withdraw_withheld_authority_encryption_pubkey
1557+
.try_into()
1558+
.unwrap(),
1559+
&epoch_info,
1560+
)
1561+
.await
1562+
.unwrap_err();
1563+
1564+
assert_eq!(
1565+
err,
1566+
TokenClientError::Client(Box::new(TransportError::TransactionError(
1567+
TransactionError::InstructionError(
1568+
0,
1569+
InstructionError::Custom(TokenError::NoMemo as u32)
1570+
)
1571+
)))
1572+
);
1573+
1574+
token
1575+
.with_memo("🦖", vec![alice.pubkey()])
1576+
.confidential_transfer_transfer_with_fee(
1577+
&alice_meta.token_account,
1578+
&bob_meta.token_account,
1579+
&alice,
1580+
100,
1581+
100,
1582+
&extension.available_balance.try_into().unwrap(),
1583+
&bob_meta.elgamal_keypair.public,
1584+
&ct_mint.auditor_encryption_pubkey.try_into().unwrap(),
1585+
&ct_mint
1586+
.withdraw_withheld_authority_encryption_pubkey
1587+
.try_into()
1588+
.unwrap(),
1589+
&epoch_info,
1590+
)
1591+
.await
1592+
.unwrap();
1593+
1594+
alice_meta
1595+
.check_balances(
1596+
&token,
1597+
ConfidentialTokenAccountBalances {
1598+
pending_balance_lo: 0,
1599+
pending_balance_hi: 0,
1600+
available_balance: 0,
1601+
decryptable_available_balance: 0,
1602+
},
1603+
)
1604+
.await;
1605+
1606+
bob_meta
1607+
.check_balances(
1608+
&token,
1609+
ConfidentialTokenAccountBalances {
1610+
pending_balance_lo: 97,
1611+
pending_balance_hi: 0,
1612+
available_balance: 0,
1613+
decryptable_available_balance: 0,
1614+
},
1615+
)
1616+
.await;
1617+
}

0 commit comments

Comments
 (0)