123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- import { Buffer } from 'node:buffer';
- import { describe, test } from 'node:test';
- import { Keypair, PublicKey, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js';
- import * as borsh from 'borsh';
- import { start } from 'solana-bankrun';
- describe('PDAs', async () => {
- const PROGRAM_ID = PublicKey.unique();
- const context = await start([{ name: 'program_derived_addresses_program', programId: PROGRAM_ID }], []);
- const client = context.banksClient;
- const payer = context.payer;
- const rent = await client.getRent();
- class Assignable {
- constructor(properties) {
- for (const [key, value] of Object.entries(properties)) {
- this[key] = value;
- }
- }
- }
- class PageVisits extends Assignable {
- toBuffer() {
- return Buffer.from(borsh.serialize(PageVisitsSchema, this));
- }
- static fromBuffer(buffer: Buffer) {
- return borsh.deserialize(PageVisitsSchema, PageVisits, buffer);
- }
- }
- const PageVisitsSchema = new Map([
- [
- PageVisits,
- {
- kind: 'struct',
- fields: [
- ['page_visits', 'u32'],
- ['bump', 'u8'],
- ],
- },
- ],
- ]);
- class IncrementPageVisits extends Assignable {
- toBuffer() {
- return Buffer.from(borsh.serialize(IncrementPageVisitsSchema, this));
- }
- }
- const IncrementPageVisitsSchema = new Map([
- [
- IncrementPageVisits,
- {
- kind: 'struct',
- fields: [],
- },
- ],
- ]);
- const testUser = Keypair.generate();
- test('Create a test user', async () => {
- const ix = SystemProgram.createAccount({
- fromPubkey: payer.publicKey,
- lamports: Number(rent.minimumBalance(BigInt(0))),
- newAccountPubkey: testUser.publicKey,
- programId: SystemProgram.programId,
- space: 0,
- });
- const tx = new Transaction();
- const blockhash = context.lastBlockhash;
- tx.recentBlockhash = blockhash;
- tx.add(ix).sign(payer, testUser); // Add instruction and Sign the transaction
- await client.processTransaction(tx);
- console.log(`Local Wallet: ${payer.publicKey}`);
- console.log(`Created User: ${testUser.publicKey}`);
- });
- function derivePageVisitsPda(userPubkey: PublicKey) {
- return PublicKey.findProgramAddressSync([Buffer.from('page_visits'), userPubkey.toBuffer()], PROGRAM_ID);
- }
- test('Create the page visits tracking PDA', async () => {
- const [pageVisitsPda, pageVisitsBump] = derivePageVisitsPda(testUser.publicKey);
- const ix = new TransactionInstruction({
- keys: [
- { pubkey: pageVisitsPda, isSigner: false, isWritable: true },
- { pubkey: testUser.publicKey, isSigner: false, isWritable: false },
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
- ],
- programId: PROGRAM_ID,
- data: new PageVisits({ page_visits: 0, bump: pageVisitsBump }).toBuffer(),
- });
- const tx = new Transaction();
- const blockhash = context.lastBlockhash;
- tx.recentBlockhash = blockhash;
- tx.add(ix).sign(payer);
- await client.processTransaction(tx);
- });
- test('Visit the page!', async () => {
- const [pageVisitsPda, _] = derivePageVisitsPda(testUser.publicKey);
- const ix = new TransactionInstruction({
- keys: [
- { pubkey: pageVisitsPda, isSigner: false, isWritable: true },
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- ],
- programId: PROGRAM_ID,
- data: new IncrementPageVisits({}).toBuffer(),
- });
- const tx = new Transaction();
- const blockhash = context.lastBlockhash;
- tx.recentBlockhash = blockhash;
- tx.add(ix).sign(payer);
- await client.processTransaction(tx);
- });
- test('Visit the page!', async () => {
- const [pageVisitsPda, _] = derivePageVisitsPda(testUser.publicKey);
- const ix = new TransactionInstruction({
- keys: [
- { pubkey: pageVisitsPda, isSigner: false, isWritable: true },
- { pubkey: payer.publicKey, isSigner: true, isWritable: true },
- ],
- programId: PROGRAM_ID,
- data: new IncrementPageVisits({}).toBuffer(),
- });
- const tx = new Transaction();
- const [blockhash, _block_height] = await client.getLatestBlockhash();
- tx.recentBlockhash = blockhash;
- tx.add(ix).sign(payer);
- await client.processTransaction(tx);
- });
- test('Read page visits', async () => {
- const [pageVisitsPda, _] = derivePageVisitsPda(testUser.publicKey);
- const accountInfo = await client.getAccount(pageVisitsPda);
- const readPageVisits = PageVisits.fromBuffer(Buffer.from(accountInfo.data));
- console.log(`Number of page visits: ${readPageVisits.page_visits}`);
- });
- });
|