@typesol/cli 0.22.0 → 0.24.0

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 +82 -0
  2. package/README.md +13 -12
  3. package/SECURITY.md +1 -1
  4. package/dist/clientgen.js +190 -41
  5. package/dist/compiler/analyze.js +195 -25
  6. package/dist/compiler/emit/base.d.ts +28 -5
  7. package/dist/compiler/emit/base.js +81 -15
  8. package/dist/compiler/emit/calls.d.ts +18 -1
  9. package/dist/compiler/emit/calls.js +159 -7
  10. package/dist/compiler/emit/cpi.d.ts +23 -0
  11. package/dist/compiler/emit/cpi.js +274 -5
  12. package/dist/compiler/emit/expressions.d.ts +9 -1
  13. package/dist/compiler/emit/expressions.js +25 -12
  14. package/dist/compiler/emit/function.js +8 -4
  15. package/dist/compiler/emit/program.js +9 -2
  16. package/dist/compiler/emit/shared.d.ts +43 -3
  17. package/dist/compiler/emit/shared.js +43 -0
  18. package/dist/compiler/emit/statements.d.ts +39 -2
  19. package/dist/compiler/emit/statements.js +346 -87
  20. package/dist/compiler/emit/storage.d.ts +6 -2
  21. package/dist/compiler/emit/storage.js +75 -45
  22. package/dist/compiler/model.d.ts +26 -1
  23. package/dist/idlpublish.d.ts +6 -1
  24. package/dist/idlpublish.js +47 -5
  25. package/dist/portgen.js +1 -1
  26. package/dist/svmrpc.d.ts +7 -1
  27. package/dist/svmrpc.js +133 -19
  28. package/dist/testing.js +23 -3
  29. package/docs/cli.md +2 -2
  30. package/docs/client.md +13 -10
  31. package/docs/errors.md +9 -3
  32. package/docs/language.md +21 -20
  33. package/docs/mainnet.md +1 -1
  34. package/docs/migrate-from-anchor.md +8 -9
  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 +127 -20
  39. package/package.json +1 -1
  40. package/runtime/typesol_rt.h +73 -18
package/CHANGELOG.md CHANGED
@@ -5,6 +5,88 @@ until 1.0, a minor version may change the language, the IDL layout or error code
5
5
 
6
6
  ## Unreleased
7
7
 
