A Python testing/fuzzing harness for Solana programs, backed by litesvm through a Rust/pyo3 extension. You drive a fast in-process SVM from Python: fund accounts, build & send (or simulate) transactions, and inspect a decoded call trace — with typed instruction builders generated from Anchor IDLs.
This guide covers the runtime harness API; the IDL → Python generator is covered in §7.
from wake_sol import svm, Account
alice, bob = Account.new(), Account.new()
svm.airdrop(alice, 1_000_000_000)
res = alice.tx(svm.system.transfer(1_000_000, from_=alice, to=bob))
print(res.call_trace) # decoded, colored call tree
assert res.success- 1 · Getting started — install, the global
svm, fund an account, send your first transaction, read the result. - 2 · Accounts — the
Accounthandle: existence vs. keypair, creating/viewing/deriving, reading state, funding, labels. - 3 · Transactions —
account.tx(...)/account.simulate(...), the signing model (signers=), v0 transactions (lookup_tables=), and theTransactionResult. - 4 · Call traces — the decoded instruction tree, per-node program logs, errors, and Rich rendering.
- 5 · The SVM & sysvars —
LiteSVMconfig, feature gates, blockhash/slot control, rent, and typed sysvar get/set (clock time-travel, etc.). - 6 · Types & encoding — width aliases (
u64,.max),pubkey,Opt/BorshEnum,BorshStruct.encode()/.decode(),MetaLike. - 7 · Programs & addresses — built-in builders (
svm.system,svm.token), well-known address constants, and generated (pytypes) programs. - 8 · Fuzzing — the stateful
FuzzTestengine:@flow/@invariant, randomized sequences, reproducibility from the seed, and reading the flow-stats output. - 9 · Signing & precompiles — detached signing (
account.sign,secp256k1/secp256r1keys), theSignedMessageclaim, and the ed25519/secp256k1/secp256r1 verify-instruction builders (with cross-instructionRefs). - 10 · Return values & events — decoded return data (
return_value,decode_return) and events (res.events, the⚡assertion surface). - 11 · Errors — the raise-by-default contract, the typed
TransactionFailedhierarchy,must_fail/may_fail, and registering custom program errors. - 12 · Address Lookup Tables & v0 transactions — the
create_lookup_tablecheatcode, the official ALT-program builders, and v0 transactions vialookup_tables=. - 13 · Mainnet forking —
svm.fork(...), offline/cache replay,exclude=for auditing your own build, and pinning programs (fork_programs/forked_accounts). - 14 · Parallel running —
wake-sol test -P N: N workers of the same suite (N seeds) or sharded (--dist uniform), per-worker seeds & logs, and aggregated results.
- Instruction builders are classmethods.
Program.ix(...)— no instantiation. A builder is a pure function of its arguments: it builds anInstructionand never reads chain state, so there is nothing for an instance to hold. State-dependent surfaces are the opposite and do hang off the SVM (svm.clock,svm.set_rent(...)— see §5), while sysvar and program addresses are plain module-level constants (see §7). - Instruction builders are data-first, accounts keyword-only. Every builder method takes the instruction's data args positionally (in IDL order) and its accounts as keyword-only params:
ix(arg1, arg2, *, account_a, account_b=None, remaining_accounts=()). This holds for the built-ins (svm.system,svm.token) and for every generated program. - Addresses are
MetaLike. Anywhere an account is expected you can pass aPubkey, anAccount, an explicitAccountMeta, or a base58str/ 32 rawbytes/ big-endianint— the builder coerces it (see §6). - One import root. Almost everything is re-exported from the top-level
wake_solpackage, sofrom wake_sol import svm, Account, Pubkey, u64, RENT_SYSVAR, …works.