main.test.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import { type Blockhash, Keypair, LAMPORTS_PER_SOL, PublicKey, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
  2. import * as borsh from 'borsh';
  3. import { before, describe, it } from 'mocha';
  4. import { type BanksClient, type ProgramTestContext, start } from 'solana-bankrun';
  5. // Constants
  6. const PROGRAM_ID = new PublicKey('HK5TuboXztZv7anSa3GptyCZ5wMYiqbY8kNSVEtqWDuD');
  7. const VAULT_SEED = Buffer.from('rent_vault');
  8. const LOAD_LAMPORTS = 1 * LAMPORTS_PER_SOL; // 1 SOL
  9. const instructionDiscriminators = {
  10. InitializeRentVault: 0,
  11. CreateNewAccount: 1,
  12. };
  13. describe('Pay the rent for an account using a PDA', () => {
  14. // Helper classes and methods to serialize instruction data
  15. class Assignable {
  16. constructor(properties) {
  17. for (const [key, value] of Object.entries(properties)) {
  18. this[key] = value;
  19. }
  20. }
  21. }
  22. class InitializeRentVault extends Assignable {
  23. toBuffer() {
  24. return Buffer.from(borsh.serialize(InitRentVaultSchema, this));
  25. }
  26. }
  27. const InitRentVaultSchema = {
  28. struct: {
  29. instruction: 'u8',
  30. fund_lamports: 'u64',
  31. },
  32. };
  33. class CreateNewAccount extends Assignable {
  34. toBuffer() {
  35. return Buffer.from(borsh.serialize(CreateNewAccountSchema, this));
  36. }
  37. }
  38. const CreateNewAccountSchema = {
  39. struct: {
  40. instruction: 'u8',
  41. },
  42. };
  43. const [vault_pda, _] = PublicKey.findProgramAddressSync([VAULT_SEED], PROGRAM_ID);
  44. let context: ProgramTestContext;
  45. let client: BanksClient;
  46. let payer: Keypair;
  47. before(async () => {
  48. context = await start([{ name: 'pda_rent_payer_program', programId: PROGRAM_ID }], []);
  49. client = context.banksClient;
  50. payer = context.payer;
  51. });
  52. it('should initialize rent vault PDA', async () => {
  53. const ixdata = new InitializeRentVault({
  54. instruction: instructionDiscriminators.InitializeRentVault,
  55. fund_lamports: BigInt(LOAD_LAMPORTS),
  56. });
  57. const data = ixdata.toBuffer();
  58. const Createix = new TransactionInstruction({
  59. keys: [
  60. { pubkey: payer.publicKey, isSigner: true, isWritable: false },
  61. { pubkey: vault_pda, isSigner: false, isWritable: true },
  62. { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
  63. ],
  64. programId: PROGRAM_ID,
  65. data,
  66. });
  67. // const Fundix = SystemProgram.transfer({
  68. // fromPubkey: payer.publicKey,
  69. // toPubkey: vault_pda,
  70. // lamports: LOAD_LAMPORTS,
  71. // });
  72. const tx = new Transaction();
  73. tx.recentBlockhash = context.lastBlockhash;
  74. tx.add(Createix).sign(payer);
  75. // Process Transaction with all the instructions
  76. await client.processTransaction(tx);
  77. });
  78. it('should create new account using rent vault', async () => {
  79. const newAccount = Keypair.generate();
  80. const data = new CreateNewAccount({
  81. instruction: instructionDiscriminators.CreateNewAccount,
  82. }).toBuffer();
  83. const ix = new TransactionInstruction({
  84. keys: [
  85. { pubkey: vault_pda, isSigner: false, isWritable: true },
  86. { pubkey: newAccount.publicKey, isSigner: true, isWritable: true },
  87. { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
  88. ],
  89. programId: PROGRAM_ID,
  90. data,
  91. });
  92. const tx = new Transaction();
  93. tx.recentBlockhash = context.lastBlockhash;
  94. tx.add(ix).sign(newAccount);
  95. // Process Transaction with all the instructions
  96. await client.processTransaction(tx);
  97. // assert(
  98. // transaction.logMessages[3].startsWith(
  99. // "Program log: Created new account!",
  100. // ),
  101. // );
  102. });
  103. });