8
+ ## 0.24.0 — 2026-10-28
9
+
10
+ Functions as values, closures for any helper, stored `map` to structs and text, Metaplex Core external plugins, and
11
+ the fixes and identical-result compute-unit savings from a full code review: expanded helpers see only their own
12
+ scope, generated clients read only their program's events, and IDLs from the chain are read with limits. Not externally
13
+ audited (see SECURITY.md).
14
+
15
+ ### Added
16
+ - Functions as values: `const h = g`, and functions that return functions (`function adder(n: u64): (x: u64) => u64
17
+ { return (x) => x + n; }`), which make a closure where they are called (`const add5 = adder(5n)`, `adder(5n)(x)`).
18
+ - Closures given to helpers with type parameters or accounts: the helper is expanded where it is called, its type
19
+ parameters bound from the call and its accounts the caller's.
20
+ - A stored `map` to structs or text: `const ps: FixedVec<Pair, 8> = xs.map((o) => ({ qty: o.qty, doubled: o.qty * 2n }))`,
21
+ `const names: FixedVec<FixedString<8>, 4> = xs.map(…)`.
22
+ - A struct argument holding a FixedVec, when the struct is only an argument: read as Anchor sends it (the FixedVec a
23
+ Borsh Vec), as a `@layout borsh` struct is.
24
+ - Metaplex Core external plugin adapters: `addExternalPlugin`, `removeExternalPlugin`, `writeExternalPluginData` and
25
+ their Collection forms, for AppData, Oracle and LifecycleHook (and the Linked forms), checked against the Core program
26
+ (Core itself answers lifecycle hooks with NotAvailable for now).
27
+
28
+ ### Changed
29
+ - Fewer compute units, same results: the PDA bump search builds its seed list once, a growing account reads the rent
30
+ sysvar once, integers become text two digits at a time, a lone `${n}` template is not copied again, and
31
+ `list = fixedVec([])` clears the list in place. For example escrow `make` 3638 → 3605, `take_offer` 7117 → 7058,
32
+ `transfer_tokens` 8467 → 8367 CU.
33
+ - `eventsOf` takes the transaction with its account keys (`transaction.message.accountKeys`, as getTransaction returns
34
+ it); without them it reads log events only. `errorCode` / `isError` also read the RPC's JSON error
35
+ (`{ InstructionError: [0, { Custom: 6000 }] }`).
36
+ - `svmConnection`: `accountNotifications` yields after each later transaction that names the account (no snapshot of
37
+ it as it is), `logsNotifications` honors `{ mentions }` and includes failed transactions (with `err`), simulation
38
+ errors are in the RPC's JSON shape, and `getTransaction` returns the account keys and each inner instruction's
39
+ program index.
40
+ - Compiler messages about accounts with a growable Vec say "has a growable Vec" instead of "ends in a Vec", and the
41
+ field-type list no longer says `Vec<T> (last)`, since a Vec can be any field (0.23.0).
42
+
43
+ ### Fixed
44
+ - A helper expanded where it is called (given a closure), and a function a helper made, read a module constant as
45
+ the instruction argument of the same name; they now see only their parameters and the module.
46
+ - A struct parameter of a closure or expanded helper could be used after a push, pop or clear moved the Vec it points
47
+ into (a stale pointer); that is refused like any other reference across the move.
48
+ - A closure parameter named like an account read the account; it is refused.
49
+ - A helper from another file, expanded here or typed from an arrow passed to it, resolved its types with this file's
50
+ imports (an aliased or unimported type failed to compile, or an annotation was dropped); its own file's imports are
51
+ used, and `applyT<u64>((v) => …)` takes the type given at the call.
52
+ - A struct with a FixedVec held in a data enum variant was read as Borsh when also an argument; that conflict is refused.
53
+ - Generated clients read only this program's events: `parseEvents` follows the invoke stack and reads a `Program data:`
54
+ line only while the program is the innermost one running, and `eventsOf` reads only `emitCpi` inner instructions that
55
+ call the program. Another program can no longer forge them.
56
+ - `watchEvents` skips failed transactions.
57
+ - `typesol client` refuses malformed generic arguments, array lengths that are not whole numbers and `repr` alignments
58
+ that are not powers of two, and caps generic instantiation (256 types, 16 levels): a ClientIdlError instead of a crash
59
+ or a hang. Sizing deeply nested structs no longer takes exponential time.
60
+ - Accounts named like `Object.prototype` properties (`constructor`, `toString`, …) are read as given, not inherited.
61
+ - `resolve.<ix>` derives a has_one source that is a PDA (a `config` PDA) before reading it, and names the account to
62
+ pass when a source is missing.
63
+ - Notes and errors escape control characters from the IDL.
64
+ - Reading an IDL from the chain caps inflation at 16 MiB, checks Anchor's IdlAccount discriminator, and refuses a
65
+ Program Metadata IDL that links to a URL or another account instead of following it.
66
+ - `typesol/testing`'s `returned()` decodes string, bytes, f32 and f64 return values, and throws for types it cannot
67
+ decode instead of misreading them.
68
+
69
+ ## 0.23.0 — 2026-10-28
70
+
71
+ Language limits lifted: `map` and `filter`, any number of growable Vecs per account, closures and arrow functions as
72
+ helper arguments, FixedVec arguments and list fields in events. Existing programs compile to the same bytes. Not
73
+ externally audited (see SECURITY.md).
74
+
75
+ ### Added
76
+ - `map` and `filter` on Vecs, FixedArrays, FixedVecs and Vec arguments. A chain used right away
77
+ (`xs.filter(f).map(g).reduce(h, 0n)`, `.length`, `for … of`, any list method) is one loop that builds no list;
78
+ callbacks after a filter get the index among the elements it let through, as in JS. Stored (`const ys = xs.map(f)`),
79
+ it is a FixedVec on the stack as big as the list it starts from, or as annotated (`const ys: FixedVec<u64, 16> = …`,
80
+ needed for a `Vec`); a list one element too small aborts with 5104.
81
+ - Arrow functions written as helper arguments (`applyTwice((x) => x * 3n, v)`), typed from the helper's parameter when
82
+ left unannotated. Given a closure (one that reads the caller's variables), the helper is expanded where it is called,
83
+ so the closure runs where it can.
84
+ - Any number of growable `Vec<T>` fields in an account, declared anywhere. They are stored after the fixed-size fields,
85
+ in the order declared (every other field keeps a fixed offset; the IDL lists the stored order), and a push, pop or
86
+ clear moves the Vecs after it. An account with one Vec is laid out as before.
87
+ - `FixedVec<T, N>` arguments (a Borsh Vec of at most N elements; more fail with 102), and `FixedVec` and `Vec` fields
88
+ in events.
89
+
8
90
  ## 0.22.0 — 2026-10-28
9
91
 
10
92
  Generated clients fill in the accounts Anchor's client still asked you to pass (signers from a default signer, PDAs
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,7 +225,8 @@ 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
 
@@ -236,16 +237,16 @@ shows mean compute units per call (generated by `scripts/readme-bench.ts` from t
236
237
  <!-- bench:table -->
237
238
  | Instruction | TypeSOL | Pinocchio 0.10 | Native Rust | Anchor 1.0.2 |
238
239
  | --- | ---: | ---: | ---: | ---: |
239
- | counter.initialize | **1,872** | 3,186 | 4,601 | 6,573 |
240
+ | counter.initialize | **1,866** | 3,186 | 4,601 | 6,573 |
240
241
  | counter.increment | **110** | 113 | 857 | 2,323 |
241
- | vault.open | **1,891** | 3,185 | 4,613 | 6,627 |
242
+ | vault.open | **1,885** | 3,185 | 4,613 | 6,627 |
242
243
  | vault.deposit | **1,314** | 1,377 | 2,832 | 4,355 |
243
244
  | vault.withdraw | **315** | 370 | 1,176 | 3,628 |
244
245
  | vault.shut | **161** | 167 | 950 | 2,024 |
245
- | escrow.make | **3,638** | 6,179 | 9,240 | 13,304 |
246
+ | escrow.make | **3,605** | 6,179 | 9,240 | 13,304 |
246
247
  | escrow.take | **4,035** | 4,051 | 8,500 | 14,365 |
247
248
  | 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 |
249
+ | binary, counter / vault / escrow | 13.1 / 16.5 / 23.9 KB | 19.6 / 22.9 / 29.4 KB | 27.9 / 35.0 / 46.5 KB | 145.2 / 158.9 / 190.7 KB |
249
250
  <!-- /bench:table -->
250
251
 
251
252
  `initialize`, `open` and `make` include the PDA bump search. TypeSOL hashes PDA candidates with the sha256 and
@@ -306,7 +307,7 @@ Details are in [docs/testing.md](docs/testing.md).
306
307
 
307
308
  ## Status
308
309
 
309
- **TypeSOL is pre-1.0 (0.22).** Releases follow the organization's
310
+ **TypeSOL is pre-1.0 (0.24).** Releases follow the organization's
310
311
  [versioning policy](https://github.com/typesol/.github/blob/main/VERSIONING.md); [CHANGELOG.md](CHANGELOG.md) lists every
311
312
  change.
312
313
  - 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.