Эх сурвалжийг харах

Make Escrow use test helper to set up accounts, mints, ATAs, etc.

Mike MacCana 1 жил өмнө
parent
commit
28722da89d

+ 1 - 1
tokens/escrow/anchor/package.json

@@ -5,7 +5,7 @@
   },
   "dependencies": {
     "@coral-xyz/anchor": "^0.30.0",
-    "@solana-developers/helpers": "^2.3.0",
+    "@solana-developers/helpers": "file:../../../../helpers",
     "@solana/spl-token": "^0.4.6"
   },
   "license": "MIT",

+ 81 - 88
tokens/escrow/anchor/tests/escrow.ts

@@ -1,32 +1,31 @@
-import { randomBytes } from 'node:crypto';
-import * as anchor from '@coral-xyz/anchor';
-import { BN, type Program } from '@coral-xyz/anchor';
+import { randomBytes } from "node:crypto";
+import * as anchor from "@coral-xyz/anchor";
+import { BN, Wallet, type Program } from "@coral-xyz/anchor";
 import {
-  MINT_SIZE,
   TOKEN_2022_PROGRAM_ID,
   type TOKEN_PROGRAM_ID,
-  createAssociatedTokenAccountIdempotentInstruction,
-  createInitializeMint2Instruction,
-  createMintToInstruction,
   getAssociatedTokenAddressSync,
-  getMinimumBalanceForRentExemptMint,
-} from '@solana/spl-token';
-import { LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, type TransactionInstruction } from '@solana/web3.js';
-import { assert } from 'chai';
-import type { Escrow } from '../target/types/escrow';
+} from "@solana/spl-token";
+import { LAMPORTS_PER_SOL, PublicKey, Keypair } from "@solana/web3.js";
+import { assert } from "chai";
+import type { Escrow } from "../target/types/escrow";
 
-import { confirmTransaction, makeKeypairs } from '@solana-developers/helpers';
+import {
+  confirmTransaction,
+  createAccountsMintsAndTokenAccounts,
+} from "@solana-developers/helpers";
 
-const TOKEN_PROGRAM: typeof TOKEN_2022_PROGRAM_ID | typeof TOKEN_PROGRAM_ID = TOKEN_2022_PROGRAM_ID;
+const TOKEN_PROGRAM: typeof TOKEN_2022_PROGRAM_ID | typeof TOKEN_PROGRAM_ID =
+  TOKEN_2022_PROGRAM_ID;
 
 const getRandomBigNumber = (size = 8) => {
   return new BN(randomBytes(size));
 };
 
