123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import { Keypair, PublicKey, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
- import * as borsh from 'borsh';
- import { assert } from 'chai';
- import { describe, it } from 'mocha';
- import { BanksClient, ProgramTestContext, start } from 'solana-bankrun';
- describe('counter program', async () => {
- const PROGRAM_ID = new PublicKey('z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35');
- let context: ProgramTestContext;
- let client: BanksClient;
- let payer: Keypair;
- before(async () => {
- context = await start([{ name: 'counter_program', programId: PROGRAM_ID }], []);
- client = context.banksClient;
- payer = context.payer;
- });
- it('initialize and increment the counter', async () => {
- // derive the counter PDA
- const [counterPDA] = PublicKey.findProgramAddressSync(
- [Buffer.from('counter')], // seed
- PROGRAM_ID,
- );
- const instructionDiscriminators = {
- initialize: Buffer.from([0]),
- increment: Buffer.from([1]),
- };
- // create the initialize instruction
- const initializeIx = new TransactionInstruction({
- programId: PROGRAM_ID,
- keys: [
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- { pubkey: counterPDA, isSigner: false, isWritable: true },
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
- ],
- data: instructionDiscriminators.initialize,
- });
- // send the initialize transaction
- const initializeTx = new Transaction();
- initializeTx.recentBlockhash = context.lastBlockhash;
- initializeTx.add(initializeIx).sign(payer);
- // process the transaction
- await client.processTransaction(initializeTx);
- // fetch the counter account data
- const accountInfo = await client.getAccount(counterPDA);
- assert(accountInfo !== null, 'counter account should exist');
- // define the counter schema
- const counterSchema: borsh.Schema = {
- struct: { discriminator: 'u64', value: 'u64' },
- };
- // deserialize the counter account data
- const counterData = borsh.deserialize(counterSchema, accountInfo?.data) as {
- value: bigint;
- };
- // check the counter value is 0
- assert(counterData.value === BigInt(0), 'counter value should be 0');
- // increment (must be a number between 0 and 255)
- const amount = BigInt(42);
- const amountBuffer = Buffer.alloc(8);
- amountBuffer.writeBigUInt64LE(amount);
- // data for the increment instruction
- const incrementData = Buffer.concat([instructionDiscriminators.increment, amountBuffer]);
- // create the increment instruction
- const incrementIx = new TransactionInstruction({
- programId: PROGRAM_ID,
- keys: [
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- { pubkey: counterPDA, isSigner: false, isWritable: true },
- ],
- data: incrementData,
- });
- // send the increment transaction
- const incrementTx = new Transaction();
- incrementTx.recentBlockhash = context.lastBlockhash;
- incrementTx.add(incrementIx).sign(payer);
- // process the transaction
- await client.processTransaction(incrementTx);
- // fetch the counter account data
- const updatedAccountInfo = await client.getAccount(counterPDA);
- assert(updatedAccountInfo !== null, 'counter account should exist');
- // deserialize the updated counter account data
- const updatedCounterData = borsh.deserialize(counterSchema, updatedAccountInfo?.data) as { value: bigint };
- assert(updatedCounterData.value === BigInt(amount), `counter value should be ${amount} but we got ${updatedCounterData.value}`);
- });
- });
|