test.ts 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. import {
  2. Connection,
  3. Keypair,
  4. PublicKey,
  5. sendAndConfirmTransaction,
  6. SystemProgram,
  7. Transaction,
  8. TransactionInstruction,
  9. } from '@solana/web3.js';
  10. import * as borsh from "borsh";
  11. import { Buffer } from "buffer";
  12. import { start } from 'solana-bankrun';
  13. import { describe, test } from 'node:test';
  14. describe("PDA Rent-Payer", async () => {
  15. const PROGRAM_ID = PublicKey.unique();
  16. const context = await start([{ name: 'pda_rent_payer_program', programId: PROGRAM_ID }],[]);
  17. const client = context.banksClient;
  18. const payer = context.payer;
  19. class Assignable {
  20. constructor(properties) {
  21. Object.keys(properties).map((key) => {
  22. return (this[key] = properties[key]);
  23. });
  24. };
  25. };
  26. enum MyInstruction {
  27. InitRentVault,
  28. CreateNewAccount,
  29. }
  30. class InitRentVault extends Assignable {
  31. toBuffer() { return Buffer.from(borsh.serialize(InitRentVaultSchema, this)) }
  32. };
  33. const InitRentVaultSchema = new Map([
  34. [InitRentVault, {
  35. kind: 'struct',
  36. fields: [ ['instruction', 'u8'], ['fund_lamports', 'u64'] ],
  37. }]
  38. ]);
  39. class CreateNewAccount extends Assignable {
  40. toBuffer() { return Buffer.from(borsh.serialize(CreateNewAccountSchema, this)) }
  41. };
  42. const CreateNewAccountSchema = new Map([
  43. [ CreateNewAccount, {
  44. kind: 'struct',
  45. fields: [ ['instruction', 'u8'] ],
  46. }]
  47. ]);
  48. function deriveRentVaultPda() {
  49. const pda = PublicKey.findProgramAddressSync(
  50. [Buffer.from("rent_vault")],
  51. PROGRAM_ID,
  52. )
  53. console.log(`PDA: ${pda[0].toBase58()}`)
  54. return pda
  55. }
  56. test("Initialize the Rent Vault", async () => {
  57. const blockhash = context.lastBlockhash;
  58. const [rentVaultPda, _] = deriveRentVaultPda();
  59. let ix = new TransactionInstruction({
  60. keys: [
  61. {pubkey: rentVaultPda, isSigner: false, isWritable: true},
  62. {pubkey: payer.publicKey, isSigner: true, isWritable: true},
  63. {pubkey: SystemProgram.programId, isSigner: false, isWritable: false}
  64. ],
  65. programId: PROGRAM_ID,
  66. data: (new InitRentVault({ instruction: MyInstruction.InitRentVault, fund_lamports: 1000000000 })).toBuffer(),
  67. });
  68. const tx = new Transaction();
  69. tx.recentBlockhash = blockhash;
  70. tx.add(ix).sign(payer);
  71. await client.processTransaction(tx);
  72. });
  73. test("Create a new account using the Rent Vault", async () => {
  74. const blockhash = context.lastBlockhash;
  75. const newAccount = Keypair.generate();
  76. const [rentVaultPda, _] = deriveRentVaultPda();
  77. let ix = new TransactionInstruction({
  78. keys: [
  79. {pubkey: newAccount.publicKey, isSigner: true, isWritable: true},
  80. {pubkey: rentVaultPda, isSigner: false, isWritable: true},
  81. {pubkey: SystemProgram.programId, isSigner: false, isWritable: false}
  82. ],
  83. programId: PROGRAM_ID,
  84. data: new CreateNewAccount({ instruction: MyInstruction.CreateNewAccount }).toBuffer(),
  85. });
  86. const tx = new Transaction();
  87. tx.recentBlockhash = blockhash;
  88. tx.add(ix).sign(payer, newAccount); // Add instruction and Sign the transaction
  89. // Now we process the transaction
  90. await client.processTransaction(tx);
  91. });
  92. });