Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ custom-heap = []
custom-panic = []

[dependencies]
borsh = "1.5.7"
borsh-derive = "1.5.7"
solana-program = "3.0"
borsh = "1.6.1"
borsh-derive = "1.6.1"
solana-program = "4.0"
cross-program-invocatio-native-lever = { path = "../lever", features = ["cpi"] }

[lib]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ custom-heap = []
custom-panic = []

[dependencies]
borsh = "1.5.7"
borsh-derive = "1.5.7"
solana-program = "3.0"
borsh = "1.6.1"
borsh-derive = "1.6.1"
solana-program = "4.0"
solana-system-interface = {version = "2.0.0", features = ["bincode"]}

[lib]
Expand Down
16 changes: 8 additions & 8 deletions basics/favorites/native/tests/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import {
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
import { BN } from "bn.js";
import * as borsh from "borsh";
import { assert, expect } from "chai";
import { describe, test } from "mocha";
Expand Down Expand Up @@ -103,15 +102,15 @@ describe("Favorites Solana Native", () => {

console.log("Deserialized data:", favoritesData);

expect(new BN(favoritesData.number as Buffer, "le").toNumber()).to.equal(favData.number);
expect(Number(favoritesData.number)).to.equal(favData.number);
expect(favoritesData.color).to.equal(favData.color);
expect(favoritesData.hobbies).to.deep.equal(favData.hobbies);
});

test("Check if the test fails if the pda seeds aren't same", async () => {
// We put the wrong seeds knowingly to see if the test fails because of checks
const favoritesPda = PublicKey.findProgramAddressSync(
[Buffer.from("favorite"), payer.publicKey.toBuffer()],
// Derive a PDA using WRONG seeds so the program's on-chain seed check rejects it
const wrongPda = PublicKey.findProgramAddressSync(
[Buffer.from("wrong_seed"), payer.publicKey.toBuffer()],
programId,
)[0];
const favData = {
Expand All @@ -124,7 +123,7 @@ describe("Favorites Solana Native", () => {
const ix = new TransactionInstruction({
keys: [
{ pubkey: payer.publicKey, isSigner: true, isWritable: true },
{ pubkey: favoritesPda, isSigner: false, isWritable: true },
{ pubkey: wrongPda, isSigner: false, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
programId,
Expand All @@ -136,12 +135,13 @@ describe("Favorites Solana Native", () => {
tx.recentBlockhash = blockhash;
tx.sign(payer);
tx.recentBlockhash = blockhash;
let threw = false;
try {
await client.processTransaction(tx);
console.error("Expected the test to fail");
} catch (_err) {
assert(true);
threw = true;
}
Comment on lines 139 to 143

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Negative test always passes — assertion swallowed by catch

assert(false, ...) inside the try block throws an AssertionError, but the catch (_err) clause catches it indiscriminately and then calls assert(true), so the test passes whether processTransaction succeeds or throws. If the program ever stops rejecting wrong seeds, this test will still show green. Consider restructuring to hoist the assertion outside the catch:

let failed = false;
try {
  await client.processTransaction(tx);
} catch {
  failed = true;
}
assert(failed, "Expected transaction to fail with wrong PDA seeds");

assert(threw, "Expected transaction to fail with wrong PDA seeds");
});

test("Get the favorite pda and cross-check the data", async () => {
Expand Down
1 change: 1 addition & 0 deletions basics/realloc/native/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
},
"dependencies": {
"@solana/web3.js": "^1.98.4",
"borsh": "^2.0.0",
"fs": "^0.0.1-security"
},
"devDependencies": {
Expand Down
10 changes: 8 additions & 2 deletions basics/realloc/native/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 23 additions & 59 deletions basics/realloc/native/ts/instructions/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,51 +3,15 @@ import { type PublicKey, SystemProgram, TransactionInstruction } from "@solana/w
import * as borsh from "borsh";
import { ReallocInstruction } from "./instruction";

export class Create {
instruction: ReallocInstruction;
name: string;
house_number: number;
street: string;
city: string;

constructor(props: {
instruction: ReallocInstruction;
name: string;
house_number: number;
street: string;
city: string;
}) {
this.instruction = props.instruction;
this.name = props.name;
this.house_number = props.house_number;
this.street = props.street;
this.city = props.city;
}

toBuffer() {
return Buffer.from(borsh.serialize(CreateSchema, this));
}

static fromBuffer(buffer: Buffer) {
return borsh.deserialize(CreateSchema, Create, buffer);
}
}

export const CreateSchema = new Map([
[
Create,
{
kind: "struct",
fields: [
["instruction", "u8"],
["name", "string"],
["house_number", "u8"],
["street", "string"],
["city", "string"],
],
},
],
]);
const CreateSchema = {
struct: {
instruction: "u8",
name: "string",
house_number: "u8",
street: "string",
city: "string",
},
} as const;

export function createCreateInstruction(
target: PublicKey,
Expand All @@ -58,23 +22,23 @@ export function createCreateInstruction(
street: string,
city: string,
): TransactionInstruction {
const instructionObject = new Create({
instruction: ReallocInstruction.Create,
name,
house_number,
street,
city,
});

const ix = new TransactionInstruction({
const data = Buffer.from(
borsh.serialize(CreateSchema, {
instruction: ReallocInstruction.Create,
name,
house_number,
street,
city,
}),
);

return new TransactionInstruction({
keys: [
{ pubkey: target, isSigner: false, isWritable: true },
{ pubkey: target, isSigner: true, isWritable: true },
{ pubkey: payer, isSigner: true, isWritable: true },
{ pubkey: SystemProgram.programId, isSigner: false, isWritable: false },
],
programId: programId,
data: instructionObject.toBuffer(),
programId,
data,
});

return ix;
}
Loading