Typescript
Тестування з LiteSVM

Тестування з LiteSVM

LiteSVM з TypeScript

Пакет litesvm надає основну інфраструктуру тестування для створення легкого середовища Solana, де ви можете безпосередньо маніпулювати станом рахунків та виконувати транзакції для ваших програм.

Перші кроки

Додайте LiteSVM до вашого проєкту:

bash
npm i --save-dev litesvm

Основи LiteSVM

Почніть з оголошення ідентифікатора вашої програми та створення екземпляра LiteSVM.

Використовуйте точно такий самий ідентифікатор програми, який ви визначили у своїй програмі, щоб забезпечити правильне виконання транзакцій і уникнути помилок ProgramMismatch під час тестування:

ts
import { LiteSVM } from "litesvm";
import { PublicKey } from "@solana/web3.js";
 
const programId = new PublicKey("22222222222222222222222222222222222222222222");
 
describe("test", () => {
    // Create a new instance of LiteSVM
    const svm = new LiteSVM();
 
    // Load the program with the right public key
    svm.addProgramFromFile(programId, "target/deploy/program.so");
})

Для виконання тестів створіть об'єкт транзакції та використовуйте функцію .sendTransaction(tx):

ts
import { LiteSVM } from "litesvm";
import { Transaction } from "@solana/web3.js";
 
describe("test", () => {
    // Create a new instance of LiteSVM
    const svm = new LiteSVM();
 
    // Create a new Transaction
    const tx = new Transaction();
 
    // Add the latest blockhash
    tx.recentBlockhash = svm.latestBlockhash();
 
    // Add the instructions and the signers
    // tx.add(...ixs);
    // tx.sign(...signersKeypair);
 
    // Send the transaction
    svm.sendTransaction(tx);
})

Рахунки

Під час тестування програм Solana з LiteSVM ви працюватимете з кількома типами рахунків, які відображають сценарії виконання програм у реальному світі.

Розуміння того, як правильно створювати ці рахунки, є важливим для ефективного тестування.

Системні рахунки

Найбільш фундаментальним типом рахунку є системний рахунок, який має два основні варіанти:

  • Рахунки платника: рахунки з лампортами, які фінансують створення програмних рахунків або переказ лампортів
  • Неініціалізовані рахунки: порожні рахунки без лампортів, зазвичай використовуються для представлення програмних рахунків, що очікують ініціалізації

Системні рахунки не містять даних і належать Системній Програмі. Основна відмінність між рахунками платників та неініціалізованими рахунками полягає в їхньому балансі лампортів: платники мають кошти, тоді як неініціалізовані рахунки починаються порожніми.

Ось як створити рахунок payer у LiteSVM:

ts
import { LiteSVM } from "litesvm";
import { Keypair, SystemProgram } from "@solana/web3.js";
 
describe("test", () => {
    // Create a new instance of LiteSVM
    const svm = new LiteSVM();
 
    // Create a new Account
    const account = Keypair.generate();
 
    // Add the Account with the modified data
    svm.setAccount(account.publicKey, {
        lamports: 100_000_000,
        data: Buffer.alloc(0),
        owner: SystemProgram.programId,
        executable: false,
    }); 
})

Неініціалізований рахунок — це просто звичайний згенерований рахунок з Keypair.generate() - додаткове налаштування не потрібне.

Програмні рахунки

Для програмних рахунків, які містять користувацькі структури даних, ви можете використовувати подібний підхід. Вам також потрібно буде серіалізувати дані рахунку в буфер, що можна зробити вручну або за допомогою бібліотеки, такої як @coral-xyz/borsh (див. приклад тут).

ts
import { LiteSVM } from "litesvm";
import { Keypair } from "@solana/web3.js";
 
describe("test", () => {
    // Create a new instance of LiteSVM
    const svm = new LiteSVM();
 
    // Create a new Account
    const account = Keypair.generate();
 
    // Populate the data of the Account
    const accountData = Buffer.alloc(SIZE_OF_THE_ACCOUNT);
 
    // Serialize the account data into the byte buffer defined above
    // ...
 
    // Grab the minimum amount of lamports to make it rent exempt
    const lamports = svm.minimumBalanceForRentExemption(SIZE_OF_THE_ACCOUNT);
 
    // Add the Account with the modified data
    svm.setAccount(account.publicKey, {
        lamports,
        data: accountData,
        owner: PROGRAM_ID,
        executable: false,
    });
})

