Documentation Index
Fetch the complete documentation index at: https://docs.privora.xyz/llms.txt
Use this file to discover all available pages before exploring further.
The @privora/test-utils-ts package provides shared utilities for testing Privora applications in TypeScript.
Installation
npm install --save-dev @privora/test-utils-ts
Quick Start
import {
createFundedAccount,
requireSequencer,
getRpcUrl,
} from '@privora/test-utils-ts';
beforeAll(async () => {
// Ensure sequencer is running (fails fast if not)
await requireSequencer();
// Create a funded test account
const { keypair, balance } = await createFundedAccount();
console.log(`Account ${keypair.publicKey.toBase58()} funded with ${balance} lamports`);
});
Constants
import {
DEFAULT_RPC_URL, // 'http://localhost:18899'
DEFAULT_AIRDROP_LAMPORTS, // 2_000_000_000 (2 SOL)
DEFAULT_AIRDROP_WAIT_MS, // 1000
DEFAULT_TEST_TIMEOUT_MS, // 30_000
FHE_TEST_TIMEOUT_MS, // 60_000
TEST_SEED, // Uint8Array(32) for deterministic keypairs
getRpcUrl, // Returns RPC_URL env var or DEFAULT_RPC_URL
getAirdropAmount, // Returns AIRDROP_AMOUNT env var or default
} from '@privora/test-utils-ts';
getRpcUrl
function getRpcUrl(): string
Returns the RPC URL from the RPC_URL environment variable, or falls back to DEFAULT_RPC_URL.
getAirdropAmount
function getAirdropAmount(): number
Returns the airdrop amount from the AIRDROP_AMOUNT environment variable, or falls back to DEFAULT_AIRDROP_LAMPORTS.
Sequencer Utilities
requireSequencer
async function requireSequencer(rpcUrl?: string): Promise<void>
Check that the sequencer is running and exit the process if not. Useful for test setup that should fail fast.
beforeAll(async () => {
await requireSequencer();
});
waitForSequencer
async function waitForSequencer(
rpcUrl?: string,
maxWaitMs?: number, // default: 30000
intervalMs?: number // default: 1000
): Promise<void>
Wait for the sequencer to become healthy. Throws an error if not ready within the timeout.
// Wait up to 60 seconds for sequencer
await waitForSequencer(undefined, 60000);
checkSequencerHealth
async function checkSequencerHealth(rpcUrl?: string): Promise<SequencerStatus>
interface SequencerStatus {
healthy: boolean;
url: string;
error?: string;
}
Check if the sequencer is running and healthy.
const status = await checkSequencerHealth();
if (!status.healthy) {
console.error('Sequencer error:', status.error);
}
rpcCall
async function rpcCall<T>(
method: string,
params?: unknown[],
rpcUrl?: string
): Promise<T>
Make a raw JSON-RPC call to the sequencer.
const result = await rpcCall<string>('getVersion', []);
Funded Account Utilities
createFundedAccount
async function createFundedAccount(options?: {
keypair?: Keypair;
lamports?: number;
rpcUrl?: string;
waitMs?: number;
}): Promise<FundedAccount>
interface FundedAccount {
keypair: Keypair;
publicKey: PublicKey;
balance: number;
}
Create a new keypair, request an airdrop, and verify the balance.
// Create with defaults
const account = await createFundedAccount();
// With custom options
const account = await createFundedAccount({
lamports: 5_000_000_000, // 5 SOL
waitMs: 2000, // Wait 2s for confirmation
});
requestAirdrop
async function requestAirdrop(
publicKey: PublicKey | string,
lamports?: number,
rpcUrl?: string
): Promise<string>
Request an airdrop to the given public key. Returns the transaction signature.
getBalance
async function getBalance(
publicKey: PublicKey | string,
rpcUrl?: string
): Promise<number>
Get the balance of an account in lamports.
getTestKeypair
function getTestKeypair(): Keypair
Create a deterministic test keypair from the standard test seed. Useful for reproducible tests.
getTestKeypairWithSeed
function getTestKeypairWithSeed(seedModifier: number): Keypair
Create a deterministic test keypair from a custom seed modifier.
const alice = getTestKeypairWithSeed(1);
const bob = getTestKeypairWithSeed(2);
Program Deployment
deployProgram
async function deployProgram(
programId: string,
programPath: string,
rpcUrl?: string
): Promise<DeployResult>
interface DeployResult {
success: boolean;
programId: string;
message?: string;
alreadyDeployed?: boolean;
}
Deploy a program to the sequencer from a .so file.
buildProgram
function buildProgram(programDir: string): boolean
Build a program using cargo build-sbf. Returns true if successful.
buildAndDeploy
async function buildAndDeploy(options: {
programId: string;
programDir: string;
programSoPath: string;
rpcUrl?: string;
buildIfMissing?: boolean; // default: true
}): Promise<DeployResult>
Build (if needed) and deploy a program.
const result = await buildAndDeploy({
programId: 'MyProgram11111111111111111111111111111111',
programDir: './programs/my-program',
programSoPath: './target/deploy/my_program.so',
});
if (result.success) {
console.log('Program deployed:', result.programId);
}
findExamplesRoot
function findExamplesRoot(startPath: string): string | null
Find the examples directory root from a given path.
Vitest Configuration
The package provides a base Vitest configuration optimized for FHE tests:
// vitest.config.ts
import { defineConfig, mergeConfig } from 'vitest/config';
import baseConfig from '@privora/test-utils-ts/vitest';
export default mergeConfig(baseConfig, defineConfig({
// Your overrides here
}));
The base config includes:
- 60-second test timeout for FHE operations
- 30-second hook timeout
- Sequential test execution (no shuffling)
- Single fork mode for WASM stability
- Verbose reporter
Example Test Setup
import { describe, it, expect, beforeAll } from 'vitest';
import {
requireSequencer,
createFundedAccount,
buildAndDeploy,
getRpcUrl,
FHE_TEST_TIMEOUT_MS,
} from '@privora/test-utils-ts';
import { Privora } from '@privora/sdk';
describe('My FHE Tests', () => {
let privora: Privora;
let payer: Keypair;
beforeAll(async () => {
// Ensure sequencer is running
await requireSequencer();
// Deploy program if needed
await buildAndDeploy({
programId: 'MyProgram11111111111111111111111111111111',
programDir: './programs/my-program',
programSoPath: './target/deploy/my_program.so',
});
// Create funded account
const account = await createFundedAccount();
payer = account.keypair;
// Connect to Privora
privora = await Privora.connect(getRpcUrl());
}, FHE_TEST_TIMEOUT_MS);
it('encrypts and submits data', async () => {
const encrypted = privora.encrypt(100, 'u8');
const hash = await privora.submit(encrypted);
expect(hash).toBeDefined();
});
});