@hisoka-io/anon-rpc-worker 0.3.0 → 0.4.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 +27 -0
- package/README.md +110 -22
- package/dist/anon-rpc-worker.js +1983 -234
- package/dist/anon-rpc-worker.js.keccak256 +1 -1
- package/dist/anon-rpc-worker.provenance.json +17 -6
- package/package.json +2 -2
- package/snapshot/capabilities.json +7 -4
- package/snapshot/nox-snapshot.json +6 -3
- package/snapshot/nox-snapshot.json.keccak256 +1 -1
- package/src/config.ts +69 -0
- package/src/core.ts +43 -4
- package/src/embed-modules.d.ts +16 -0
- package/src/errors.ts +7 -1
- package/src/fetch-map.ts +18 -1
- package/src/tls/channel.ts +183 -0
- package/src/tls/module.ts +98 -0
- package/src/tls/pool.ts +358 -0
- package/src/tls/transport.ts +257 -0
- package/src/tls/tunnel.ts +360 -0
- package/src/worker.ts +12 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@hisoka-io/anon-rpc-worker`.
|
|
4
4
|
|
|
5
|
+
## 0.4.0 (2026-10-10)
|
|
6
|
+
|
|
7
|
+
Built on `@hisoka-io/nox-client` 0.8.0. Every 0.3.0 config stays valid; with the new defaults, https calls go
|
|
8
|
+
through TLS tunnels and need exits on nox rc.9 or later with `[tunnel]` enabled.
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- End-to-end TLS (README "End-to-end TLS"): the worker runs TLS 1.3 and 1.2 itself (rustls with ring in a second
|
|
13
|
+
embedded WebAssembly module, `packages/nox-tls`, compiled at boot) and exits relay TLS records over one TCP
|
|
14
|
+
connection per tunnel. Requests and responses stay end-to-end encrypted between the worker and the RPC provider,
|
|
15
|
+
and the mixnet keeps the sender anonymous; the exit sees the provider's host name, timing and sizes.
|
|
16
|
+
- Config `tls` (`"required"` default, `"preferred"`, `"off"`), `tlsSession` (`"per-call"` default, `"keep-alive"`),
|
|
17
|
+
`tlsSpares`, `tlsSpareTtlMs`, `tlsKeepAliveMs`, `tlsMaxCallsPerSession`, `tlsOpenTimeoutMs`, `tlsCopyAfterMs`,
|
|
18
|
+
`tlsGapMs`, `tlsMaxCopies`.
|
|
19
|
+
- Per-call sessions with handshaken spares per recently used host, opened in the background after the first wallet
|
|
20
|
+
call settled; keep-alive sessions as an opt-in. Resumption and 0-RTT stay off; ALPN is `http/1.1`.
|
|
21
|
+
- HTTP/1.1 in the worker: caller headers keep their order and duplicates; framing, hop-by-hop and `User-Agent`
|
|
22
|
+
headers are set by the encoder alone; CR, LF and NUL are refused; a whole JSON request is padded to a size bucket;
|
|
23
|
+
responses are complete only by HTTP framing or TLS close_notify.
|
|
24
|
+
- Call code `permission-denied` (the tunnel exit refuses the destination). Log events `boot.tls`, `tls.open`,
|
|
25
|
+
`tls.fallback`, `tls.reject`, `tls.exit.skipped`, `tls.retry`.
|
|
26
|
+
- Build: `nox-tls` built with the pinned toolchain and a pinned clang (`DEBIAN_SNAPSHOT`, `CLANG_PACKAGE_VERSION`,
|
|
27
|
+
`CLANG_VERSION` in `scripts/toolchain.env`); provenance records its digest, clang, the webpki-roots version and
|
|
28
|
+
release date, and `extraRoots`. `build.mjs --extra-root` and `build-test-worker.mjs --extra-root` for test beds;
|
|
29
|
+
`build-worker.sh --release` refuses a bundle with extra roots.
|
|
30
|
+
- Release gate: `verify-snapshot.mjs --release` requires an exit whose capability hints carry `tunnel_v1`.
|
|
31
|
+
|
|
5
32
|
## 0.3.0 (2026-10-06)
|
|
6
33
|
|
|
7
34
|
Every 0.2.0 config stays valid. Works against entries on nox 0.4.0-rc.6 and on nodes with claim protocol v2.
|
package/README.md
CHANGED
|
@@ -10,15 +10,16 @@ ready the worker reads the registry through the mixnet itself. Where the nodes a
|
|
|
10
10
|
looked up at run time, so operators change IPs whenever they like and new nodes join without a new bundle. A cold
|
|
11
11
|
boot needs no seed server and no public RPC; the bundle reaches the network only through the harness's KPS dialer.
|
|
12
12
|
|
|
13
|
-
What each party sees: the entry node sees the wallet's IP address and encrypted packets
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
What each party sees: the entry node sees the wallet's IP address and encrypted packets. With end-to-end TLS (the
|
|
14
|
+
default, `tls: "required"`), requests and responses stay end-to-end encrypted between the worker and the RPC
|
|
15
|
+
provider, and the mixnet keeps the sender anonymous: the worker runs TLS itself and the exit relays TLS ciphertext
|
|
16
|
+
over one TCP connection, seeing the provider's host name, timing and sizes (see [End-to-end TLS](#end-to-end-tls)).
|
|
16
17
|
|
|
17
18
|
## Layout
|
|
18
19
|
|
|
19
20
|
| Path | Contents |
|
|
20
21
|
|---|---|
|
|
21
|
-
| `src/` | The worker: `worker.ts` (bundle entry), `core.ts` (boot, readiness, accept loop, deadlines), `config.ts`, `fetch-map.ts` (`fetch` to Nox `HttpRequest`), `jsonrpc.ts`, `errors.ts`, `log.ts`, `storage.ts`, `spec-types.ts` (anon-rpc SPEC 0.3.2 worker types) |
|
|
22
|
+
| `src/` | The worker: `worker.ts` (bundle entry), `core.ts` (boot, readiness, accept loop, deadlines), `config.ts`, `fetch-map.ts` (`fetch` to Nox `HttpRequest`, redirects, gzip), `tls/` (end-to-end TLS: `tunnel.ts` one exit tunnel, `channel.ts` TLS and HTTP/1.1 over it, `pool.ts` sessions, spares and exit choice, `transport.ts` the per-hop transport and error mapping, `module.ts` the TLS module bindings), `jsonrpc.ts`, `errors.ts`, `log.ts`, `storage.ts`, `spec-types.ts` (anon-rpc SPEC 0.3.2 worker types) |
|
|
22
23
|
| `snapshot/` | The pinned registry snapshot, its keccak-256, JSON Schema and reviewed capability hints, and the discovery bootstrap (`nox-bootstrap.json`) |
|
|
23
24
|
| `scripts/` | Snapshot generator and verifier, reproducible WASM and bundle build, hashing, provenance |
|
|
24
25
|
| `specifier/` | Worker specifier contracts (Foundry) and a read-only deploy planner and inspector |
|
|
@@ -51,6 +52,16 @@ optional, and every config valid for 0.1.0 stays valid:
|
|
|
51
52
|
| `bootRetryMaxMs` | integer | 60,000 | 5,000-300,000 |
|
|
52
53
|
| `topologySources` | integer | 2 | 1-4 |
|
|
53
54
|
| `warmup` | boolean | false | one echo through a full route before ready |
|
|
55
|
+
| `tls` | `"required"`, `"preferred"`, `"off"` | `"required"` | end-to-end TLS, see [End-to-end TLS](#end-to-end-tls) |
|
|
56
|
+
| `tlsSession` | `"per-call"`, `"keep-alive"` | `"per-call"` | one TLS session per call, or sessions shared by the calls to one host |
|
|
57
|
+
| `tlsSpares` | integer | 1 | 0-4 handshaken spare sessions per recently used host (per-call mode) |
|
|
58
|
+
| `tlsSpareTtlMs` | integer | 20,000 | 1,000-50,000; an unused spare is closed after this long |
|
|
59
|
+
| `tlsKeepAliveMs` | integer | 30,000 | 1,000-50,000; how long a keep-alive session serves calls after it opened |
|
|
60
|
+
| `tlsMaxCallsPerSession` | integer | 100 | 1-1,000 calls per keep-alive session |
|
|
61
|
+
| `tlsOpenTimeoutMs` | integer | 5,000 | 1,000-30,000; an exit that does not answer a tunnel open in this long is skipped for 10 minutes |
|
|
62
|
+
| `tlsCopyAfterMs` | integer | 2,500 | 500-30,000; another copy of the current tunnel exchange when nothing arrived for this long (raised to the observed p95) |
|
|
63
|
+
| `tlsGapMs` | integer | 800 | 100-10,000; another copy when a gap in the reply stream stays open this long |
|
|
64
|
+
| `tlsMaxCopies` | integer | 3 | 1-5 copies per exchange for silence or a gap |
|
|
54
65
|
|
|
55
66
|
An unknown key, a wrong type or an out-of-range value fails the boot with `bad-config`, naming the field.
|
|
56
67
|
|
|
@@ -64,6 +75,70 @@ Examples:
|
|
|
64
75
|
{ gateways: ["100.56.0.72:15005:uEiBVDwIs40bsslDkM-BYb2AOHw3PHe70_bj5U_09r7vdIQ"] }
|
|
65
76
|
```
|
|
66
77
|
|
|
78
|
+
## End-to-end TLS
|
|
79
|
+
|
|
80
|
+
The worker carries a TLS client (rustls with ring, compiled to WebAssembly, `packages/nox-tls`) and runs TLS with
|
|
81
|
+
the RPC provider itself. A Nox exit that advertises `tunnel_v1` holds one TCP connection to the provider per tunnel
|
|
82
|
+
and relays TLS records both ways (`ServiceRequest::TunnelV1`, nox `docs/tunnel.md`). Requests and responses stay
|
|
83
|
+
end-to-end encrypted between the worker and the provider, and the mixnet keeps the sender anonymous; the exit relays
|
|
84
|
+
ciphertext.
|
|
85
|
+
|
|
86
|
+
What the exit learns: the provider's host name (from SNI, its own DNS lookup and the IP) and port 443; when a tunnel
|
|
87
|
+
opens and closes; the number, size and timing of TLS records in both directions (a whole JSON request is padded to
|
|
88
|
+
512 B, 1 KiB, 4 KiB, 16 KiB, then 16 KiB steps, so calls of similar size share one record size; response sizes stay
|
|
89
|
+
visible, and larger buckets are a later milestone); the TLS client fingerprint, shared by every worker of one
|
|
90
|
+
version; in keep-alive mode, which calls share a session. The URL path and query (API keys included), headers,
|
|
91
|
+
JSON-RPC methods and parameters, signed transactions, response content and the sender stay hidden from it, and the
|
|
92
|
+
worker detects any change or truncation of a response.
|
|
93
|
+
|
|
94
|
+
`tls`:
|
|
95
|
+
|
|
96
|
+
| `tls` | https on port 443, host by name | http, another port, or an IP-literal host | no known exit advertises `tunnel_v1` |
|
|
97
|
+
|---|---|---|---|
|
|
98
|
+
| `"required"` (default) | tunnel | rejects `unsupported` | rejects `network-error` |
|
|
99
|
+
| `"preferred"` | tunnel | exit `HttpRequest` (logged `tls.fallback`) | exit `HttpRequest` (logged `tls.fallback`) |
|
|
100
|
+
| `"off"` | exit `HttpRequest` | exit `HttpRequest` | exit `HttpRequest` |
|
|
101
|
+
|
|
102
|
+
The transport is chosen before any byte of a call leaves the worker, from the URL and the capability data, and a
|
|
103
|
+
call that started on a tunnel never continues on `HttpRequest`, redirects included. The capabilities of pinned
|
|
104
|
+
members are the hints in the bundle's snapshot (`snapshot/capabilities.json`), so tunnel exits change, and an exit
|
|
105
|
+
stops counting as one, only with a new bundle; with discovery, other members' capabilities come from the seed's
|
|
106
|
+
liveness data. `"preferred"` uses plaintext whenever no known exit advertises `tunnel_v1`; `"required"` keeps every
|
|
107
|
+
call end-to-end encrypted. An exit that answers `Disabled`, or no tunnel open within `tlsOpenTimeoutMs`, is skipped
|
|
108
|
+
for 10 minutes and the open moves to another tunnel exit; skipped exits still count as tunnel exits, so with every one
|
|
109
|
+
skipped a call fails with `network-error` under both settings.
|
|
110
|
+
|
|
111
|
+
Session modes:
|
|
112
|
+
|
|
113
|
+
- `"per-call"` (default): every call has its own TLS session and `Connection: close`; no resumption, no 0-RTT, a
|
|
114
|
+
fresh key share each time. `tlsSpares` keeps handshaken, unused sessions for hosts the wallet called, opened in
|
|
115
|
+
the background (only after the first wallet call settled) on a random tunnel exit after an exponential delay
|
|
116
|
+
(mean 2 s), each serving one call. Each call travels in its own session; at low traffic the timing of a spare's
|
|
117
|
+
open can still chain sequential calls of one wallet to one host, which weakens as traffic grows.
|
|
118
|
+
- `"keep-alive"`: calls to one host share a session on one exit for `tlsKeepAliveMs`, up to 4 sessions per host.
|
|
119
|
+
The exit links the calls of a session, and the provider sees them on one TLS connection.
|
|
120
|
+
|
|
121
|
+
Latency: a call on a ready session (a spare, or a warm keep-alive session) costs what the exit `HttpRequest` path
|
|
122
|
+
costs. The first call to a host, and calls beyond the ready spares, add one mixnet round trip for the handshake.
|
|
123
|
+
|
|
124
|
+
Certificates are checked against the Mozilla root store compiled into the bundle (webpki-roots; the version and its
|
|
125
|
+
release date are in the provenance, refreshed with every worker release), with the host name and the device clock;
|
|
126
|
+
a wrong clock fails with a message that names it. Each worker release ships its root store, so wallets keep their
|
|
127
|
+
roots current by moving to new worker releases. Resends of a tunnel exchange go to the same exit through another
|
|
128
|
+
entry and mix and carry identical bytes, which the exit writes once; after a lost tunnel only reads that may be resent
|
|
129
|
+
run again on a new tunnel.
|
|
130
|
+
|
|
131
|
+
`tls` governs the wallet's calls. The chain check's registry reads (discovery) use the exit `HttpRequest` path: public
|
|
132
|
+
chain data, accepted only when a quorum of exit and provider pairs agrees byte for byte.
|
|
133
|
+
|
|
134
|
+
Next milestones: registry reads through tunnels as well, Encrypted Client Hello for providers that publish it, and
|
|
135
|
+
a hybrid post-quantum key exchange (X25519MLKEM768).
|
|
136
|
+
|
|
137
|
+
Errors: `permission-denied` (the exit refuses the destination), `network-error` (no tunnel exit, a certificate
|
|
138
|
+
failure, the exit cannot reach the provider), `protocol-error` (TLS or HTTP checks failed, a truncated response),
|
|
139
|
+
`too-large`, `timeout`. Log events: `boot.tls`, `tls.open` (debug: handshake time and CPU), `tls.fallback{reason}`,
|
|
140
|
+
`tls.reject{code}`, `tls.exit.skipped`, `tls.retry`; none carries bytes or a host name.
|
|
141
|
+
|
|
67
142
|
## Discovery (identity from chain, location at run time)
|
|
68
143
|
|
|
69
144
|
The bundle pins `snapshot/nox-bootstrap.json` (`nox-anon-rpc-bootstrap/1`) next to the snapshot, both covered by
|
|
@@ -125,19 +200,25 @@ were read at, and when each member outside the snapshot was first seen. At most
|
|
|
125
200
|
days. A cache that fails any check (another registry, too many records, one malformed record) is ignored whole, and
|
|
126
201
|
a learned address is used only after the node's `/metadata.json` names the same member.
|
|
127
202
|
|
|
128
|
-
## Release 0.
|
|
203
|
+
## Release 0.3.0
|
|
129
204
|
|
|
130
205
|
| | |
|
|
131
206
|
|---|---|
|
|
132
|
-
| `workerHash` (keccak-256 of `dist/anon-rpc-worker.js`) | `
|
|
133
|
-
| Size |
|
|
134
|
-
|
|
|
207
|
+
| `workerHash` (keccak-256 of `dist/anon-rpc-worker.js`) | `0x24604525d220bcc7e39f2dbc22966a814600a63ada51baafad5dd0bcc1d28549` |
|
|
208
|
+
| Size | 961,799 bytes; 279,515 bytes with `gzip -9 -n` |
|
|
209
|
+
| sha256 | `0458b19258dffcfb9ce23d584096f3df06532080390d34ee71b201b6b78dbbac` |
|
|
210
|
+
| Specifier | Ethereum Sepolia `0x29B51ca9Ad80E9c0B0D111C8748E6a7908b82eDB` (`ImmutableWorkerSpecifier`, resolvers in [specifier/README.md](./specifier/README.md#deployments)) |
|
|
135
211
|
| Snapshot | NoxRegistry at Arbitrum Sepolia block 316,207,920, keccak-256 `0xa351960e…94fbb2` |
|
|
136
212
|
| nox-wasm module | 188,708 bytes, sha256 `5171416972ea4499fd4b4ea8bcadf002f4c10f10ed42cafb0d5a426121da9c4f` |
|
|
137
|
-
| Built from | `nox-sdk` commit `
|
|
213
|
+
| Built from | `nox-sdk` commit `6bddd851c5b1f4e5508f4718e2ea9b4db626b17f`, rustc 1.95.0, wasm-pack 0.13.1, wasm-bindgen 0.2.114, binaryen 117, esbuild 0.27.3 |
|
|
214
|
+
|
|
215
|
+
The npm package carries the bundle and provenance file of the first pinned container build.
|
|
216
|
+
|
|
217
|
+
Release 0.2.0: `workerHash` `0x0a58f9915f686950072a4786249d396ecbf2194a39ac835effe8ea1a7c76f324` (924,847 bytes, commit
|
|
218
|
+
`ef019a7`), specifier `0x29b4a6A8Cc11769531854d87f9F33EC63Efe8fe6`.
|
|
138
219
|
|
|
139
|
-
Two builds in fresh containers of the pinned images (at two different paths)
|
|
140
|
-
|
|
220
|
+
Two builds in fresh containers of the pinned images (at two different paths) give these exact bytes
|
|
221
|
+
(`scripts/verify-reproducible.sh --ref 6bddd85`). Run it from the repository root as
|
|
141
222
|
`packages/anon-rpc-worker/scripts/verify-reproducible.sh` (or `pnpm verify:reproducible` inside the package); host builds (`--native`,
|
|
142
223
|
`--local`) use rustc 1.95.0, so set `RUSTUP_TOOLCHAIN=1.95.0` when the host default differs.
|
|
143
224
|
|
|
@@ -145,15 +226,16 @@ bytes (`scripts/verify-reproducible.sh --native`). Run it from the repository ro
|
|
|
145
226
|
|
|
146
227
|
- `dist/anon-rpc-worker.js`: a single IIFE built by esbuild (target es2022, not minified, so it can be read
|
|
147
228
|
and audited). Every module is inlined: the worker source, the `@hisoka-io/nox-client` sources, the
|
|
148
|
-
`nox-wasm` WebAssembly
|
|
149
|
-
byte for byte as one string.
|
|
229
|
+
`nox-wasm` and `nox-tls` WebAssembly modules (base64), the pinned registry snapshot and the discovery bootstrap,
|
|
230
|
+
each embedded byte for byte as one string. The TLS module is compiled at boot, off the first call's path.
|
|
150
231
|
The bundle has no imports and never loads code or WebAssembly by URL. The SDK's ambient `fetch` and
|
|
151
232
|
`WebSocket` defaults are replaced at build time by a stand-in that fails closed, and the build checks the
|
|
152
233
|
output for any other network API.
|
|
153
234
|
- `dist/anon-rpc-worker.js.keccak256`: the Ethereum keccak-256 of those exact bytes, the value a worker
|
|
154
235
|
specifier pins as `workerHash()`.
|
|
155
236
|
- `dist/anon-rpc-worker.provenance.json`: source commit, toolchain versions, input digests (snapshot, bootstrap,
|
|
156
|
-
WASM, lockfile) and
|
|
237
|
+
both WASM modules, lockfile), the compiled-in root store (webpki-roots version and release date, and
|
|
238
|
+
`extraRoots`, 0 in every release) and output digests.
|
|
157
239
|
|
|
158
240
|
## Pinned registry snapshot
|
|
159
241
|
|
|
@@ -172,13 +254,16 @@ The committed release snapshot is of block 316207920 (finalized, read and re-ver
|
|
|
172
254
|
providers of different organisations). It carries the KPS addresses nox-1, nox-2 and nox-8 publish, so the worker
|
|
173
255
|
finds its entries from the snapshot alone, and the default anchors and the chain check add any later moves.
|
|
174
256
|
The release gate names the seven mix and exit nodes, which serve the mixnet without a KPS listener, with
|
|
175
|
-
`--allow-missing-kps
|
|
257
|
+
`--allow-missing-kps`, and requires an exit whose capability hints carry `tunnel_v1`: the hints in
|
|
258
|
+
`snapshot/capabilities.json` come from the seed topology of 2026-10-10 (fleet on nox 0.4.0-rc.9), where the three
|
|
259
|
+
exits advertise `tunnel_v1`. The registry state at that block is the same as in 0.3.0 (fingerprint
|
|
260
|
+
`0x14ca3b69…7c75`); with the new hints the snapshot's keccak-256 is `0x1090f071…014681`.
|
|
176
261
|
|
|
177
262
|
```bash
|
|
178
263
|
pnpm --filter @hisoka-io/nox-client build
|
|
179
264
|
node scripts/make-snapshot.mjs --rpc <arbitrum-sepolia-rpc> --rpc <second-rpc> [--block <n>]
|
|
180
265
|
node scripts/verify-snapshot.mjs --offline # schema, hashes, SDK-derived fields
|
|
181
|
-
node scripts/verify-snapshot.mjs --rpc <rpc> --rpc <rpc> --release # chain re-read
|
|
266
|
+
node scripts/verify-snapshot.mjs --rpc <rpc> --rpc <rpc> --release # chain re-read, KPS addresses, a tunnel exit
|
|
182
267
|
```
|
|
183
268
|
|
|
184
269
|
## Building and checking the hash
|
|
@@ -190,10 +275,11 @@ node packages/anon-rpc-worker/scripts/hash.mjs packages/anon-rpc-worker/dist/ano
|
|
|
190
275
|
```
|
|
191
276
|
|
|
192
277
|
`scripts/toolchain.env` pins every tool that shapes the bytes: the Node and Rust container images by digest,
|
|
193
|
-
rustc, wasm-pack, wasm-bindgen and binaryen (with sha256 digests of their release archives)
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
278
|
+
rustc, wasm-pack, wasm-bindgen and binaryen (with sha256 digests of their release archives), and clang with llvm-ar
|
|
279
|
+
for ring's C sources in `nox-tls` (Debian bookworm packages at a snapshot.debian.org timestamp, the same on x86_64
|
|
280
|
+
and aarch64); pnpm comes from the repository's `packageManager` field and esbuild from the lockfile.
|
|
281
|
+
`scripts/build-wasm.sh` follows the tor-js recipe: path remapping, a `RUSTC_WRAPPER` that makes cargo's metadata
|
|
282
|
+
host-independent, `--locked`, and a pinned `wasm-opt` on `PATH`.
|
|
197
283
|
|
|
198
284
|
`scripts/verify-reproducible.sh` builds a commit twice from clean `git archive` exports in fresh containers
|
|
199
285
|
of the pinned images, at two different paths, and compares the WASM, bundle and provenance digests
|
|
@@ -202,12 +288,14 @@ container builds and requires all three to match; `--local --bwrap` runs the two
|
|
|
202
288
|
namespaces at the container paths, for hosts without a container runtime.
|
|
203
289
|
|
|
204
290
|
For a test bed, `node scripts/build.mjs --snapshot <file>` embeds another canonical snapshot (for example a
|
|
205
|
-
local mesh); the provenance records which snapshot a
|
|
291
|
+
local mesh) and `--extra-root <ca.der>` a test CA next to the Mozilla roots; the provenance records which snapshot a
|
|
292
|
+
bundle carries and how many extra roots. The release build (`build-worker.sh --release`) refuses a bundle with an
|
|
293
|
+
extra root (`provenance.mjs --release`).
|
|
206
294
|
|
|
207
295
|
## Tests
|
|
208
296
|
|
|
209
297
|
```bash
|
|
210
|
-
pnpm --filter @hisoka-io/anon-rpc-worker test # worker, SDK integration over an in-memory KPS network, build
|
|
298
|
+
pnpm --filter @hisoka-io/anon-rpc-worker test # worker, SDK integration over an in-memory KPS network, build, e2e bed unit tests
|
|
211
299
|
pnpm --filter @hisoka-io/anon-rpc-specifier test # Foundry and harness-path tests (forge, anvil)
|
|
212
300
|
```
|
|
213
301
|
|