@typesol/cli 0.23.0 → 0.24.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +77 -2
  2. package/README.md +18 -15
  3. package/SECURITY.md +1 -1
  4. package/dist/clientgen.js +222 -61
  5. package/dist/compiler/analyze.js +132 -20
  6. package/dist/compiler/emit/base.d.ts +27 -4
  7. package/dist/compiler/emit/base.js +68 -15
  8. package/dist/compiler/emit/calls.d.ts +7 -0
  9. package/dist/compiler/emit/calls.js +99 -9
  10. package/dist/compiler/emit/cpi.d.ts +33 -1
  11. package/dist/compiler/emit/cpi.js +353 -110
  12. package/dist/compiler/emit/expressions.d.ts +9 -1
  13. package/dist/compiler/emit/expressions.js +16 -12
  14. package/dist/compiler/emit/function.js +3 -1
  15. package/dist/compiler/emit/shared.d.ts +11 -1
  16. package/dist/compiler/emit/statements.d.ts +4 -2
  17. package/dist/compiler/emit/statements.js +128 -27
  18. package/dist/compiler/emit/storage.d.ts +6 -2
  19. package/dist/compiler/emit/storage.js +36 -32
  20. package/dist/compiler/model.d.ts +8 -0
  21. package/dist/idlpublish.d.ts +6 -1
  22. package/dist/idlpublish.js +47 -5
  23. package/dist/portgen.js +1 -1
  24. package/dist/svmrpc.d.ts +7 -1
  25. package/dist/svmrpc.js +133 -19
  26. package/dist/testing.js +23 -3
  27. package/docs/architecture.md +26 -2
  28. package/docs/cli.md +2 -2
  29. package/docs/client.md +13 -10
  30. package/docs/errors.md +9 -3
  31. package/docs/language.md +18 -17
  32. package/docs/mainnet.md +1 -1
  33. package/docs/migrate-from-anchor.md +8 -9
  34. package/docs/runtime.md +59 -0
  35. package/docs/test-your-program.md +6 -2
  36. package/docs/testing.md +1 -1
  37. package/docs/troubleshooting.md +3 -2
  38. package/lib/typesol.d.ts +120 -21
  39. package/package.json +1 -1
  40. package/runtime/typesol_rt.h +106 -28
package/CHANGELOG.md CHANGED
@@ -1,10 +1,85 @@
1
1
  # Changelog
2
2
 
