From cd3f55d98e980306a7806758b57e43048d349997 Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 09:24:32 +0530 Subject: [PATCH 1/7] feat: add LiteSVM tests for closing an account in Anchor program --- .../anchor/tests/litesvm.test.ts | 104 ++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 basics/close-account/anchor/tests/litesvm.test.ts diff --git a/basics/close-account/anchor/tests/litesvm.test.ts b/basics/close-account/anchor/tests/litesvm.test.ts new file mode 100644 index 000000000..684d8ba95 --- /dev/null +++ b/basics/close-account/anchor/tests/litesvm.test.ts @@ -0,0 +1,104 @@ +import assert from "node:assert/strict"; +import { describe, it } from "node:test"; +import anchor from "@coral-xyz/anchor"; +import { + Keypair, + LAMPORTS_PER_SOL, + PublicKey, + SystemProgram, + Transaction, + TransactionInstruction, +} from "@solana/web3.js"; +import { LiteSVM } from "litesvm"; + +import IDL from "../target/idl/close_account_program.json" with { + type: "json", +}; + +describe("LiteSVM: Close an account", () => { + const litesvm = new LiteSVM(); + const programId = new PublicKey(IDL.address); + const payer = Keypair.generate(); + const coder = new anchor.BorshCoder(IDL as anchor.Idl); // For serialization and deserialization + + const programPath = new URL( + "../target/deploy/close_account_program.so", + import.meta.url, + ).pathname; + litesvm.addProgramFromFile(programId, programPath); + + litesvm.airdrop(payer.publicKey, BigInt(5 * LAMPORTS_PER_SOL)); + + /** + * Derive the PDA for the user's account. + */ + const [userAccountAddress] = PublicKey.findProgramAddressSync( + [Buffer.from("USER"), payer.publicKey.toBuffer()], + programId, + ); + + it("Create an account", () => { + /** + * Instruction data + * Convert into buffer of instruction data + */ + const dataArg = { name: "John Doe" }; + const data = coder.instruction.encode("create_user", dataArg); + + /** + * Create Transactions + */ + const ix = new TransactionInstruction({ + keys: [ + { pubkey: payer.publicKey, isSigner: true, isWritable: true }, + { pubkey: userAccountAddress, isSigner: false, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId, + data, + }); + + const tx = new Transaction().add(ix); + tx.feePayer = payer.publicKey; + tx.recentBlockhash = litesvm.latestBlockhash(); + tx.sign(payer); + litesvm.sendTransaction(tx); + + /** + * Fetch account + */ + const userAccount = litesvm.getAccount(userAccountAddress); + const user = coder.accounts.decode( + "UserState", + Buffer.from(userAccount.data), + ); + assert.equal(user.name, "John Doe"); + assert.equal(user.user.toBase58(), payer.publicKey.toBase58()); + }); + + it("Close an account", () => { + const data = coder.instruction.encode("close_user", {}); + + const ix = new TransactionInstruction({ + keys: [ + { pubkey: payer.publicKey, isSigner: true, isWritable: true }, + { pubkey: userAccountAddress, isSigner: false, isWritable: true }, + { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, + ], + programId, + data, + }); + + const tx = new Transaction().add(ix); + tx.feePayer = payer.publicKey; + tx.recentBlockhash = litesvm.latestBlockhash(); + tx.sign(payer); + litesvm.sendTransaction(tx); + + /** + * Fetch account + */ + const userAccount = litesvm.getAccount(userAccountAddress); + assert.equal(userAccount, null); + }); +}); From 22092958ac72f8609a06fe166ea131682f2ed9d9 Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 09:26:07 +0530 Subject: [PATCH 2/7] chore: update dependencies in package.json and pnpm-lock.yaml - Add litesvm dependency with version 0.4.0 - Upgrade @solana/web3.js to version 1.98.4 - Update related dependencies in pnpm-lock.yaml to reflect changes --- basics/close-account/anchor/package.json | 3 +- basics/close-account/anchor/pnpm-lock.yaml | 190 ++++++++++++++++----- 2 files changed, 154 insertions(+), 39 deletions(-) diff --git a/basics/close-account/anchor/package.json b/basics/close-account/anchor/package.json index 627de5fda..307d6fb0f 100644 --- a/basics/close-account/anchor/package.json +++ b/basics/close-account/anchor/package.json @@ -5,7 +5,8 @@ }, "dependencies": { "@coral-xyz/anchor": "0.32.1", - "@solana/web3.js": "^1.95.2" + "@solana/web3.js": "^1.98.4", + "litesvm": "^0.4.0" }, "devDependencies": { "@types/bn.js": "^5.1.0", diff --git a/basics/close-account/anchor/pnpm-lock.yaml b/basics/close-account/anchor/pnpm-lock.yaml index aae81ea51..9b82a23a9 100644 --- a/basics/close-account/anchor/pnpm-lock.yaml +++ b/basics/close-account/anchor/pnpm-lock.yaml @@ -10,10 +10,13 @@ importers: dependencies: '@coral-xyz/anchor': specifier: 0.32.1 - version: 0.32.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 0.32.1(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) '@solana/web3.js': - specifier: ^1.95.2 - version: 1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: ^1.98.4 + version: 1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) + litesvm: + specifier: ^0.4.0 + version: 0.4.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) devDependencies: '@types/bn.js': specifier: ^5.1.0 @@ -26,7 +29,7 @@ importers: version: 9.1.1 anchor-bankrun: specifier: ^0.4.0 - version: 0.4.0(@coral-xyz/anchor@0.32.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@solana/web3.js@1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(solana-bankrun@0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + version: 0.4.0(@coral-xyz/anchor@0.32.1(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10))(@solana/web3.js@1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10))(solana-bankrun@0.3.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10)) chai: specifier: ^4.3.4 version: 4.4.1 @@ -35,7 +38,7 @@ importers: version: 9.2.2 solana-bankrun: specifier: ^0.3.0 - version: 0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + version: 0.3.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) ts-mocha: specifier: ^10.0.0 version: 10.0.0(mocha@9.2.2) @@ -78,8 +81,27 @@ packages: resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} engines: {node: '>=5.10'} - '@solana/web3.js@1.95.2': - resolution: {integrity: sha512-SjlHp0G4qhuhkQQc+YXdGkI8EerCqwxvgytMgBpzMUQTafrkNant3e7pgilBGgjy/iM40ICvWBLgASTPMrQU7w==} + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/web3.js@1.98.4': + resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} '@swc/helpers@0.5.12': resolution: {integrity: sha512-KMZNXiGibsW9kvZAO1Pam2JPTDBm+KSHMMHWdsyI/1DbIZjT2A6Gy3hblVXUMEDvUAKq+e0vL0X0o54owWji7g==} @@ -168,17 +190,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - bigint-buffer@1.1.5: - resolution: {integrity: sha512-trfYco6AoZ+rKhKnxA0hgX0HAbVP/s808/EuDSe2JDzUnCp/xAsli35Orvk67UrTEcwuxZqYZDmfA2RXJgxVvA==} - engines: {node: '>= 10.0.0'} - binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bindings@1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - bn.js@5.2.1: resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} @@ -227,6 +242,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + check-error@1.0.3: resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} @@ -244,6 +263,10 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + commander@14.0.2: + resolution: {integrity: sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -312,8 +335,8 @@ packages: fast-stable-stringify@1.0.0: resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} - file-uri-to-path@1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} @@ -429,6 +452,46 @@ packages: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} + litesvm-darwin-arm64@0.4.0: + resolution: {integrity: sha512-LN6iZcUQ6Xi5KO/7yJBYSALjjDCI/s/s2PgV3BqM4dpeBaLz+fXX/+qgMcBgpEVgEdEmhelux+WtAMkbEzJfrA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + litesvm-darwin-x64@0.4.0: + resolution: {integrity: sha512-3ltogKQdle8LbakVqoB6plxaNwp6Vb3tnkqa3G5mAvvZNorB2iumThDaTZ381Knl69t566LZm+g/VDZwYfsfhA==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + litesvm-linux-arm64-gnu@0.4.0: + resolution: {integrity: sha512-SWlcRUqkXCMgLoDX/Wqr/S1lff+ggVI9f0YrRJMraxtEyApxutAoW2AWw4tvo6DsEgNwjxgsZOAwnE6bQBv8CA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + litesvm-linux-arm64-musl@0.4.0: + resolution: {integrity: sha512-YMMqwEWJUSWwL0Rwp8dFwl3jvgNU21eI7Qc+BpH9u2yeIRYQTn3rNGDnsK8v3QIZPHQdMo7NrPhzk4XoB1aKPg==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + litesvm-linux-x64-gnu@0.4.0: + resolution: {integrity: sha512-brZ3tFABDVQEYCgci7AO8iVYLw10UXVo97/lpTy75bTzNoqkggg8wFQOrbgCdb9NRwt06Y4Zf8cpIZAoDQq2mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + litesvm-linux-x64-musl@0.4.0: + resolution: {integrity: sha512-D98qdIOuWg4fOewIIiH1D23AtM4I7/3vLKXIL8uQz06D5ev5fsBzNp2gM7libAywTkCYy/u666xgD6PsWhrTaw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + litesvm@0.4.0: + resolution: {integrity: sha512-ySr5mB2ap4SzJpmVR2I5+gjzTH8NJbkg7DYPormzA2U9F4LhfvTTrD17X/k5N3Bn4b5Db6/CwSyX2qc0HrJtNA==} + engines: {node: '>= 20'} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -744,12 +807,12 @@ snapshots: '@coral-xyz/anchor-errors@0.31.1': {} - '@coral-xyz/anchor@0.32.1(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + '@coral-xyz/anchor@0.32.1(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/anchor-errors': 0.31.1 - '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@coral-xyz/borsh': 0.31.1(@solana/web3.js@1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10)) '@noble/hashes': 1.8.0 - '@solana/web3.js': 1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) bn.js: 5.2.2 bs58: 4.0.1 buffer-layout: 1.2.2 @@ -762,11 +825,12 @@ snapshots: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate - '@coral-xyz/borsh@0.31.1(@solana/web3.js@1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + '@coral-xyz/borsh@0.31.1(@solana/web3.js@1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10))': dependencies: - '@solana/web3.js': 1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) bn.js: 5.2.2 buffer-layout: 1.2.2 @@ -782,14 +846,31 @@ snapshots: dependencies: buffer: 6.0.3 - '@solana/web3.js@1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + '@solana/codecs-core@2.3.0(typescript@4.9.5)': + dependencies: + '@solana/errors': 2.3.0(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/codecs-numbers@2.3.0(typescript@4.9.5)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@4.9.5) + '@solana/errors': 2.3.0(typescript@4.9.5) + typescript: 4.9.5 + + '@solana/errors@2.3.0(typescript@4.9.5)': + dependencies: + chalk: 5.6.2 + commander: 14.0.2 + typescript: 4.9.5 + + '@solana/web3.js@1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10)': dependencies: '@babel/runtime': 7.25.0 '@noble/curves': 1.4.2 '@noble/hashes': 1.4.0 '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.3.0(typescript@4.9.5) agentkeepalive: 4.5.0 - bigint-buffer: 1.1.5 bn.js: 5.2.1 borsh: 0.7.0 bs58: 4.0.1 @@ -802,6 +883,7 @@ snapshots: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate '@swc/helpers@0.5.12': @@ -850,11 +932,11 @@ snapshots: dependencies: humanize-ms: 1.2.1 - anchor-bankrun@0.4.0(@coral-xyz/anchor@0.32.1(bufferutil@4.0.8)(utf-8-validate@5.0.10))(@solana/web3.js@1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10))(solana-bankrun@0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + anchor-bankrun@0.4.0(@coral-xyz/anchor@0.32.1(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10))(@solana/web3.js@1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10))(solana-bankrun@0.3.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10)): dependencies: - '@coral-xyz/anchor': 0.32.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) - '@solana/web3.js': 1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) - solana-bankrun: 0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@coral-xyz/anchor': 0.32.1(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) + solana-bankrun: 0.3.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) ansi-colors@4.1.1: {} @@ -883,16 +965,8 @@ snapshots: base64-js@1.5.1: {} - bigint-buffer@1.1.5: - dependencies: - bindings: 1.5.0 - binary-extensions@2.3.0: {} - bindings@1.5.0: - dependencies: - file-uri-to-path: 1.0.0 - bn.js@5.2.1: {} bn.js@5.2.2: {} @@ -949,6 +1023,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.6.2: {} + check-error@1.0.3: dependencies: get-func-name: 2.0.2 @@ -977,6 +1053,8 @@ snapshots: color-name@1.1.4: {} + commander@14.0.2: {} + commander@2.20.3: {} concat-map@0.0.1: {} @@ -1025,7 +1103,7 @@ snapshots: fast-stable-stringify@1.0.0: {} - file-uri-to-path@1.0.0: {} + fastestsmallesttextencoderdecoder@1.0.22: {} fill-range@7.0.1: dependencies: @@ -1134,6 +1212,41 @@ snapshots: jsonparse@1.3.1: {} + litesvm-darwin-arm64@0.4.0: + optional: true + + litesvm-darwin-x64@0.4.0: + optional: true + + litesvm-linux-arm64-gnu@0.4.0: + optional: true + + litesvm-linux-arm64-musl@0.4.0: + optional: true + + litesvm-linux-x64-gnu@0.4.0: + optional: true + + litesvm-linux-x64-musl@0.4.0: + optional: true + + litesvm@0.4.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10): + dependencies: + '@solana/web3.js': 1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) + fastestsmallesttextencoderdecoder: 1.0.22 + optionalDependencies: + litesvm-darwin-arm64: 0.4.0 + litesvm-darwin-x64: 0.4.0 + litesvm-linux-arm64-gnu: 0.4.0 + litesvm-linux-arm64-musl: 0.4.0 + litesvm-linux-x64-gnu: 0.4.0 + litesvm-linux-x64-musl: 0.4.0 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + locate-path@6.0.0: dependencies: p-locate: 5.0.0 @@ -1273,9 +1386,9 @@ snapshots: solana-bankrun-linux-x64-musl@0.3.0: optional: true - solana-bankrun@0.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + solana-bankrun@0.3.0(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10): dependencies: - '@solana/web3.js': 1.95.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.4(bufferutil@4.0.8)(typescript@4.9.5)(utf-8-validate@5.0.10) bs58: 4.0.1 optionalDependencies: solana-bankrun-darwin-arm64: 0.3.0 @@ -1286,6 +1399,7 @@ snapshots: transitivePeerDependencies: - bufferutil - encoding + - typescript - utf-8-validate source-map-support@0.5.21: From ffdcf73d8e773457e13abce3c71f38a80989f5fb Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 11:13:14 +0530 Subject: [PATCH 3/7] refactor: clean up imports in LiteSVM test - Anchor tests natively use Mocha, so replaced unnecessary `node:test` usage with Mocha and Chai for consistency. --- basics/close-account/anchor/tests/litesvm.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/basics/close-account/anchor/tests/litesvm.test.ts b/basics/close-account/anchor/tests/litesvm.test.ts index 684d8ba95..c36336724 100644 --- a/basics/close-account/anchor/tests/litesvm.test.ts +++ b/basics/close-account/anchor/tests/litesvm.test.ts @@ -1,5 +1,3 @@ -import assert from "node:assert/strict"; -import { describe, it } from "node:test"; import anchor from "@coral-xyz/anchor"; import { Keypair, @@ -9,8 +7,8 @@ import { Transaction, TransactionInstruction, } from "@solana/web3.js"; +import { assert } from "chai"; import { LiteSVM } from "litesvm"; - import IDL from "../target/idl/close_account_program.json" with { type: "json", }; From 10102e55fb3ce7848d02a136cf7483a9dbc16aab Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 13:04:17 +0530 Subject: [PATCH 4/7] chore: update TypeScript configuration for close-account anchor - Upgrade TypeScript compiler options to target ES2020 and use nodenext module resolution. - Enable JSON module resolution for improved compatibility. --- basics/close-account/anchor/tsconfig.json | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/basics/close-account/anchor/tsconfig.json b/basics/close-account/anchor/tsconfig.json index a1fc2a26b..88e8865f0 100644 --- a/basics/close-account/anchor/tsconfig.json +++ b/basics/close-account/anchor/tsconfig.json @@ -1,9 +1,10 @@ { - "compilerOptions": { - "typeRoots": ["./node_modules/@types"], - "lib": ["es2015"], - "module": "commonjs", - "target": "es6", - "esModuleInterop": true - } + "compilerOptions": { + "typeRoots": ["./node_modules/@types"], + "lib": ["es2020"], + "module": "nodenext", + "target": "es2020", + "esModuleInterop": true, + "resolveJsonModule": true + } } From 6ede5268b84fd0642bcbea9db488992c09d259e2 Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 13:06:26 +0530 Subject: [PATCH 5/7] fix: update LiteSVM close account test transaction instruction to match IDL - Removed unnecessary SystemProgram reference from transaction instruction keys for clarity and correctness. --- basics/close-account/anchor/tests/litesvm.test.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/basics/close-account/anchor/tests/litesvm.test.ts b/basics/close-account/anchor/tests/litesvm.test.ts index c36336724..c1b8e5433 100644 --- a/basics/close-account/anchor/tests/litesvm.test.ts +++ b/basics/close-account/anchor/tests/litesvm.test.ts @@ -81,7 +81,6 @@ describe("LiteSVM: Close an account", () => { keys: [ { pubkey: payer.publicKey, isSigner: true, isWritable: true }, { pubkey: userAccountAddress, isSigner: false, isWritable: true }, - { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ], programId, data, From a668ba4668836f69eb3e5ab3953338e9af352643 Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 13:16:36 +0530 Subject: [PATCH 6/7] refactor: replace `node:assert` with `chai` in tests (default for Anchor) --- .../anchor/tests/close-account.ts | 46 -------------- basics/close-account/anchor/tests/test.ts | 61 +++++++++++++++++++ 2 files changed, 61 insertions(+), 46 deletions(-) delete mode 100644 basics/close-account/anchor/tests/close-account.ts create mode 100644 basics/close-account/anchor/tests/test.ts diff --git a/basics/close-account/anchor/tests/close-account.ts b/basics/close-account/anchor/tests/close-account.ts deleted file mode 100644 index da436acb6..000000000 --- a/basics/close-account/anchor/tests/close-account.ts +++ /dev/null @@ -1,46 +0,0 @@ -import assert from 'node:assert'; -import type { Program } from '@coral-xyz/anchor'; -import * as anchor from '@coral-xyz/anchor'; -import { PublicKey } from '@solana/web3.js'; -import type { CloseAccountProgram } from '../target/types/close_account_program'; - -describe('close-an-account', () => { - // Configure the client to use the local cluster. - const provider = anchor.AnchorProvider.env(); - anchor.setProvider(provider); - - const program = anchor.workspace.CloseAccountProgram as Program; - const payer = provider.wallet as anchor.Wallet; - - // Derive the PDA for the user's account. - const [userAccountAddress] = PublicKey.findProgramAddressSync([Buffer.from('USER'), payer.publicKey.toBuffer()], program.programId); - - it('Create Account', async () => { - await program.methods - .createUser('John Doe') - .accounts({ - user: payer.publicKey, - userAccount: userAccountAddress, - }) - .rpc(); - - // Fetch the account data - const userAccount = await program.account.userState.fetch(userAccountAddress); - assert.equal(userAccount.name, 'John Doe'); - assert.equal(userAccount.user.toBase58(), payer.publicKey.toBase58()); - }); - - it('Close Account', async () => { - await program.methods - .closeUser() - .accounts({ - user: payer.publicKey, - userAccount: userAccountAddress, - }) - .rpc(); - - // The account should no longer exist, returning null. - const userAccount = await program.account.userState.fetchNullable(userAccountAddress); - assert.equal(userAccount, null); - }); -}); diff --git a/basics/close-account/anchor/tests/test.ts b/basics/close-account/anchor/tests/test.ts new file mode 100644 index 000000000..a546f72e4 --- /dev/null +++ b/basics/close-account/anchor/tests/test.ts @@ -0,0 +1,61 @@ +import type { Program } from "@coral-xyz/anchor"; +import * as anchor from "@coral-xyz/anchor"; +import { PublicKey, SystemProgram } from "@solana/web3.js"; +import { assert } from "chai"; +import type { CloseAccountProgram } from "../target/types/close_account_program.ts"; + +describe("Anchor: Close an account", () => { + /** + * Configure the client to use the local cluster. + */ + const provider = anchor.AnchorProvider.env(); + anchor.setProvider(provider); + + const program = anchor.workspace + .CloseAccountProgram as Program; + const payer = provider.wallet as anchor.Wallet; + + /** + * Derive the PDA for the user's account. + */ + const [userAccountAddress] = PublicKey.findProgramAddressSync( + [Buffer.from("USER"), payer.publicKey.toBuffer()], + program.programId, + ); + + it("Create an account", async () => { + await program.methods + .createUser("John Doe") + .accounts({ + user: payer.publicKey, + userAccount: userAccountAddress, + system_program: SystemProgram.programId, + }) + .rpc(); + + /** + * Fetch account + */ + const userAccount = + await program.account.userState.fetch(userAccountAddress); + assert.equal(userAccount.name, "John Doe"); + assert.equal(userAccount.user.toBase58(), payer.publicKey.toBase58()); + }); + + it("Close an account", async () => { + await program.methods + .closeUser() + .accounts({ + user: payer.publicKey, + userAccount: userAccountAddress, + }) + .rpc(); + + /** + * Fetch account + */ + const userAccount = + await program.account.userState.fetchNullable(userAccountAddress); + assert.equal(userAccount, null); + }); +}); From cccd3b1ce74f0dd7c24bec15b3dd8bde67785d3b Mon Sep 17 00:00:00 2001 From: solwarrior <118261237+sol-warrior@users.noreply.github.com> Date: Fri, 5 Dec 2025 13:19:34 +0530 Subject: [PATCH 7/7] chore: remove deprecated `bankrun` test --- .../anchor/tests/bankrun.test.ts | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 basics/close-account/anchor/tests/bankrun.test.ts diff --git a/basics/close-account/anchor/tests/bankrun.test.ts b/basics/close-account/anchor/tests/bankrun.test.ts deleted file mode 100644 index 76afde229..000000000 --- a/basics/close-account/anchor/tests/bankrun.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import assert from "node:assert"; -import { describe, it } from "node:test"; -import * as anchor from "@coral-xyz/anchor"; -import { PublicKey } from "@solana/web3.js"; -import { BankrunProvider } from "anchor-bankrun"; -import { startAnchor } from "solana-bankrun"; -import type { CloseAccountProgram } from "../target/types/close_account_program"; - -import IDL from "../target/idl/close_account_program.json" with { type: "json" }; -const PROGRAM_ID = new PublicKey(IDL.address); - -describe("close-an-account", async () => { - // Configure the client to use the local cluster. - const context = await startAnchor( - "", - [{ name: "close_account_program", programId: PROGRAM_ID }], - [], - ); - const provider = new BankrunProvider(context); - - const payer = provider.wallet as anchor.Wallet; - const program = new anchor.Program(IDL, provider); - // Derive the PDA for the user's account. - const [userAccountAddress] = PublicKey.findProgramAddressSync( - [Buffer.from("USER"), payer.publicKey.toBuffer()], - program.programId, - ); - - it("Create Account", async () => { - await program.methods - .createUser("John Doe") - .accounts({ - user: payer.publicKey, - }) - .rpc(); - - // Fetch the account data - const userAccount = - await program.account.userState.fetch(userAccountAddress); - assert.equal(userAccount.name, "John Doe"); - assert.equal(userAccount.user.toBase58(), payer.publicKey.toBase58()); - }); - - it("Close Account", async () => { - await program.methods - .closeUser() - .accounts({ - user: payer.publicKey, - }) - .rpc(); - - // The account should no longer exist, returning null. - try { - const userAccount = - await program.account.userState.fetchNullable(userAccountAddress); - assert.equal(userAccount, null); - } catch (err) { - // Won't return null and will throw an error in anchor-bankrun' - assert.equal(err.message, `Could not find ${userAccountAddress}`); - } - }); -});