diff --git a/.github/workflows/anchor.yml b/.github/workflows/anchor.yml index 479e75bd..c9d49c97 100644 --- a/.github/workflows/anchor.yml +++ b/.github/workflows/anchor.yml @@ -36,7 +36,7 @@ jobs: - name: Setup Anchor if: steps.changes.outputs.anchor == 'true' || steps.changes.outputs.anchor_action == 'true' || github.event_name == 'schedule' || github.event_name == 'push' - uses: heyAyushh/setup-anchor@v3.12 + uses: heyAyushh/setup-anchor@v4.0 with: anchor-version: ${{ matrix.anchor-version }} solana-cli-version: ${{ matrix.solana-version }} @@ -154,13 +154,13 @@ jobs: # Skip Installing and Displaying versions if theres no change in anchor programs or anchor action workflow file or isn't a schedule event - name: Setup Anchor if: steps.changes.outputs.anchor == 'true' || steps.changes.outputs.anchor_action == 'true' || github.event_name == 'schedule' || github.event_name == 'push' - uses: heyAyushh/setup-anchor@v3.12 + uses: heyAyushh/setup-anchor@v4.0 with: anchor-version: ${{ matrix.anchor-version }} solana-cli-version: ${{ matrix.solana-version }} node-version: ${{ matrix.node-version }} - name: Display versions and Install pnpm - if: steps.changes.outputs.anchor == 'true' || steps.changes.outputs.anchor_action == 'true' || github.event_name == 'schedule' + if: steps.changes.outputs.anchor == 'true' || steps.changes.outputs.anchor_action == 'true' || github.event_name == 'schedule' || github.event_name == 'push' run: | solana -V solana-keygen new --no-bip39-passphrase @@ -201,7 +201,7 @@ jobs: shell: bash # Skip Testing all Programs if it's a CRON job or a change in the workflow file - name: Test All Anchor Programs - if: github.event_name == 'schedule' || steps.changes.outputs.anchor_action == 'true' + if: github.event_name == 'schedule' || github.event_name == 'push' || steps.changes.outputs.anchor_action == 'true' run: | declare -a ProjectDirs=($(find . -type d -name "anchor"| grep -v -f <(grep . .github/.ghaignore | grep -v '^$'))) echo "Projects to Test:" diff --git a/.github/workflows/solana-native.yml b/.github/workflows/solana-native.yml index b572293b..76ada94d 100644 --- a/.github/workflows/solana-native.yml +++ b/.github/workflows/solana-native.yml @@ -25,7 +25,7 @@ jobs: with: node-version: ${{ matrix.node-version }} check-latest: true - - uses: heyAyushh/setup-solana@v5.2 + - uses: heyAyushh/setup-solana@v5.4 with: solana-cli-version: ${{ matrix.solana-version }} - run: solana block @@ -75,7 +75,7 @@ jobs: with: node-version: ${{ matrix.node-version }} check-latest: true - - uses: heyAyushh/setup-solana@v5.2 + - uses: heyAyushh/setup-solana@v5.4 with: solana-cli-version: ${{ matrix.solana-version }} - run: solana block diff --git a/tokens/escrow/anchor/tests/escrow.ts b/tokens/escrow/anchor/tests/escrow.ts index 0d59638e..c09aad30 100644 --- a/tokens/escrow/anchor/tests/escrow.ts +++ b/tokens/escrow/anchor/tests/escrow.ts @@ -1,6 +1,6 @@ -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, type Program } from '@coral-xyz/anchor'; import { MINT_SIZE, TOKEN_2022_PROGRAM_ID, @@ -10,27 +10,20 @@ import { 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, SystemProgram, Transaction, type TransactionInstruction } from '@solana/web3.js'; +import { assert } from 'chai'; +import type { Escrow } from '../target/types/escrow'; -import { confirmTransaction, makeKeypairs } from "@solana-developers/helpers"; +import { confirmTransaction, makeKeypairs } 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 () => { +describe('escrow', async () => { anchor.setProvider(anchor.AnchorProvider.env()); const provider = anchor.getProvider(); @@ -46,112 +39,66 @@ describe("escrow", async () => { 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 = [ - alice, - bob, - ].map((account) => - SystemProgram.transfer({ - fromPubkey: provider.publicKey, - toPubkey: account.publicKey, - lamports: 10 * LAMPORTS_PER_SOL, - }) - ); - - const createMintInstructions: Array = [ - 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 = [ - { - 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, - ]; - - 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; - } - ); + 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 = [alice, bob].map((account) => + SystemProgram.transfer({ + fromPubkey: provider.publicKey, + toPubkey: account.publicKey, + lamports: 10 * LAMPORTS_PER_SOL, + }), + ); + + const createMintInstructions: Array = [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 = [ + { + 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]; + + 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; + }); const tokenAOfferedAmount = new BN(1_000_000); const tokenBWantedAmount = new BN(1_000_000); @@ -163,20 +110,11 @@ 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; @@ -215,24 +153,18 @@ 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(); });