memo-transfer.ts 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. import * as anchor from '@coral-xyz/anchor';
  2. import type { Program } from '@coral-xyz/anchor';
  3. import { createMemoInstruction } from '@solana/spl-memo';
  4. import { TOKEN_2022_PROGRAM_ID, createAccount, createMint, createTransferInstruction, mintTo } from '@solana/spl-token';
  5. import { Transaction, sendAndConfirmTransaction } from '@solana/web3.js';
  6. import type { MemoTransfer } from '../target/types/memo_transfer';
  7. describe('memo-transfer', () => {
  8. // Configure the client to use the local cluster.
  9. const provider = anchor.AnchorProvider.env();
  10. const connection = provider.connection;
  11. const wallet = provider.wallet as anchor.Wallet;
  12. anchor.setProvider(provider);
  13. const program = anchor.workspace.MemoTransfer as Program<MemoTransfer>;
  14. const mintKeypair = new anchor.web3.Keypair();
  15. const tokenKeypair = new anchor.web3.Keypair();
  16. it('Create Token Account with RequiredMemo extension', async () => {
  17. await createMint(
  18. connection,
  19. wallet.payer, // Payer of the transaction and initialization fees
  20. wallet.publicKey, // Mint Authority
  21. null, // Optional Freeze Authority
  22. 2, // Decimals of Mint
  23. mintKeypair, // Optional keypair
  24. undefined, // Options for confirming the transaction
  25. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  26. );
  27. const transactionSignature = await program.methods
  28. .initialize()
  29. .accounts({
  30. mintAccount: mintKeypair.publicKey,
  31. tokenAccount: tokenKeypair.publicKey,
  32. })
  33. .signers([tokenKeypair])
  34. .rpc({ skipPreflight: true });
  35. console.log('Your transaction signature', transactionSignature);
  36. });
  37. it('Attempt transfer without memo, expect fail', async () => {
  38. // Create a new token account to transfer to
  39. const sourceTokenAccount = await createAccount(
  40. connection,
  41. wallet.payer, // Payer to create Token Account
  42. mintKeypair.publicKey, // Mint Account address
  43. wallet.publicKey, // Token Account owner
  44. new anchor.web3.Keypair(), // Optional keypair,
  45. undefined, // Confirmation options
  46. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  47. );
  48. await mintTo(connection, wallet.payer, mintKeypair.publicKey, sourceTokenAccount, wallet.payer, 1, [], null, TOKEN_2022_PROGRAM_ID);
  49. const transferInstruction = createTransferInstruction(
  50. sourceTokenAccount, // Source Token Account
  51. tokenKeypair.publicKey, // Destination Token Account
  52. wallet.publicKey, // Source Token Account owner
  53. 1, // Amount
  54. undefined, // Additional signers
  55. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  56. );
  57. const transaction = new Transaction().add(transferInstruction);
  58. try {
  59. // Send transaction
  60. await sendAndConfirmTransaction(
  61. connection,
  62. transaction,
  63. [wallet.payer], // Signers
  64. );
  65. } catch (error) {
  66. console.log('\nExpect Error:', error.logs);
  67. }
  68. });
  69. it('Attempt transfer with memo, expect success', async () => {
  70. // Create a new token account to transfer to
  71. const sourceTokenAccount = await createAccount(
  72. connection,
  73. wallet.payer, // Payer to create Token Account
  74. mintKeypair.publicKey, // Mint Account address
  75. wallet.publicKey, // Token Account owner
  76. new anchor.web3.Keypair(), // Optional keypair, default to Associated Token Account
  77. undefined, // Confirmation options
  78. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  79. );
  80. await mintTo(connection, wallet.payer, mintKeypair.publicKey, sourceTokenAccount, wallet.payer, 1, [], null, TOKEN_2022_PROGRAM_ID);
  81. const memoInstruction = createMemoInstruction('hello, world', [wallet.publicKey]);
  82. const transferInstruction = createTransferInstruction(
  83. sourceTokenAccount, // Source Token Account
  84. tokenKeypair.publicKey, // Destination Token Account
  85. wallet.publicKey, // Source Token Account owner
  86. 1, // Amount
  87. undefined, // Additional signers
  88. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  89. );
  90. const transaction = new Transaction().add(memoInstruction, transferInstruction);
  91. const transactionSignature = await sendAndConfirmTransaction(
  92. connection,
  93. transaction,
  94. [wallet.payer], // Signers
  95. );
  96. console.log('Your transaction signature', transactionSignature);
  97. });
  98. it('Disable RequiredMemo extension', async () => {
  99. const transactionSignature = await program.methods
  100. .disable()
  101. .accounts({
  102. tokenAccount: tokenKeypair.publicKey,
  103. })
  104. .rpc({ skipPreflight: true });
  105. console.log('Your transaction signature', transactionSignature);
  106. });
  107. it('Attempt transfer without memo, expect success', async () => {
  108. // Create a new token account to transfer to
  109. const sourceTokenAccount = await createAccount(
  110. connection,
  111. wallet.payer, // Payer to create Token Account
  112. mintKeypair.publicKey, // Mint Account address
  113. wallet.publicKey, // Token Account owner
  114. new anchor.web3.Keypair(), // Optional keypair,
  115. undefined, // Confirmation options
  116. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  117. );
  118. await mintTo(connection, wallet.payer, mintKeypair.publicKey, sourceTokenAccount, wallet.payer, 1, [], null, TOKEN_2022_PROGRAM_ID);
  119. const transferInstruction = createTransferInstruction(
  120. sourceTokenAccount, // Source Token Account
  121. tokenKeypair.publicKey, // Destination Token Account
  122. wallet.publicKey, // Source Token Account owner
  123. 1, // Amount
  124. undefined, // Additional signers
  125. TOKEN_2022_PROGRAM_ID, // Token Extension Program ID
  126. );
  127. const transaction = new Transaction().add(transferInstruction);
  128. const transactionSignature = await sendAndConfirmTransaction(
  129. connection,
  130. transaction,
  131. [wallet.payer], // Signers
  132. );
  133. console.log('Your transaction signature', transactionSignature);
  134. });
  135. });