Під час тестування вам не потрібно розраховувати точну ренту. Ви можете встановити lamports на велике значення, наприклад 100_000_000_000, і пропустити розрахунок ренти, оскільки це не реальні кошти.

Токен-акаунти

Для серіалізації даних для SPL Token акаунтів ви можете використовувати AccountLayout та MintLayout з @solana/spl-token.

ts
import { LiteSVM } from "litesvm";
import { Keypair } from "@solana/web3.js";
import { TOKEN_PROGRAM_ID, AccountLayout, MintLayout, ACCOUNT_SIZE, MINT_SIZE } from "@solana/spl-token"
 
describe("test", () => {
    // Create a new instance of LiteSVM
    const svm = new LiteSVM();
 
    const owner = Keypair.generate();
 
    // Create a new Mint Account
    const mint = Keypair.generate();
 
    // Populate the data of the Mint Account
    let mintData = Buffer.alloc(MINT_SIZE);
    MintLayout.encode(
        {
          mintAuthorityOption: 1,
          mintAuthority: owner.publicKey,
          supply: BigInt(0),
          decimals: 0,
          isInitialized: true,
          freezeAuthorityOption: 0,
          freezeAuthority: PublicKey.default,
        },
        mintData
    )
 
    // Grab the minimum amount of lamports to make it rent exempt
    const lamports = svm.minimumBalanceForRentExemption(MINT_SIZE);
 
    // Add the Account with the modified data
    svm.setAccount(mint.publicKey, {
        lamports,
        data: mintData,
        owner: TOKEN_PROGRAM_ID,
        executable: false,
    });
 
    // Create a new Token Account
    const tokenAccount = Keypair.generate();
 
    // Populate the data of the Token Account
    const tokenAccountData = Buffer.alloc(ACCOUNT_SIZE);
    AccountLayout.encode(
        {
            mint: mint.publicKey,
            owner: owner.publicKey,
            amount: BigInt(100),
            delegateOption: 0,
            delegate: PublicKey.default,
            delegatedAmount: BigInt(0),
            state: 1,
            isNativeOption: 0,
            isNative: BigInt(0),
            closeAuthorityOption: 0,
            closeAuthority: PublicKey.default,
        },
        tokenAccountData,
    );
 
    // Grab the minimum amount of lamports to make it rent exempt
    const lamports = svm.minimumBalanceForRentExemption(ACCOUNT_SIZE);
 
    // Add the Account with the modified data
    svm.setAccount(tokenAccount.publicKey, {
        lamports,
        data: tokenAccountData,
        owner: TOKEN_PROGRAM_ID,
        executable: false,
    });
})

Виконання

Після створення акаунтів та додавання їх до вашого екземпляра LiteSVM ви можете надсилати транзакції та перевіряти логіку вашої програми.

Перед надсиланням транзакції ви можете симулювати результат:

ts
// Simulate before executing
const simulatedResult = svm.simulateTransaction(tx);

Потім надішліть транзакцію та перевірте її логи:

ts
// Execute and inspect logs
const result = svm.sendTransaction(tx);
console.log(result.logs);

Розширені функції

До та після виконання весь реєстр, що міститься у вашому екземплярі LiteSVM, можна читати та налаштовувати.

Ви можете маніпулювати значеннями sysvar, такими як годинник:

ts
// Change the Clock
const newClock = svm.getClock();
newClock.unixTimestamp = 50n;
svm.setClock(newClock);
 
// Jump to a certain Slot
svm.warpToSlot(500);
 
// Expire the current blockhash
svm.expireBlockhash();

Ви також можете читати дані акаунтів та протоколу:

ts
// Get all the information about an account (data, lamports, owner, ...)
svm.getAccount(account.publicKey);
 
// Get the lamport balance of an account
svm.getBalance(account.publicKey);

Або налаштувати поведінку середовища виконання:

ts
// Sets the compute budget
const computeBudget = new ComputeBudget();
computeBudget.computeUnitLimit = 2_000_000n;
svm.withComputeBudget(computeBudget);
 
// Sets Sigverify as active
svm.withSigverify(true);
 
// Sets the Blockhash check as active
svm.withBlockhashCheck(true);
 
// Sets the default Sysvars
svm.withSysvars();
 
// Set the FeatureSet to use
svm.withFeatureSet(new FeatureSet(...))
Blueshift © 2025Commit: 6d01265
Blueshift | Тестування з LiteSVM | LiteSVM з Typescript