π TypeSOL has a new home on GitHub
Our GitHub account was suspended on Nov 2, most likely by GitHub's automated protection: our CI/CD ran a lot of test runs, merges and releases in a short time. We're not alone here, lately many developers have reported the same on Reddit and GitHub's community forum.
We contacted GitHub Support and haven't heard back yet. Development didn't stop, so we moved everything to a new organization: https://t.co/F5lGpF2npE
What moved
β’ typesol, benchmarks and the org profile, with their full history
β’ All 32 release tags
β’ https://t.co/py6WvEOHEC, the docs and the playground now link to the new home
What didn't change
β’ npm: same package, the TypeSOL CLI, installs and works as before
β’ https://t.co/py6WvEOHEC and everything on it
Once the original account is restored, the repositories move back to it, and we'll say so here first. If you starred the old repo, a star on the new one helps a lot.
Testing what a Solana program emits is now one line in TypeSOL.
https://t.co/9DhG4Vxy3s(res) gives you every event a transaction emitted, decoded from your program's IDL and in the order they happened, whether it came from emit as a log line or from emitCpi inside an inner instruction. No other package needed.
New in v0.48.0, alongside the Meteora port.
A program that moves a Token-2022 token with a transfer hook has to hand Token-2022 the hook's extra accounts, in the right order, with the right flags.
In TypeSOL v0.48.0 that's one call. transferCheckedWithHook resolves every extra account from the hook's own list, the way the transfer hook interface does on chain, with the same refusals and error codes. A mint without a hook gets a plain transferChecked.
Account state at a chosen slot is exactly what a program test wants.
TypeSOL's ports are already checked this way with accounts read from mainnet: real Meteora pools and DAMM configs loaded into a local VM, then the same transactions run on the port and on the deployed binary. Picking the exact slot, or the state right after one transaction, makes that sharper.
Introducing the Historical Accounts API (Beta)
See what any account, pool, or wallet looked like at any point in time -- get state at the end of a slot, or after individual transactions
Backtest trades, simulate transactions against historical state and see exactly what changed
Meteora's Dynamic Bonding Curve is now ported to TypeScript with TypeSOL: all 35 instructions.
Config, pool creation on SPL and Token-2022 (transfer hooks included), swaps, fee claims, and graduation into DAMM v2 or DAMM v1. Every test transaction runs on the port and on the binary deployed on mainnet, side by side, and both must leave the same accounts, the same events and the same errors.
The port is in the repo under Meteora's own licence. What the compiler needed for it, like Token-2022 transfers with hooks by CPI, ships in v0.48.0, on npm now.
Your first Solana program doesn't need an install.
https://t.co/ODi0Lhfe0Q runs the TypeSOL 0.47.0 compiler in your browser. Pick one of the examples or write your own, and see the C, the IDL and the typed client it compiles to, with completions as you type. Nothing you type leaves the page.
When it's ready to build, test and deploy, the TypeSOL CLI's init command makes the project.
In a TypeSOL test, a bad argument fails right where you wrote it.
Give a u64 a negative number, or one too big for 64 bits, and the test stops with an error naming the instruction and the argument. Your program never receives a value it would read as some other number.
Byte arguments take a Uint8Array or a plain number[], and test transactions can carry more than 1,000 bytes of instruction data. All in v0.47.0.
Knowing what actually runs on chain had a good week: Watchtower alerts on program upgrades, Circular Replay rebuilds the exact state a transaction ran against.
For programs written in TypeScript, typesol verify --docker rebuilds one from its source in a pinned container and compares it with the bytes deployed at its address.
TypeSOL v0.47.0 is on npm: a lighter new project.
The test kit now encodes instruction arguments and decodes accounts with its own Borsh coder, read from the IDL and checked against Anchor's on random values for every example program. So a new project no longer pulls in Anchor's TypeScript package: npm install adds 96 packages instead of 156.
Your programs don't change. Every one builds to the same bytes as before.
Know TypeScript, new to Solana? Start here.
The TypeSOL language reference is now a guide you read in order: the basics ("Solana in a dozen lines"), types, statements, accounts, PDAs, errors and events, CPI, the chain, and native programs once you are ready. Every page ends with what to read next, and its terms link to a glossary.
Every example in it compiles, and a test checks that each refused construct is refused with the exact message the page quotes.
Try it in the browser first: https://t.co/ODi0Lhfe0Q
A port is easy to pass with tests you wrote yourself. So the Phoenix port also runs Phoenix's own.
Every test function in its repository at the deployed commit is mapped to a case on the mainnet binary and on the TypeSOL port: 37 added and run whole, 11 already covered by the port's instruction tests, and 2 that only check types at compile time.
Each refusal a test expects is pinned to the original's error and message, and the test's own checks on balances, the book and fees are made on chain.
November 1 to 12, one release at a time.
Raydium CLMM and Jito's three MEV programs. Then Marginfi v2, Raydium AMM v4, Raydium CP-Swap, SPL Stake Pool and Phoenix. Each one ported to TypeScript in full and run beside the binary that is deployed today, same outcomes, same logs, same bytes.
Then a release that makes every build come out the same on any of three kinds of machine.
Twelve days, seven mainnet ports.
Why write a Solana program in TypeScript with TypeSOL:
It compiles to native SBF, with no interpreter on chain and no generated Rust. The program, its tests and its typed client are one language. Every arithmetic operation is checked, and the account checks come from your types. Eight deployed programs are ported in full and run beside their mainnet binaries. And the same source builds to the same bytes on any of three kinds of machine.
Builders talk at https://t.co/kFBFp0UaG9.
To build the same bytes on every machine, TypeSOL v0.45.0 stopped linking the platform's integer builtins and ships its own: 128-bit multiply, divide, remainder and shifts, and signed 64-bit division.
Each one runs as SBF on SBPF v0, v1 and v2 against a BigInt reference and against compiler-builtins, and the test fails if any call costs more units than the library's.
Division now takes the shortest route for its operands' sizes. Totals over whole test suites: Raydium AMM v4 down 7.9%, Marginfi 5.1%, CLMM 5.0%.
An order book has to survive its worst transaction, not its average one.
The heaviest cases in the Phoenix tests, mainnet binary against the TypeSOL port: cancelling 200 orders in a book of 8,000 takes 1,184,623 compute units against 471,050. A match of 300 fills, its events sent in three batches: 443,217 against 217,847.
Same outcome, same logs, same bytes, and well clear of the 1.4M transaction limit.
How do you test an order book port? Let it trade.
The Phoenix port runs a seeded random walk over two books started nearly full. Makers and takers deposit, withdraw, place every kind of order, reduce and cancel, sometimes with someone else's or a bit-flipped id. The authority evicts, force-cancels and collects fees, the clock moves so orders expire, and some packets arrive corrupted.
Every step runs on the mainnet binary and on the port, and must match. After each one, an oracle checks that the vaults hold exactly the traders' locked and free lots plus the unclaimed fees. A one-off run of five seeds: 21,593 transactions, no difference.
A native Solana program talks to its callers in ways Anchor hides, and Phoenix uses all of them. So TypeSOL native entries now can too.
setReturnData hands bytes back to the caller, the way Phoenix returns the ids of the orders that rested. logComputeUnits writes the runtime's own "units remaining" line. And a program whose checks already logged can fail quietly, returning only the error, about a hundred compute units cheaper each time.
Checked against the lines the Phoenix binary writes.
TypeSOL v0.45.0 is on npm: one source, the same bytes on every machine.
A TypeSOL program now builds to the same binary on macOS arm64, Linux arm64 and Linux x86_64. All 76 programs in the repository, built on all three for SBPF v0, came out identical. And typesol verify --docker rebuilds a deployed program in a pinned container, so anyone can check that what runs on chain came from the source they read.
No slower for it: of 18,085 transactions sent to the programs whose bytes changed, none costs more and 2,659 cost less.
Phoenix, the on-chain order book, instruction by instruction: the mainnet binary against its TypeSOL port, same transactions, same results.
Creating a market: 79,146 compute units against 10,940. Requesting a seat: 14,900 against 4,599. Withdrawing funds: 17,760 against 6,201. Collecting fees: 13,814 against 4,977.
The token transfers inside cost the same in both, and the totals still come out at about a third.