counter.test.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import { describe, test } from 'node:test';
  2. import { Keypair, PublicKey, SystemProgram, Transaction, type TransactionInstruction } from '@solana/web3.js';
  3. import { assert } from 'chai';
  4. import { start } from 'solana-bankrun';
  5. import { COUNTER_ACCOUNT_SIZE, PROGRAM_ID, createIncrementInstruction, deserializeCounterAccount } from '../ts';
  6. describe('Counter Solana Native', async () => {
  7. // Randomly generate the program keypair and load the program to solana-bankrun
  8. const context = await start([{ name: 'counter_solana_native', programId: PROGRAM_ID }], []);
  9. const client = context.banksClient;
  10. // Get the payer keypair from the context, this will be used to sign transactions with enough lamports
  11. const payer = context.payer;
  12. // Get the rent object to calculate rent for the accounts
  13. const rent = await client.getRent();
  14. test('Test allocate counter + increment tx', async () => {
  15. // Randomly generate the account key
  16. // to sign for setting up the Counter state
  17. const counterKeypair = Keypair.generate();
  18. const counter = counterKeypair.publicKey;
  19. // Create a TransactionInstruction to interact with our counter program
  20. const allocIx: TransactionInstruction = SystemProgram.createAccount({
  21. fromPubkey: payer.publicKey,
  22. newAccountPubkey: counter,
  23. lamports: Number(rent.minimumBalance(BigInt(COUNTER_ACCOUNT_SIZE))),
  24. space: COUNTER_ACCOUNT_SIZE,
  25. programId: PROGRAM_ID,
  26. });
  27. const incrementIx: TransactionInstruction = createIncrementInstruction({ counter }, {});
  28. const tx = new Transaction().add(allocIx).add(incrementIx);
  29. // Explicitly set the feePayer to be our wallet (this is set to first signer by default)
  30. tx.feePayer = payer.publicKey;
  31. // Fetch a "timestamp" so validators know this is a recent transaction
  32. const blockhash = context.lastBlockhash;
  33. tx.recentBlockhash = blockhash;
  34. // Sign the transaction with the payer's keypair
  35. tx.sign(payer, counterKeypair);
  36. // Send transaction to bankrun
  37. await client.processTransaction(tx);
  38. // Get the counter account info from network
  39. const counterAccountInfo = await client.getAccount(counter);
  40. assert(counterAccountInfo, 'Expected counter account to have been created');
  41. // Deserialize the counter & check count has been incremented
  42. const counterAccount = deserializeCounterAccount(Buffer.from(counterAccountInfo.data));
  43. assert(counterAccount.count.toNumber() === 1, 'Expected count to have been 1');
  44. console.log(`[alloc+increment] count is: ${counterAccount.count.toNumber()}`);
  45. });
  46. test('Test allocate tx and increment tx', async () => {
  47. const counterKeypair = Keypair.generate();
  48. const counter = counterKeypair.publicKey;
  49. // Check allocate tx
  50. const allocIx: TransactionInstruction = SystemProgram.createAccount({
  51. fromPubkey: payer.publicKey,
  52. newAccountPubkey: counter,
  53. lamports: Number(rent.minimumBalance(BigInt(COUNTER_ACCOUNT_SIZE))),
  54. space: COUNTER_ACCOUNT_SIZE,
  55. programId: PROGRAM_ID,
  56. });
  57. let tx = new Transaction().add(allocIx);
  58. const blockhash = context.lastBlockhash;
  59. tx.feePayer = payer.publicKey;
  60. tx.recentBlockhash = blockhash;
  61. tx.sign(payer, counterKeypair);
  62. await client.processTransaction(tx);
  63. let counterAccountInfo = await client.getAccount(counter);
  64. assert(counterAccountInfo, 'Expected counter account to have been created');
  65. let counterAccount = deserializeCounterAccount(Buffer.from(counterAccountInfo.data));
  66. assert(counterAccount.count.toNumber() === 0, 'Expected count to have been 0');
  67. console.log(`[allocate] count is: ${counterAccount.count.toNumber()}`);
  68. // Check increment tx
  69. const incrementIx: TransactionInstruction = createIncrementInstruction({ counter }, {});
  70. tx = new Transaction().add(incrementIx);
  71. tx.feePayer = payer.publicKey;
  72. tx.recentBlockhash = blockhash;
  73. tx.sign(payer);
  74. await client.processTransaction(tx);
  75. counterAccountInfo = await client.getAccount(counter);
  76. assert(counterAccountInfo, 'Expected counter account to have been created');
  77. counterAccount = deserializeCounterAccount(Buffer.from(counterAccountInfo.data));
  78. assert(counterAccount.count.toNumber() === 1, 'Expected count to have been 1');
  79. console.log(`[increment] count is: ${counterAccount.count.toNumber()}`);
  80. });
  81. });