@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.
- package/CHANGELOG.md +82 -0
- package/README.md +13 -12
- package/SECURITY.md +1 -1
- package/dist/clientgen.js +190 -41
- package/dist/compiler/analyze.js +195 -25
- package/dist/compiler/emit/base.d.ts +28 -5
- package/dist/compiler/emit/base.js +81 -15
- package/dist/compiler/emit/calls.d.ts +18 -1
- package/dist/compiler/emit/calls.js +159 -7
- package/dist/compiler/emit/cpi.d.ts +23 -0
- package/dist/compiler/emit/cpi.js +274 -5
- package/dist/compiler/emit/expressions.d.ts +9 -1
- package/dist/compiler/emit/expressions.js +25 -12
- package/dist/compiler/emit/function.js +8 -4
- package/dist/compiler/emit/program.js +9 -2
- package/dist/compiler/emit/shared.d.ts +43 -3
- package/dist/compiler/emit/shared.js +43 -0
- package/dist/compiler/emit/statements.d.ts +39 -2
- package/dist/compiler/emit/statements.js +346 -87
- package/dist/compiler/emit/storage.d.ts +6 -2
- package/dist/compiler/emit/storage.js +75 -45
- package/dist/compiler/model.d.ts +26 -1
- package/dist/idlpublish.d.ts +6 -1
- package/dist/idlpublish.js +47 -5
- package/dist/portgen.js +1 -1
- package/dist/svmrpc.d.ts +7 -1
- package/dist/svmrpc.js +133 -19
- package/dist/testing.js +23 -3
- package/docs/cli.md +2 -2
- package/docs/client.md +13 -10
- package/docs/errors.md +9 -3
- package/docs/language.md +21 -20
- package/docs/mainnet.md +1 -1
- package/docs/migrate-from-anchor.md +8 -9
- package/docs/test-your-program.md +6 -2
- package/docs/testing.md +1 -1
- package/docs/troubleshooting.md +3 -2
- package/lib/typesol.d.ts +127 -20
- package/package.json +1 -1
- 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="
|
|
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.**
|
|
35
|
-
|
|
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,
|
|
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:
|
|
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/
|
|
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,
|
|
240
|
+
| counter.initialize | **1,866** | 3,186 | 4,601 | 6,573 |
|
|
240
241
|
| counter.increment | **110** | 113 | 857 | 2,323 |
|
|
241
|
-
| vault.open | **1,
|
|
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,
|
|
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.
|
|
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.
|
|
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
|
-
-
|
|
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.
|