escrow.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. const anchor = require("@project-serum/anchor");
  2. const { TOKEN_PROGRAM_ID, Token } = require("@solana/spl-token");
  3. const assert = require("assert");
  4. describe("escrow", () => {
  5. const provider = anchor.Provider.env();
  6. anchor.setProvider(provider);
  7. const program = anchor.workspace.Escrow;
  8. let mintA = null;
  9. let mintB = null;
  10. let initializerTokenAccountA = null;
  11. let initializerTokenAccountB = null;
  12. let takerTokenAccountA = null;
  13. let takerTokenAccountB = null;
  14. let pda = null;
  15. const takerAmount = 1000;
  16. const initializerAmount = 500;
  17. const escrowAccount = anchor.web3.Keypair.generate();
  18. const payer = anchor.web3.Keypair.generate();
  19. const mintAuthority = anchor.web3.Keypair.generate();
  20. it("Initialise escrow state", async () => {
  21. // Airdropping tokens to a payer.
  22. await provider.connection.confirmTransaction(
  23. await provider.connection.requestAirdrop(payer.publicKey, 10000000000),
  24. "confirmed"
  25. );
  26. mintA = await Token.createMint(
  27. provider.connection,
  28. payer,
  29. mintAuthority.publicKey,
  30. null,
  31. 0,
  32. TOKEN_PROGRAM_ID
  33. );
  34. mintB = await Token.createMint(
  35. provider.connection,
  36. payer,
  37. mintAuthority.publicKey,
  38. null,
  39. 0,
  40. TOKEN_PROGRAM_ID
  41. );
  42. initializerTokenAccountA = await mintA.createAccount(provider.wallet.publicKey);
  43. takerTokenAccountA = await mintA.createAccount(provider.wallet.publicKey);
  44. initializerTokenAccountB = await mintB.createAccount(provider.wallet.publicKey);
  45. takerTokenAccountB = await mintB.createAccount(provider.wallet.publicKey);
  46. await mintA.mintTo(
  47. initializerTokenAccountA,
  48. mintAuthority.publicKey,
  49. [mintAuthority],
  50. initializerAmount
  51. );
  52. await mintB.mintTo(
  53. takerTokenAccountB,
  54. mintAuthority.publicKey,
  55. [mintAuthority],
  56. takerAmount
  57. );
  58. let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
  59. let _takerTokenAccountB = await mintB.getAccountInfo(takerTokenAccountB);
  60. assert.ok(_initializerTokenAccountA.amount.toNumber() == initializerAmount);
  61. assert.ok(_takerTokenAccountB.amount.toNumber() == takerAmount);
  62. });
  63. it("Initialize escrow", async () => {
  64. await program.rpc.initializeEscrow(
  65. new anchor.BN(initializerAmount),
  66. new anchor.BN(takerAmount),
  67. {
  68. accounts: {
  69. initializer: provider.wallet.publicKey,
  70. initializerDepositTokenAccount: initializerTokenAccountA,
  71. initializerReceiveTokenAccount: initializerTokenAccountB,
  72. escrowAccount: escrowAccount.publicKey,
  73. tokenProgram: TOKEN_PROGRAM_ID,
  74. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  75. },
  76. instructions: [
  77. await program.account.escrowAccount.createInstruction(escrowAccount),
  78. ],
  79. signers: [escrowAccount],
  80. }
  81. );
  82. // Get the PDA that is assigned authority to token account.
  83. const [_pda, _nonce] = await anchor.web3.PublicKey.findProgramAddress(
  84. [Buffer.from(anchor.utils.bytes.utf8.encode("escrow"))],
  85. program.programId
  86. );
  87. pda = _pda;
  88. let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
  89. let _escrowAccount = await program.account.escrowAccount.fetch(
  90. escrowAccount.publicKey
  91. );
  92. // Check that the new owner is the PDA.
  93. assert.ok(_initializerTokenAccountA.owner.equals(pda));
  94. // Check that the values in the escrow account match what we expect.
  95. assert.ok(_escrowAccount.initializerKey.equals(provider.wallet.publicKey));
  96. assert.ok(_escrowAccount.initializerAmount.toNumber() == initializerAmount);
  97. assert.ok(_escrowAccount.takerAmount.toNumber() == takerAmount);
  98. assert.ok(
  99. _escrowAccount.initializerDepositTokenAccount.equals(initializerTokenAccountA)
  100. );
  101. assert.ok(
  102. _escrowAccount.initializerReceiveTokenAccount.equals(initializerTokenAccountB)
  103. );
  104. });
  105. it("Exchange escrow", async () => {
  106. await program.rpc.exchange({
  107. accounts: {
  108. taker: provider.wallet.publicKey,
  109. takerDepositTokenAccount: takerTokenAccountB,
  110. takerReceiveTokenAccount: takerTokenAccountA,
  111. pdaDepositTokenAccount: initializerTokenAccountA,
  112. initializerReceiveTokenAccount: initializerTokenAccountB,
  113. initializerMainAccount: provider.wallet.publicKey,
  114. escrowAccount: escrowAccount.publicKey,
  115. pdaAccount: pda,
  116. tokenProgram: TOKEN_PROGRAM_ID,
  117. },
  118. });
  119. let _takerTokenAccountA = await mintA.getAccountInfo(takerTokenAccountA);
  120. let _takerTokenAccountB = await mintB.getAccountInfo(takerTokenAccountB);
  121. let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
  122. let _initializerTokenAccountB = await mintB.getAccountInfo(initializerTokenAccountB);
  123. // Check that the initializer gets back ownership of their token account.
  124. assert.ok(_takerTokenAccountA.owner.equals(provider.wallet.publicKey));
  125. assert.ok(_takerTokenAccountA.amount.toNumber() == initializerAmount);
  126. assert.ok(_initializerTokenAccountA.amount.toNumber() == 0);
  127. assert.ok(_initializerTokenAccountB.amount.toNumber() == takerAmount);
  128. assert.ok(_takerTokenAccountB.amount.toNumber() == 0);
  129. });
  130. let newEscrow = anchor.web3.Keypair.generate();
  131. it("Initialize escrow and cancel escrow", async () => {
  132. // Put back tokens into initializer token A account.
  133. await mintA.mintTo(
  134. initializerTokenAccountA,
  135. mintAuthority.publicKey,
  136. [mintAuthority],
  137. initializerAmount
  138. );
  139. await program.rpc.initializeEscrow(
  140. new anchor.BN(initializerAmount),
  141. new anchor.BN(takerAmount),
  142. {
  143. accounts: {
  144. initializer: provider.wallet.publicKey,
  145. initializerDepositTokenAccount: initializerTokenAccountA,
  146. initializerReceiveTokenAccount: initializerTokenAccountB,
  147. escrowAccount: newEscrow.publicKey,
  148. tokenProgram: TOKEN_PROGRAM_ID,
  149. rent: anchor.web3.SYSVAR_RENT_PUBKEY,
  150. },
  151. instructions: [await program.account.escrowAccount.createInstruction(newEscrow)],
  152. signers: [newEscrow],
  153. }
  154. );
  155. let _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
  156. // Check that the new owner is the PDA.
  157. assert.ok(_initializerTokenAccountA.owner.equals(pda));
  158. // Cancel the escrow.
  159. await program.rpc.cancelEscrow({
  160. accounts: {
  161. initializer: provider.wallet.publicKey,
  162. pdaDepositTokenAccount: initializerTokenAccountA,
  163. pdaAccount: pda,
  164. escrowAccount: newEscrow.publicKey,
  165. tokenProgram: TOKEN_PROGRAM_ID,
  166. },
  167. });
  168. // Check the final owner should be the provider public key.
  169. _initializerTokenAccountA = await mintA.getAccountInfo(initializerTokenAccountA);
  170. assert.ok(_initializerTokenAccountA.owner.equals(provider.wallet.publicKey));
  171. // Check all the funds are still there.
  172. assert.ok(_initializerTokenAccountA.amount.toNumber() == initializerAmount);
  173. });
  174. });