3
- TypeSOL follows [semantic versioning](https://semver.org/) with the 0.x rules described in CONTRIBUTING.md:
4
- until 1.0, a minor version may change the language, the IDL layout or error codes, and says so here.
3
+ TypeSOL follows the organization's [versioning policy](https://github.com/typesol/.github/blob/main/VERSIONING.md)
4
+ (compiler specifics in CONTRIBUTING.md): until 1.0, a minor version may change the language, the IDL layout or error
5
+ codes, and says so here.
5
6
 
6
7
  ## Unreleased
7
8
 
9
+ ## 0.24.1 — 2026-10-28
10
+
11
+ Smaller programs and fewer compute units, with the same results; no change to the language, IDLs or error codes. Also
12
+ new contributor docs (repository layout, a guide to the C runtime). Not externally audited (see SECURITY.md).
13
+
14
+ ### Performance
15
+ - Smaller programs, same results: the rent calculation no longer links soft-float (an exact integer equivalent,
16
+ checked against IEEE doubles), and every failure logs through one shared call. The benchmarked programs are 11.6%
17
+ smaller in total (counter 13.1 → 11.0 KB, escrow 23.9 → 21.3 KB). A failing instruction costs 2 more compute units;
18
+ successful ones are unchanged.
19
+ - An identical signer-seed list in the same scope reuses the array declared for the first CPI (escrow `take_offer`
20
+ 7058 → 7044, `refund_offer` 4287 → 4271).
21
+
22
+ ## 0.24.0 — 2026-10-28
23
+
24
+ Functions as values, closures for any helper, stored `map` to structs and text, Metaplex Core external plugins, and
25
+ the fixes and identical-result compute-unit savings from a full code review: expanded helpers see only their own
26
+ scope, generated clients read only their program's events, and IDLs from the chain are read with limits. Not externally
27
+ audited (see SECURITY.md).
28
+
29
+ ### Added
30
+ - Functions as values: `const h = g`, and functions that return functions (`function adder(n: u64): (x: u64) => u64
31
+ { return (x) => x + n; }`), which make a closure where they are called (`const add5 = adder(5n)`, `adder(5n)(x)`).
32
+ - Closures given to helpers with type parameters or accounts: the helper is expanded where it is called, its type
33
+ parameters bound from the call and its accounts the caller's.
34
+ - A stored `map` to structs or text: `const ps: FixedVec<Pair, 8> = xs.map((o) => ({ qty: o.qty, doubled: o.qty * 2n }))`,
35
+ `const names: FixedVec<FixedString<8>, 4> = xs.map(…)`.
36
+ - A struct argument holding a FixedVec, when the struct is only an argument: read as Anchor sends it (the FixedVec a
37
+ Borsh Vec), as a `@layout borsh` struct is.
38
+ - Metaplex Core external plugin adapters: `addExternalPlugin`, `removeExternalPlugin`, `writeExternalPluginData` and
39
+ their Collection forms, for AppData, Oracle and LifecycleHook (and the Linked forms), checked against the Core program
40
+ (Core itself answers lifecycle hooks with NotAvailable for now).
41
+
42
+ ### Changed
43
+ - Fewer compute units, same results: the PDA bump search builds its seed list once, a growing account reads the rent
44
+ sysvar once, integers become text two digits at a time, a lone `${n}` template is not copied again, and
45
+ `list = fixedVec([])` clears the list in place. For example escrow `make` 3638 → 3605, `take_offer` 7117 → 7058,
46
+ `transfer_tokens` 8467 → 8367 CU.
47
+ - `eventsOf` takes the transaction with its account keys (`transaction.message.accountKeys`, as getTransaction returns
48
+ it); without them it reads log events only. `errorCode` / `isError` also read the RPC's JSON error
49
+ (`{ InstructionError: [0, { Custom: 6000 }] }`).
50
+ - `svmConnection`: `accountNotifications` yields after each later transaction that names the account (no snapshot of
51
+ it as it is), `logsNotifications` honors `{ mentions }` and includes failed transactions (with `err`), simulation
52
+ errors are in the RPC's JSON shape, and `getTransaction` returns the account keys and each inner instruction's
53
+ program index.
54
+ - Compiler messages about accounts with a growable Vec say "has a growable Vec" instead of "ends in a Vec", and the
55
+ field-type list no longer says `Vec<T> (last)`, since a Vec can be any field (0.23.0).
56
+
57
+ ### Fixed
58
+ - A helper expanded where it is called (given a closure), and a function a helper made, read a module constant as
59
+ the instruction argument of the same name; they now see only their parameters and the module.
60
+ - A struct parameter of a closure or expanded helper could be used after a push, pop or clear moved the Vec it points
61
+ into (a stale pointer); that is refused like any other reference across the move.
62
+ - A closure parameter named like an account read the account; it is refused.
63
+ - A helper from another file, expanded here or typed from an arrow passed to it, resolved its types with this file's
64
+ imports (an aliased or unimported type failed to compile, or an annotation was dropped); its own file's imports are
65
+ used, and `applyT<u64>((v) => …)` takes the type given at the call.
66
+ - A struct with a FixedVec held in a data enum variant was read as Borsh when also an argument; that conflict is refused.
67
+ - Generated clients read only this program's events: `parseEvents` follows the invoke stack and reads a `Program data:`
68
+ line only while the program is the innermost one running, and `eventsOf` reads only `emitCpi` inner instructions that
69
+ call the program. Another program can no longer forge them.
70
+ - `watchEvents` skips failed transactions.
71
+ - `typesol client` refuses malformed generic arguments, array lengths that are not whole numbers and `repr` alignments
72
+ that are not powers of two, and caps generic instantiation (256 types, 16 levels): a ClientIdlError instead of a crash
73
+ or a hang. Sizing deeply nested structs no longer takes exponential time.
74
+ - Accounts named like `Object.prototype` properties (`constructor`, `toString`, …) are read as given, not inherited.
75
+ - `resolve.<ix>` derives a has_one source that is a PDA (a `config` PDA) before reading it, and names the account to
76
+ pass when a source is missing.
77
+ - Notes and errors escape control characters from the IDL.
78
+ - Reading an IDL from the chain caps inflation at 16 MiB, checks Anchor's IdlAccount discriminator, and refuses a
79
+ Program Metadata IDL that links to a URL or another account instead of following it.
80
+ - `typesol/testing`'s `returned()` decodes string, bytes, f32 and f64 return values, and throws for types it cannot
81
+ decode instead of misreading them.
82
+
8
83
  ## 0.23.0 — 2026-10-28
9
84
 
10
85
  Language limits lifted: `map` and `filter`, any number of growable Vecs per account, closures and arrow functions as
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  <p align="center">
8
8
  <a href="https://github.com/typesol/typesol/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/typesol/typesol/actions/workflows/ci.yml/badge.svg?branch=main"></a>
9
9
  <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-3178C6"></a>
10
- <a href="CHANGELOG.md"><img alt="Version 0.10.0 release candidate" src="https://img.shields.io/badge/version-0.10.0--rc-9945FF"></a>
10
+ <a href="https://www.npmjs.com/package/@typesol/cli"><img alt="npm version" src="https://img.shields.io/npm/v/@typesol/cli"></a>
11
11
  <img alt="Target: Solana SBF" src="https://img.shields.io/badge/target-Solana%20SBF-14F195">
12
12
  </p>
13
13
 
@@ -31,9 +31,9 @@ clients read TypeSOL programs unchanged.
31
31
  - Every arithmetic operation is checked.
32
32
  - Account owner, discriminator, signer, writability and aliasing checks are generated from your parameter types.
33
33
  - Constraints follow Anchor's rules and use Anchor's error codes.
34
- - **Small and fast.** On the same programs, TypeSOL uses 5–46% of Anchor's compute units, with binaries about 10×
35
- smaller. It also uses fewer compute units than native Rust and than hand-tuned Pinocchio on every benchmarked
36
- instruction.
34
+ - **Small and fast.** In the LiteSVM benchmarks below, TypeSOL uses 5–32% of Anchor's compute units, with binaries
35
+ about 10× smaller, and fewer compute units than native Rust and hand-tuned Pinocchio on every instruction. On
36
+ mainnet the results differ by instruction; see [the mainnet table](#on-mainnet).
37
37
  - **Reproducible.** The same sources and toolchain produce the same bytes. `typesol verify` reads a deployed program
38
38
  from the cluster and checks it, and the IDL published on chain, against its source.
39
39
 
@@ -175,14 +175,14 @@ counter.ts ─▶ tsc typecheck ─▶ subset check ─▶ C + typesol_rt.h ─
175
175
 
176
176
  1. **Typecheck.** The TypeScript compiler checks your code against [`lib/typesol.d.ts`](lib/typesol.d.ts), which
177
177
  declares every TypeSOL type and built-in.
178
- 2. **Subset check.** TypeSOL rejects anything outside the language (floats, closures, classes, `any`, foreign imports)
178
+ 2. **Subset check.** TypeSOL rejects anything outside the language (floats, classes, `any`, foreign imports)
179
179
  with a `file:line:col` diagnostic. Nothing is half-supported.
180
180
  3. **Lower.** Instruction bodies become C. Account validation, checked arithmetic, Borsh encoding and CPI plumbing
181
181
  come from [`runtime/typesol_rt.h`](runtime/typesol_rt.h).
182
182
  4. **Build.** The Agave platform-tools `clang` and `ld.lld` produce the `.so` (SBPF v0 by default; v1 and v2 with
183
183
  `--sbpf`).
184
184
 
185
- Runtime failures point back to your source: `Error 6000 Unauthorized (counter.ts:21)`, or
185
+ Runtime failures point back to your source: `Error 6000 Unauthorized (counter.ts:25)`, or
186
186
  `TypeSOL: arithmetic overflow (vault.ts:42)`.
187
187
 
188
188
  ## What you can write
@@ -225,27 +225,30 @@ import { build } from "typesol/compiler";
225
225
  const { soPath, idl } = build("programs/counter.ts", "target/counter", programAddress);
226
226
  ```
227
227
 
228
- Subpath exports: `typesol/compiler`, `typesol/workspace`, `typesol/cpi`, `typesol/idl`, `typesol/profile`.
228
+ Subpath exports: `typesol/compiler`, `typesol/workspace`, `typesol/cpi`, `typesol/client`, `typesol/idl`,
229
+ `typesol/profile`, `typesol/testing`, `typesol/ts-plugin`.
229
230
 
230
231
  ## Numbers
231
232
 
232
233
  The same counter, vault and escrow programs, written four ways. All four use the same instruction encoding, account
233
234
  layout and checks. They get identical transactions in LiteSVM and must end in identical account state. The table
234
- shows mean compute units per call (generated by `scripts/readme-bench.ts` from the benchmark run):
235
+ shows mean compute units per call (generated by `scripts/readme-bench.ts` from the benchmark run). The programs,
236
+ scenarios and harness are in [typesol/benchmarks](https://github.com/typesol/benchmarks), which pins the compiler and
237
+ toolchain and records them with every result:
235
238
 
236
239
  <!-- bench:table -->
237
240
  | Instruction | TypeSOL | Pinocchio 0.10 | Native Rust | Anchor 1.0.2 |
238
241
  | --- | ---: | ---: | ---: | ---: |
239
- | counter.initialize | **1,872** | 3,186 | 4,601 | 6,573 |
242
+ | counter.initialize | **1,866** | 3,186 | 4,601 | 6,573 |
240
243
  | counter.increment | **110** | 113 | 857 | 2,323 |
241
- | vault.open | **1,891** | 3,185 | 4,613 | 6,627 |
244
+ | vault.open | **1,885** | 3,185 | 4,613 | 6,627 |
242
245
  | vault.deposit | **1,314** | 1,377 | 2,832 | 4,355 |
243
246
  | vault.withdraw | **315** | 370 | 1,176 | 3,628 |
244
247
  | vault.shut | **161** | 167 | 950 | 2,024 |
245
- | escrow.make | **3,638** | 6,179 | 9,240 | 13,304 |
246
- | escrow.take | **4,035** | 4,051 | 8,500 | 14,365 |
247
- | escrow.refund | **2,716** | 2,769 | 5,695 | 8,449 |
248
- | binary, counter / vault / escrow | 13.2 / 16.5 / 24.0 KB | 19.6 / 22.9 / 29.4 KB | 27.9 / 35.0 / 46.5 KB | 145.2 / 158.9 / 190.7 KB |
248
+ | escrow.make | **3,605** | 6,179 | 9,240 | 13,304 |
249
+ | escrow.take | **4,019** | 4,051 | 8,500 | 14,365 |
250
+ | escrow.refund | **2,696** | 2,769 | 5,695 | 8,449 |
251
+ | binary, counter / vault / escrow | 11.0 / 14.1 / 21.3 KB | 19.6 / 22.9 / 29.4 KB | 27.9 / 35.0 / 46.5 KB | 145.2 / 158.9 / 190.7 KB |
249
252
  <!-- /bench:table -->
250
253
 
251
254
  `initialize`, `open` and `make` include the PDA bump search. TypeSOL hashes PDA candidates with the sha256 and
@@ -306,7 +309,7 @@ Details are in [docs/testing.md](docs/testing.md).
306
309
 
307
310
  ## Status
308
311
 
309
- **TypeSOL is pre-1.0 (0.23).** Releases follow the organization's
312
+ **TypeSOL is pre-1.0.** Releases follow the organization's
310
313
  [versioning policy](https://github.com/typesol/.github/blob/main/VERSIONING.md); [CHANGELOG.md](CHANGELOG.md) lists every
311
314
  change.
312
315
  - The compiler, runtime and tooling have been through internal security reviews and are covered by the tests above.
package/SECURITY.md CHANGED
@@ -4,7 +4,7 @@ TypeSOL generates programs that hold funds. Treat it accordingly.
4
4
 
5
5
  ## Status
6
6
 
7
- - Version 0.10 was reviewed internally (runtime, code generation and tooling). Every release is covered by execution
7
+ - The compiler, runtime and tooling have been through internal security reviews. Every release is covered by execution
8
8
  tests, differential tests against Anchor, and randomized tests. **TypeSOL has not been audited by an independent
9
9
  firm.** Do not put significant value behind programs built with it until an external audit of the compiler and
10
10
  runtime is published, and audit your own programs as you would any Solana program.