-describe('escrow', async () => {
-  anchor.setProvider(anchor.AnchorProvider.env());
-
-  const provider = anchor.getProvider();
+describe("escrow", async () => {
+  // Use the cluster and the keypair from Anchor.toml
+  const provider = anchor.AnchorProvider.env();
+  anchor.setProvider(provider);
 
   const connection = provider.connection;
 
@@ -37,68 +36,47 @@ describe('escrow', async () => {
     tokenProgram: TOKEN_PROGRAM,
   };
 
-  const [alice, bob, tokenMintA, tokenMintB] = makeKeypairs(4);
-
-  before('Creates Alice and Bob accounts, 2 token mints, and associated token accounts for both tokens for both users', async () => {
-    const [aliceTokenAccountA, aliceTokenAccountB, bobTokenAccountA, bobTokenAccountB] = [alice, bob].flatMap((keypair) =>
-      [tokenMintA, tokenMintB].map((mint) => getAssociatedTokenAddressSync(mint.publicKey, keypair.publicKey, false, TOKEN_PROGRAM)),
-    );
-
-    // Airdrops to users, and creates two tokens mints 'A' and 'B'"
-    const minimumLamports = await getMinimumBalanceForRentExemptMint(connection);
-
-    const sendSolInstructions: Array<TransactionInstruction> = [alice, bob].map((account) =>
-      SystemProgram.transfer({
-        fromPubkey: provider.publicKey,
-        toPubkey: account.publicKey,
-        lamports: 10 * LAMPORTS_PER_SOL,
-      }),
-    );
-
-    const createMintInstructions: Array<TransactionInstruction> = [tokenMintA, tokenMintB].map((mint) =>
-      SystemProgram.createAccount({
-        fromPubkey: provider.publicKey,
-        newAccountPubkey: mint.publicKey,
-        lamports: minimumLamports,
-        space: MINT_SIZE,
-        programId: TOKEN_PROGRAM,
-      }),
-    );
-
-    // Make tokenA and tokenB mints, mint tokens and create ATAs
-    const mintTokensInstructions: Array<TransactionInstruction> = [
-      {
-        mint: tokenMintA.publicKey,
-        authority: alice.publicKey,
-        ata: aliceTokenAccountA,
-      },
-      {
-        mint: tokenMintB.publicKey,
-        authority: bob.publicKey,
-        ata: bobTokenAccountB,
-      },
-    ].flatMap((mintDetails) => [
-      createInitializeMint2Instruction(mintDetails.mint, 6, mintDetails.authority, null, TOKEN_PROGRAM),
-      createAssociatedTokenAccountIdempotentInstruction(provider.publicKey, mintDetails.ata, mintDetails.authority, mintDetails.mint, TOKEN_PROGRAM),
-      createMintToInstruction(mintDetails.mint, mintDetails.ata, mintDetails.authority, 1_000_000_000, [], TOKEN_PROGRAM),
-    ]);
-
-    // Add all these instructions to our transaction
-    const tx = new Transaction();
-    tx.instructions = [...sendSolInstructions, ...createMintInstructions, ...mintTokensInstructions];
-
-    const transactionSignature = await provider.sendAndConfirm(tx, [tokenMintA, tokenMintB, alice, bob]);
-
-    // Save the accounts for later use
-    accounts.maker = alice.publicKey;
-    accounts.taker = bob.publicKey;
-    accounts.tokenMintA = tokenMintA.publicKey;
-    accounts.makerTokenAccountA = aliceTokenAccountA;
-    accounts.takerTokenAccountA = bobTokenAccountA;
-    accounts.tokenMintB = tokenMintB.publicKey;
-    accounts.makerTokenAccountB = aliceTokenAccountB;
-    accounts.takerTokenAccountB = bobTokenAccountB;
-  });
+  let alice: Keypair;
+  let bob: Keypair;
+  let tokenMintA: Keypair;
+  let tokenMintB: Keypair;
+
+  before(
+    "Creates Alice and Bob accounts, 2 token mints, and associated token accounts for both tokens for both users",
+    async () => {
+      const connection = provider.connection;
+
+      const providerUser = (provider.wallet as Wallet).payer;
+
+      const SOL_BALANCE = 10 * LAMPORTS_PER_SOL;
+
+      const accountsMintsAndTokenAccounts =
+        await createAccountsMintsAndTokenAccounts(
+          [
+            [1_000_000_000, 0], // Alice has 1_000_000_000 of token A and 0 of token B
+            [0, 1_000_000_000], // Bob has 0 of token A and 1_000_000_000 of token B
+          ],
+          SOL_BALANCE,
+          connection,
+          providerUser
+        );
+
+      const tokenAccounts = accountsMintsAndTokenAccounts.tokenAccounts;
+
+      [alice, bob] = accountsMintsAndTokenAccounts.users;
+      [tokenMintA, tokenMintB] = accountsMintsAndTokenAccounts.mints;
+
+      // Save the accounts for later use
+      accounts.maker = alice.publicKey;
+      accounts.taker = bob.publicKey;
+      accounts.tokenMintA = tokenMintA.publicKey;
+      accounts.makerTokenAccountA = tokenAccounts[0][0];
+      accounts.takerTokenAccountA = tokenAccounts[1][0];
+      accounts.tokenMintB = tokenMintB.publicKey;
+      accounts.makerTokenAccountB = tokenAccounts[0][1];
+      accounts.takerTokenAccountB = tokenAccounts[1][1];
+    }
+  );
 
   const tokenAOfferedAmount = new BN(1_000_000);
   const tokenBWantedAmount = new BN(1_000_000);
@@ -110,11 +88,20 @@ describe('escrow', async () => {
 
     // Then determine the account addresses we'll use for the offer and the vault
     const offer = PublicKey.findProgramAddressSync(
-      [Buffer.from('offer'), accounts.maker.toBuffer(), offerId.toArrayLike(Buffer, 'le', 8)],
-      program.programId,
+      [
+        Buffer.from("offer"),
+        accounts.maker.toBuffer(),
+        offerId.toArrayLike(Buffer, "le", 8),
+      ],
+      program.programId
     )[0];
 
-    const vault = getAssociatedTokenAddressSync(accounts.tokenMintA, offer, true, TOKEN_PROGRAM);
+    const vault = getAssociatedTokenAddressSync(
+      accounts.tokenMintA,
+      offer,
+      true,
+      TOKEN_PROGRAM
+    );
 
     accounts.offer = offer;
     accounts.vault = vault;
@@ -153,18 +140,24 @@ describe('escrow', async () => {
 
     // Check the offered tokens are now in Bob's account
     // (note: there is no before balance as Bob didn't have any offered tokens before the transaction)
-    const bobTokenAccountBalanceAfterResponse = await connection.getTokenAccountBalance(accounts.takerTokenAccountA);
-    const bobTokenAccountBalanceAfter = new BN(bobTokenAccountBalanceAfterResponse.value.amount);
+    const bobTokenAccountBalanceAfterResponse =
+      await connection.getTokenAccountBalance(accounts.takerTokenAccountA);
+    const bobTokenAccountBalanceAfter = new BN(
+      bobTokenAccountBalanceAfterResponse.value.amount
+    );
     assert(bobTokenAccountBalanceAfter.eq(tokenAOfferedAmount));
 
     // Check the wanted tokens are now in Alice's account
     // (note: there is no before balance as Alice didn't have any wanted tokens before the transaction)
-    const aliceTokenAccountBalanceAfterResponse = await connection.getTokenAccountBalance(accounts.makerTokenAccountB);
-    const aliceTokenAccountBalanceAfter = new BN(aliceTokenAccountBalanceAfterResponse.value.amount);
+    const aliceTokenAccountBalanceAfterResponse =
+      await connection.getTokenAccountBalance(accounts.makerTokenAccountB);
+    const aliceTokenAccountBalanceAfter = new BN(
+      aliceTokenAccountBalanceAfterResponse.value.amount
+    );
     assert(aliceTokenAccountBalanceAfter.eq(tokenBWantedAmount));
   };
 
-  it('Puts the tokens Alice offers into the vault when Alice makes an offer', async () => {
+  it("Puts the tokens Alice offers into the vault when Alice makes an offer", async () => {
     await make();
   });
 

+ 1 - 1
tokens/escrow/anchor/tsconfig.json

@@ -2,7 +2,7 @@
   "compilerOptions": {
     "types": ["mocha", "chai"],
     "typeRoots": ["./node_modules/@types"],
-    "lib": ["es2015"],
+    "lib": ["es2022"],
     "module": "commonjs",
     "target": "es6",
     "esModuleInterop": true