memo-transfer.ts 6.0 KB

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