test.ts 3.2 KB

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