The following program initialises a pda on chain through a CPI
Ref - https://github.com/100xdevs-cohort-3/cpis-on-pdas/blob/main/contract/src/lib.rs
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
msg,
program::invoke_signed,
pubkey::Pubkey,
system_instruction::create_account,
system_program::ID as SYSTEM_PROGRAM_ID,
};
entrypoint!(process_instruction);
pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
_instruction_data: &[u8],
) -> ProgramResult {
let iter = &mut accounts.iter();
let payer_account = next_account_info(iter)?;
let pda_account = next_account_info(iter)?;
let payer_pubkey = payer_account.key;
let system_program = next_account_info(iter)?;
let (pda, bump) = Pubkey::find_program_address(
&[b"client1", payer_pubkey.as_ref()],
&program_id,
);
let ix = create_account(
&payer_account.key,
&pda,
1000000000,
4,
&program_id,
);
let signer_seeds = &[b"client1", payer_pubkey.as_ref(), &[bump]];
invoke_signed(&ix, accounts, &[signer_seeds])?;
Ok(())
}
Ref - https://github.com/100xdevs-cohort-3/cpis-on-pdas/blob/main/contract/client/index.test.ts
import { test, expect, beforeAll, describe } from "bun:test";
import { LiteSVM } from "litesvm";
import { Keypair, PublicKey, SystemProgram, Transaction, TransactionInstruction, } from "@solana/web3.js";
describe("Create pda from client", () => {
let liveSvm: LiteSVM;
let pda: PublicKey;
let bump: number;
let programId: PublicKey;
let payer: Keypair;
beforeAll(() => {
liveSvm = new LiteSVM();
programId = PublicKey.unique();
payer = Keypair.generate();
liveSvm.addProgramFromFile(programId, "./contract.so");
liveSvm.airdrop(payer.publicKey, BigInt(100000000000));
[pda, bump] = PublicKey.findProgramAddressSync([Buffer.from("client1"), payer.publicKey.toBuffer()], programId);
let ix = new TransactionInstruction({
keys: [
{
pubkey: payer.publicKey,
isSigner: true,
isWritable: true,
},
{
pubkey: pda,
isSigner: false,
isWritable: true,
},
{
pubkey: SystemProgram.programId,
isSigner: false,
isWritable: false,
}
],
programId,
data: Buffer.from("")
});
const tx = new Transaction().add(ix);
tx.feePayer = payer.publicKey;
tx.recentBlockhash = liveSvm.latestBlockhash();
tx.sign(payer);
let res = liveSvm.sendTransaction(tx);
console.log(res.toString())
});
test("should create pda", () => {
const balance = liveSvm.getBalance(pda);
console.log(balance)
expect(Number(balance)).toBeGreaterThan(0);
expect(Number(balance)).toBe(1000000000);
});
});