@@ -123,6 +123,48 @@ impl ConfidentialTokenAccountMeta {
123
123
}
124
124
}
125
125
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
+
126
168
async fn with_tokens < T > (
127
169
token : & Token < T > ,
128
170
owner : & Keypair ,
@@ -774,7 +816,7 @@ async fn ct_transfer() {
774
816
err,
775
817
TokenClientError :: Client ( Box :: new( TransportError :: TransactionError (
776
818
TransactionError :: InstructionError (
777
- 1 ,
819
+ 0 ,
778
820
InstructionError :: Custom (
779
821
TokenError :: MaximumPendingBalanceCreditCounterExceeded as u32
780
822
) ,
@@ -846,7 +888,7 @@ async fn ct_transfer() {
846
888
assert_eq ! (
847
889
err,
848
890
TokenClientError :: Client ( Box :: new( TransportError :: TransactionError (
849
- TransactionError :: InstructionError ( 1 , InstructionError :: InvalidAccountData )
891
+ TransactionError :: InstructionError ( 0 , InstructionError :: InvalidAccountData )
850
892
) ) )
851
893
) ;
852
894
@@ -1049,7 +1091,7 @@ async fn ct_transfer_with_fee() {
1049
1091
assert_eq ! (
1050
1092
err,
1051
1093
TokenClientError :: Client ( Box :: new( TransportError :: TransactionError (
1052
- TransactionError :: InstructionError ( 1 , InstructionError :: InvalidAccountData )
1094
+ TransactionError :: InstructionError ( 0 , InstructionError :: InvalidAccountData )
1053
1095
) ) )
1054
1096
) ;
1055
1097
@@ -1355,3 +1397,221 @@ async fn ct_withdraw_withheld_tokens_from_accounts() {
1355
1397
)
1356
1398
. await ;
1357
1399
}
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