@warptoad/skinny-fat-imt-js 0.0.2

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 warptoad
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # @warptoad/skinny-fat-imt-js
2
+
3
+ JS library counterpart of the [skinny-fat-imt](https://github.com/warptoad/skinny-fat-imt) contracts, used to sync the onchain tree client side.
4
+
5
+ Reads a contract's [LeanIMT](https://github.com/privacy-scaling-explorations/zk-kit) state over viem — from storage or from events, whichever the contract exposes — and keeps a local mirror in sync.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ pnpm add @warptoad/skinny-fat-imt-js viem
11
+ ```
12
+
13
+ `viem` is a **peer dependency**, so it isn't installed for you. That's deliberate: two copies of viem in one tree produce `PublicClient` types that look identical but don't unify, and you'd get baffling assignability errors passing your client into `Trees`.
14
+
15
+ ESM only, Node >= 22.
16
+
17
+ ## Usage
18
+
19
+ ```ts
20
+ import { Trees } from "@warptoad/skinny-fat-imt-js";
21
+ import { createPublicClient, http } from "viem";
22
+
23
+ const client = createPublicClient({ transport: http(rpcUrl) });
24
+ const trees = new Trees(contractAddress, client);
25
+
26
+ // full node: read the trees straight from contract storage
27
+ const synced = await trees.sync([treeId]);
28
+
29
+ // archive node: replay the contract's events, discovering treeIds as it goes
30
+ const all = await trees.sync([], { fullNodeMode: false, autoDiscovery: true });
31
+ ```
32
+
33
+ `fullNodeMode` (default `true`) reads current storage, so a plain full node is enough — that's what the name means. It's the cheap path, but it only sees the tree as it is now.
34
+
35
+ Turning it off replays events, which needs a provider that still has the logs. Recent history is fine on a full node; anything older than roughly a year wants an archive node, and `autoDiscovery` scans all the way back to the deployment block, so it always does. In exchange you get history: `syncToRoot` to reconstruct an old root, and treeId discovery, neither of which storage reads can do.
36
+
37
+ `syncTreesStorage` / `syncTreesEvent` are the two paths directly if you'd rather not go through `sync`.
38
+
39
+ The event-scanning helpers are a separate entry point, so you can chunk `getLogs` calls against any contract without pulling in the tree machinery:
40
+
41
+ ```ts
42
+ import { queryEventInChunks, queryMultiEventsInChunks, minBigInt } from "@warptoad/skinny-fat-imt-js/event-scanning";
43
+ ```
44
+
45
+ | Entry point | Exports |
46
+ | --- | --- |
47
+ | `@warptoad/skinny-fat-imt-js` | `Trees`, `identifyTree`, `getEventFilter`, `copyTree`, `ERC165_IDS`, the ABIs, `getInterfaceId`, `DEPLOY_BLOCK`, … |
48
+ | `@warptoad/skinny-fat-imt-js/event-scanning` | `queryEventInChunks`, `queryMultiEventsInChunks`, `minBigInt`, `EventLog`, `PostQueryEventFilter` |
49
+
50
+ ## Development
51
+
52
+ ```sh
53
+ pnpm install
54
+ pnpm compile # hardhat compile, then regenerate src/abis.ts
55
+ pnpm test # hardhat test
56
+ pnpm typecheck # tsc over src + test + hardhat.config.ts
57
+ pnpm build # emit dist/ from src/ via tsconfig.build.json
58
+ ```
59
+
60
+ ### About `src/abis.ts`
61
+
62
+ `src/abis.ts` is **generated and committed**. `scripts/genAbis.mjs` copies nine ABIs out of hardhat's `artifacts/` into `as const` tuples.
63
+
64
+ The library deliberately does not import `artifacts/` directly, even though that's the obvious thing to do. `artifacts/` is gitignored, ~13MB, and hardhat's generated `artifacts.d.ts` files end with:
65
+
66
+ ```ts
67
+ declare module "hardhat/types/artifacts" { interface ArtifactMap { … } }
68
+ ```
69
+
70
+ Shipping that would make the published typings require `hardhat` to be resolvable in the consumer's project, and would inject our contract names into *their* `ArtifactMap`. Baking the ABIs in keeps full viem inference with no hardhat dependency at all — `hardhat` stays a devDependency and never enters a consumer's graph.
71
+
72
+ **Whenever the contracts change, run `pnpm compile` and commit the resulting `src/abis.ts` diff.** Nothing regenerates it automatically at publish time — that's on purpose, so `npm publish` can never silently rewrite source.
73
+
74
+ ## Publishing to npm
75
+
76
+ ### One-time setup
77
+
78
+ Log in. The `@warptoad` scope must already exist on npm and your account must be able to publish to it.
79
+
80
+ ```sh
81
+ npm login
82
+ npm whoami # confirm the right account
83
+ ```
84
+
85
+ `publishConfig.access` is already set to `public` in package.json. Without it npm assumes scoped packages are private and rejects the publish on a free account.
86
+
87
+ > The package name is `@warptoad/skinny-fat-imt-js`, all lowercase — npm rejects uppercase in package names, so `skinny-fat-IMT-js` is not a valid name.
88
+
89
+ ### Publishing a version
90
+
91
+ 1. Make sure the ABIs are current and everything passes:
92
+
93
+ ```sh
94
+ pnpm compile # only needed if the contracts changed
95
+ pnpm typecheck
96
+ pnpm test
97
+ ```
98
+
99
+ Commit any `src/abis.ts` diff before continuing.
100
+
101
+ 2. Bump the version. This writes package.json, commits, and tags:
102
+
103
+ ```sh
104
+ npm version patch # or: minor / major
105
+ ```
106
+
107
+ 3. Check what will actually ship before you ship it:
108
+
109
+ ```sh
110
+ npm pack --dry-run
111
+ ```
112
+
113
+ Expect `dist/**`, `src/**`, `README.md`, `LICENSE`, `package.json` — about 50KB. If you see `artifacts/` or a multi-MB tarball, something is wrong with `files` in package.json.
114
+
115
+ 4. Publish. `prepublishOnly` runs `pnpm build` (a clean `rm -rf dist` then `tsc -p tsconfig.build.json`), so `dist/` is always rebuilt from current source:
116
+
117
+ ```sh
118
+ npm publish
119
+ ```
120
+
121
+ 5. Push the commit and tag:
122
+
123
+ ```sh
124
+ git push --follow-tags
125
+ ```
126
+
127
+ ### Publishing a prerelease
128
+
129
+ To try a version out without moving the `latest` tag:
130
+
131
+ ```sh
132
+ npm version prerelease --preid=rc # 0.0.1 -> 0.0.2-rc.0
133
+ npm publish --tag next
134
+ ```
135
+
136
+ Consumers get it with `pnpm add @warptoad/skinny-fat-imt-js@next`; plain `pnpm add @warptoad/skinny-fat-imt-js` still resolves to the last stable release.
137
+
138
+ ### Verifying the published package
139
+
140
+ ```sh
141
+ mkdir /tmp/check && cd /tmp/check && pnpm init
142
+ pnpm add @warptoad/skinny-fat-imt-js viem
143
+ node -e "import('@warptoad/skinny-fat-imt-js').then(m => console.log(Object.keys(m)))"
144
+ ```
145
+
146
+ ### Notes
147
+
148
+ - **You cannot republish a version.** Once `0.0.1` is out, `0.0.1` is taken forever, even if you unpublish. Bump and move on.
149
+ - `npm unpublish` is only allowed within 72 hours, and only if nothing depends on it. Use `npm deprecate` instead for anything older.
150
+ - If publish fails with `402 Payment Required`, `publishConfig.access` got lost — scoped packages need `"access": "public"`.
151
+ - If it fails with `404`, you're either not logged in or not a member of the `@warptoad` scope.