-
Notifications
You must be signed in to change notification settings - Fork 0
Scaffold the EFS SDK monorepo #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
JamesCarnley
wants to merge
47
commits into
main
Choose a base branch
from
chore/scaffold
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
47 commits
Select commit
Hold shift + click to select a range
a5a03e2
chore: scaffold the EFS SDK monorepo
JamesCarnley 7f0f5b7
docs(adr): note the lightweight MADR-style lineage
JamesCarnley c8e5a19
chore: adopt @efs npm scope; trim ADR system per validation
JamesCarnley 885a0ad
docs: add docs/specs/ — plain-language "how it works" layer
JamesCarnley 7994df5
ci: fix scope rename in CI; add OIDC release workflow (ADR-0004)
JamesCarnley 117b1b4
ci: fix Solidity forge-std install and changeset gate
JamesCarnley daa503a
ci: harden workflows per review
JamesCarnley eadb898
fix(solidity): forge fmt clean + drop stub warnings
JamesCarnley bd6f0a3
ci/sdk: address Codex review — release build scope + stale version
JamesCarnley ba5c8b1
adr: ADR-0005 — per-chain deployments registry; SDK is a client not a…
JamesCarnley d1e88d3
fix: address SDK-relevant findings from holistic review (cheap defects)
JamesCarnley cf3025e
plan: beta-slice implementation spec (review-hardened)
JamesCarnley 85c7d3d
ci: unblock Changesets version PR + make solidity tests self-bootstra…
JamesCarnley 2c88bc2
feat(content): contentHash = bare SHA-256 (ADR-0006) + real hashing m…
JamesCarnley 39653f6
style: biome-format verifyContent signature (CI lint fix)
JamesCarnley e71548b
ci: disable auto-publish until launch (Codex P1)
JamesCarnley 5e92a8d
feat(sdk): namespaced client (F) + EAS layer, lenses, deployments, er…
JamesCarnley c70a66f
fix(sdk): async fs stubs + honest integrity-check docs (review)
JamesCarnley 145e590
docs: fix package README quickstart to namespaced API (Codex P2)
JamesCarnley 9e5467f
fix(eas): forward resolver value as msg.value in attest builders (Cod…
JamesCarnley 4017c17
refactor(sdk): foundation hardening batch 1 — types, write-gating, seams
JamesCarnley 82d5b03
docs: quickstart uses the actual ReadOptions key `lens` (Codex P2)
JamesCarnley f9733fc
chore(sdk): foundation hardening batch 2 — exports, attw/publint, ADRs
JamesCarnley cdd250f
docs: standards-foundation spec (7-domain EIP/ERC/CAIP research pass)
JamesCarnley 1ca8d9e
fix(solidity): exports map exposes the documented src/*.sol import (C…
JamesCarnley 3443be8
feat(sdk): EIP-1193 provider boundary (standard at the edge, viem ins…
JamesCarnley 69239b1
fix(solidity): _efsPinFile locks the emit happy-path shape (Codex P2)
JamesCarnley 3e1233e
docs: future-proofing doctrine (9-domain research pass 2)
JamesCarnley 97230fe
docs: recover dropped pass-2 findings (completeness sweep + sim seam)
JamesCarnley d4e413c
review: apply verified API + standards review (40 findings)
JamesCarnley 449c286
feat: build freeze-independent foundation (fetch engine, classifier, …
JamesCarnley ae1d1c0
fix(ci): scope noNonNullAssertion off for tests, keep src strict
JamesCarnley 78a6a6c
fix(mirror): block canonical hex IPv4-mapped IPv6 in SSRF guard (P1)
JamesCarnley a0c0d83
fix(mirror): re-check redirect targets in SSRF guard (P1)
JamesCarnley 59253c1
fix(mirror): trailing-dot host bypass (P1) + data: URI size cap (P2)
JamesCarnley 2fa8bf9
harden(mirror): IPv6 transition SSRF, decompression bomb, data: decod…
JamesCarnley db195ad
harden(mirror): reject gateway path traversal in ipfs/arweave subpath…
JamesCarnley 335762d
harden(mirror): require / boundary in gateway namespace check (P2)
JamesCarnley 0e6a859
feat: build on merged on-chain tag-exclusion filter + folder Overview…
JamesCarnley 310ef5f
chore(size): raise budget to 10 kB for the view ABI + filter/Overview…
JamesCarnley 8481394
fix(mirror,errors): UTF-8 data: cap + walk cause chain for error code…
JamesCarnley f4f9bb5
fix(mirror): exclude base64 padding/whitespace from data: cap prechec…
JamesCarnley fa56b11
fix(mirror,eas): byte-wise data: octet decode + EAS error fragments (…
JamesCarnley be24b0c
fix(mirror): percent-decode base64 data: bodies before decoding (P2)
JamesCarnley 28a0bd8
fix(mirror): bound-aware data: octet decode — enforce cap DURING deco…
JamesCarnley 1f0541f
fix(mirror): size-check percent-encoded base64 before materializing (P2)
JamesCarnley 47dd93b
fix(mirror): trim media type before ;base64 test + surrogate-safe flush
JamesCarnley File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| { | ||
| "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json", | ||
| "changelog": "@changesets/cli/changelog", | ||
| "commit": false, | ||
| "fixed": [], | ||
| "linked": [], | ||
| "access": "public", | ||
| "baseBranch": "main", | ||
| "updateInternalDependencies": "patch", | ||
| "ignore": [] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| --- | ||
| --- | ||
|
|
||
| Initial monorepo scaffold — structure, toolchain, ADRs, and docs. No package release (both packages are unpublished `0.0.0`); this empty changeset satisfies the CI gate for a no-release PR. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
|
|
||
| # CI only reads the repo — never needs write. | ||
| permissions: | ||
| contents: read | ||
|
|
||
| # Cancel superseded runs on the same ref. | ||
| concurrency: | ||
| group: ci-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| jobs: | ||
| ts: | ||
| name: TypeScript (build, typecheck, test, lint) | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: pnpm/action-setup@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
| cache: pnpm | ||
| # --ignore-scripts neutralizes malicious dependency postinstall/preinstall | ||
| # scripts — the dominant supply-chain attack on a wallet-adjacent SDK. | ||
| # It only suppresses *dependency* lifecycle scripts; explicit `pnpm run` | ||
| # pre/post hooks (e.g. the Solidity forge-std bootstrap) still run. | ||
| - run: pnpm install --frozen-lockfile --ignore-scripts | ||
| - run: pnpm --filter @efs/sdk build | ||
| # Guard the dual ESM/CJS `exports` map: attw catches type masquerading / | ||
| # resolution bugs, publint catches malformed package metadata. | ||
| # node16 profile: the package requires Node >=20 and ships an `exports` | ||
| # map, so legacy node10 resolution (which ignores `exports`, breaking | ||
| # subpath entries) is an explicit non-target. | ||
| - run: pnpm --filter @efs/sdk exec attw --pack --profile node16 | ||
| - run: pnpm --filter @efs/sdk exec publint | ||
| - run: pnpm --filter @efs/sdk typecheck | ||
| - run: pnpm --filter @efs/sdk test | ||
| # Bundle-size budget on the @efs/sdk ESM entry (viem external). Fails the | ||
| # build if the gzipped surface grows past the budget in .size-limit.json. | ||
| - run: pnpm --filter @efs/sdk size | ||
| # Dead-code / unused-dependency report. Report-only (|| true) for now — the | ||
| # findings are follow-ups, not a merge gate, while the API surface settles. | ||
| - run: pnpm --filter @efs/sdk knip || true | ||
| - run: pnpm lint | ||
|
|
||
| solidity: | ||
| name: Solidity (build, test, fmt) | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: foundry-rs/foundry-toolchain@v1 | ||
| - uses: pnpm/action-setup@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
| cache: pnpm | ||
| - run: pnpm install --frozen-lockfile --ignore-scripts | ||
| # Use the package scripts so CI and a contributor's `pnpm test` run the same | ||
| # path; the build/test pre-hooks bootstrap forge-std (test-only, not shipped). | ||
| # --ignore-scripts above only suppresses *dependency* install scripts, so | ||
| # these explicit `pnpm run` pre/post hooks still execute. | ||
| - run: pnpm --filter @efs/solidity build | ||
| - run: pnpm --filter @efs/solidity test | ||
| - run: pnpm --filter @efs/solidity fmt:check | ||
|
|
||
| changeset: | ||
| name: Changeset present | ||
| # Skip the gate for Changesets' own "Version Packages" PR, which consumes | ||
| # (deletes) the changeset files — it legitimately has none left. | ||
| if: github.event_name == 'pull_request' && github.head_ref != 'changeset-release/main' | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| fetch-depth: 0 | ||
| - uses: pnpm/action-setup@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 20 | ||
| cache: pnpm | ||
| - run: pnpm install --frozen-lockfile --ignore-scripts | ||
| - run: pnpm changeset status --since=origin/main | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| name: Release | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
|
|
||
| concurrency: release-${{ github.ref }} | ||
|
|
||
| permissions: | ||
| contents: write # create version PR, tags, GitHub releases | ||
| pull-requests: write # open the Changesets "Version Packages" PR | ||
| id-token: write # OIDC — npm Trusted Publishing (no NPM_TOKEN secret) | ||
|
|
||
| jobs: | ||
| release: | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 15 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: pnpm/action-setup@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 # Trusted Publishing needs Node >= 22.14 / npm >= 11.5.1 | ||
| cache: pnpm | ||
| registry-url: https://registry.npmjs.org | ||
| # --ignore-scripts: block dependency install scripts on the publish path too. | ||
| - run: pnpm install --frozen-lockfile --ignore-scripts | ||
| - run: npm install -g npm@11 # pinned major; needs npm >= 11.5.1 for OIDC publishing | ||
| # Only the TS package needs a build artifact to publish; @efs/solidity ships | ||
| # .sol source as-is, so the release path needs no Foundry. (CI compile-checks | ||
| # the Solidity package on every PR before merge.) | ||
| - run: pnpm --filter @efs/sdk build | ||
| # PUBLISHING IS INTENTIONALLY DISABLED UNTIL LAUNCH. The packages are pre-1.0, | ||
| # unpublished 0.0.0, and the @efs npm org isn't created yet — auto-publishing | ||
| # now would push a scaffold. With no `publish:` input, changesets/action only | ||
| # manages the "Version Packages" PR; it never publishes. | ||
| # | ||
| # TO ENABLE AT LAUNCH: add `with: { publish: pnpm release }` below, and | ||
| # configure a Trusted Publisher PER PACKAGE on npmjs.com (OIDC, no token): | ||
| # package settings -> Trusted Publisher -> repo "efs-project/sdk", | ||
| # workflow ".github/workflows/release.yml". Repo must stay public. | ||
| - uses: changesets/action@v1 | ||
| env: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Dependencies | ||
| node_modules/ | ||
| .pnpm-store/ | ||
|
|
||
| # TypeScript / build output | ||
| dist/ | ||
| *.tsbuildinfo | ||
|
|
||
| # Turbo | ||
| .turbo/ | ||
|
|
||
| # Foundry (packages/solidity) — build artifacts, never shipped or tracked | ||
| out/ | ||
| cache/ | ||
| broadcast/ | ||
| packages/solidity/out/ | ||
| packages/solidity/cache/ | ||
| packages/solidity/lib/ | ||
|
|
||
| # Env / secrets | ||
| .env | ||
| .env.* | ||
| !.env.example | ||
|
|
||
| # Editor / OS | ||
| .DS_Store | ||
| .idea/ | ||
| .vscode/ | ||
| *.log |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| 20 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| # AGENTS.md | ||
|
|
||
| The **EFS SDK** — the developer-facing SDK for the Ethereum File System (an on-chain filesystem on EAS attestations). This repo ships two packages: a TypeScript SDK and a compile-in Solidity SDK. Pre-1.0, pre-launch — breaking changes are fine for now; good design and future-proofing of the *public surface* is what matters. | ||
|
|
||
| This is the **upgradeable** layer of EFS (vs. the immutable contracts). Ship the simple version, observe, revise. | ||
|
|
||
| ## Read on init | ||
|
|
||
| **If your tool does not auto-load `@`-imported files, read these before starting any task:** | ||
|
|
||
| - **[docs/specs/overview.md](./docs/specs/overview.md)** — plain-language *how the SDK works* (the model). Start here to understand behaviour. | ||
| - **[docs/adr/README.md](./docs/adr/README.md)** — the ADR system and the **boundary rule** (SDK ADR vs. planning-vault design). Required before writing a decision. | ||
| - **[README.md](./README.md)** — what the two packages are and how they're consumed. | ||
|
|
||
| Doc layers (don't duplicate): **specs** = how it works now · **ADRs** = why we chose it · **planning vault** = cross-cutting design. See [docs/specs/README.md](./docs/specs/README.md). | ||
|
|
||
| ## The two packages | ||
|
|
||
| - **`packages/sdk`** → `@efs/sdk` — TypeScript, off-chain reads/writes, viem-native (ADR-0002). | ||
| - **`packages/solidity`** → `@efs/solidity` — a compile-in Solidity library (ADR-0003); your contract stays the attester. | ||
|
|
||
| ## Cross-repo coordination — the planning vault | ||
|
|
||
| The cross-cutting SDK architecture lives in the **planning vault**, not here: `planning/Designs/sdk-architecture.md` (the "what + why"), plus `planning/Designs/sdk-minimal-clicks.md`. This repo's ADRs implement *slices* of that design. | ||
|
|
||
| **Boundary rule (see [docs/adr/README.md](./docs/adr/README.md)):** | ||
| - SDK-only decision (package layout, deps, error model, API shape) → an **SDK ADR** here. | ||
| - A decision that changes EFS *architecture* or touches the **contracts**/**client** repos → a **planning-vault design**, not an SDK ADR. | ||
| - SDK code decisions never go in `planning/Decisions.md` (that's for cross-repo coordination only). | ||
|
|
||
| The sibling repos: protocol contracts (`efs-project/contracts`) and the production client (`efs-project/client`). | ||
|
|
||
| ## Conventions | ||
|
|
||
| - **ADRs:** mirror the contracts repo's format, independent numbering from `0001`, lighter discipline (no freeze ceremony). Supersede-don't-edit accepted ADRs. | ||
| - **Commits:** conventional style (`feat:`, `fix:`, `docs:`, `adr:`, `chore:`). | ||
| - **Quality:** `pnpm build && pnpm test && pnpm typecheck && pnpm lint` before a PR. Every change that touches a published package needs a Changeset (`pnpm changeset`). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| # CLAUDE.md | ||
|
|
||
| This repo uses **AGENTS.md** as the canonical entrypoint for all AI agents. The files below are auto-loaded into context at session start: | ||
|
|
||
| @AGENTS.md | ||
| @docs/adr/README.md |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| # Contributing | ||
|
|
||
| ## Setup | ||
|
|
||
| ```bash | ||
| pnpm install | ||
| ``` | ||
|
|
||
| Requires **pnpm 9+**, **Node 20+**, and **[Foundry](https://book.getfoundry.sh/)** (for `packages/solidity`). | ||
|
|
||
| ## Commands | ||
|
|
||
| ```bash | ||
| pnpm build # build both packages (turbo) | ||
| pnpm test # vitest (sdk) + forge test (solidity) | ||
| pnpm typecheck # tsc --noEmit | ||
| pnpm lint # biome ci | ||
| pnpm format # biome format --write | ||
| ``` | ||
|
|
||
| Per package: `pnpm --filter @efs/sdk test`, `pnpm --filter @efs/solidity build`, etc. | ||
|
|
||
| ## Before you open a PR | ||
|
|
||
| 1. `pnpm build && pnpm test && pnpm typecheck && pnpm lint` are green. | ||
| 2. If you changed a **published package**, add a Changeset: `pnpm changeset` (pick the bump; write a one-line consumer-facing summary). | ||
| 3. If you made a **decision** (a choice with alternatives), write an ADR — see below. | ||
|
|
||
| ## Decisions → ADRs | ||
|
|
||
| Read [`docs/adr/README.md`](./docs/adr/README.md). The short version: | ||
|
|
||
| - A decision **scoped to the SDK** (package layout, deps, error model, public API shape) → a new ADR in `docs/adr/`, numbered from the next free `NNNN`, using `_template.md`. | ||
| - A decision that changes EFS **architecture** or touches the **contracts**/**client** repos → it belongs in the **planning vault** (`planning/Designs/`), not here. | ||
| - Accepted ADRs are immutable — to change one, write a new ADR and mark the old `Superseded by ADR-NNNN`. | ||
|
|
||
| The SDK is the upgradeable layer, so the ADR bar is light: same format as the contracts repo, no freeze ceremony. | ||
|
|
||
| ## Style | ||
|
|
||
| - TypeScript: Biome (`pnpm format`); `strict` tsconfig; typed errors (extend `EfsError`), never raw RPC strings. | ||
| - Solidity: `forge fmt` (solhint planned). | ||
| - Commits: conventional (`feat:`, `fix:`, `docs:`, `adr:`, `chore:`). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # EFS SDK | ||
|
|
||
| The developer SDK for the **Ethereum File System (EFS)** — an on-chain filesystem built on [EAS](https://attest.org) attestations. | ||
|
|
||
| > **Status: scaffold.** Repo structure, toolchain, and public API shapes are in place; implementations land next. How it works: [`docs/specs/overview.md`](./docs/specs/overview.md). Decisions: [`docs/adr/`](./docs/adr). (Cross-cutting design rationale lives in the EFS planning vault, internal.) | ||
|
|
||
| ## Two packages, two audiences | ||
|
|
||
| | Package | npm | For | | ||
| |---|---|---| | ||
| | [`packages/sdk`](./packages/sdk) | `@efs/sdk` | **TypeScript** — apps, scripts, agents reading/writing EFS off-chain. viem-native. | | ||
| | [`packages/solidity`](./packages/solidity) | `@efs/solidity` | **Solidity** — a compile-in library so your *own contract* can read/write EFS. | | ||
|
|
||
| ```bash | ||
| npm i @efs/sdk viem # TypeScript SDK | ||
| npm i @efs/solidity # Solidity library (compile-in) | ||
| ``` | ||
|
|
||
| ## Repo layout | ||
|
|
||
| ``` | ||
| packages/ | ||
| sdk/ TypeScript SDK (tsup, viem, vitest) | ||
| solidity/ Solidity library (Foundry, ships .sol source) | ||
| examples/ runnable consumers (foundry / hardhat / ts) | ||
| docs/adr/ architecture decision records (this repo's decisions) | ||
| ``` | ||
|
|
||
| The cross-cutting design lives in the **planning vault**; this repo holds the code and its per-repo ADRs. See [AGENTS.md](./AGENTS.md) for the boundary rule. | ||
|
|
||
| ## Develop | ||
|
|
||
| ```bash | ||
| pnpm install | ||
| pnpm build # turbo: builds both packages | ||
| pnpm test # turbo: vitest + forge test | ||
| pnpm typecheck | ||
| pnpm lint # biome | ||
| ``` | ||
|
|
||
| Requires **pnpm 9+**, **Node 20+**, and **Foundry** (for the Solidity package). | ||
|
|
||
| ## Contributing | ||
|
|
||
| See [CONTRIBUTING.md](./CONTRIBUTING.md). Every change to a published package needs a Changeset. | ||
|
|
||
| ## License | ||
|
|
||
| [MIT](./LICENSE) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", | ||
| "vcs": { "enabled": true, "clientKind": "git", "useIgnoreFile": true }, | ||
| "files": { "ignore": ["dist", "out", "cache", "node_modules", "**/*.sol"] }, | ||
| "organizeImports": { "enabled": true }, | ||
| "formatter": { | ||
| "enabled": true, | ||
| "indentStyle": "space", | ||
| "indentWidth": 2, | ||
| "lineWidth": 100 | ||
| }, | ||
| "linter": { | ||
| "enabled": true, | ||
| "rules": { "recommended": true } | ||
| }, | ||
| "javascript": { | ||
| "formatter": { "quoteStyle": "single", "semicolons": "asNeeded" } | ||
| }, | ||
| "overrides": [ | ||
| { | ||
| "include": ["**/test/**", "**/*.test.ts"], | ||
| "linter": { | ||
| "rules": { | ||
| "style": { "noNonNullAssertion": "off" } | ||
| } | ||
| } | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # ADR-0001: Monorepo layout, packages & toolchain | ||
|
|
||
| **Status:** Accepted | ||
| **Date:** 2026-06-10 | ||
| **Related:** planning/Designs/sdk-architecture.md (Q1: both SDKs in one repo) | ||
|
|
||
| ## Context | ||
|
|
||
| The EFS SDK ships two deliverables from one repo (`github.com/efs-project/sdk`): a **TypeScript SDK** (npm, off-chain reads/writes) and an **on-chain Solidity SDK** (a compile-in library). The planning design resolved Q1 — both live here because distribution, not deployment, is the deciding factor: the Solidity library is `npm install`-ed and compiled into a dev's own contract, exactly like `@openzeppelin/contracts`. | ||
|
|
||
| We need a layout that is clean for us (builders) and obvious for external devs, with a publishing story that works for both audiences. | ||
|
|
||
| ## Decision | ||
|
|
||
| A **pnpm + Turborepo + Changesets** monorepo with two independently-versioned packages: | ||
|
|
||
| ``` | ||
| sdk/ | ||
| ├── packages/ | ||
| │ ├── sdk/ → npm @efs/sdk (TypeScript, off-chain) | ||
| │ └── solidity/ → npm @efs/solidity (Solidity, compile-in source) | ||
| ├── examples/ (foundry-consumer, hardhat-consumer, ts-quickstart) | ||
| ├── docs/adr/ (this system) | ||
| ├── pnpm-workspace.yaml, turbo.json, tsconfig.base.json, biome.json, .changeset/ | ||
| ``` | ||
|
|
||
| - **Workspace manager: pnpm.** De-facto standard for 2025–2026 TS+Solidity monorepos (viem, wagmi); strict `node_modules` avoids phantom-dependency bugs. We override the sibling `contracts` repo's yarn/scaffold-eth convention — inheriting yarn isn't worth it here. | ||
| - **Task runner: Turborepo.** Caches build/test/typecheck across packages. | ||
| - **Two packages, versioned independently via Changesets.** The Solidity ABI and the TS API move on different cadences; lockstep would force no-op bumps and dishonest changelogs. | ||
| - **npm scope `@efs`** (selected 2026-06-10 after confirming the scope has no published packages on the npm registry; pending the org being claimed via `npm org create efs` before first publish). The GitHub org stays `efs-project`; only the npm scope is the shorter `@efs`. | ||
| - **Package name `@efs/solidity`, not `…/contracts`** — to avoid conceptual collision with the core protocol repo (`efs-project/contracts`). This SDK is a *library you compile in*, not the deployed protocol. | ||
|
|
||
| ## Consequences | ||
|
|
||
| - External devs run `npm i @efs/sdk` (TS) or `npm i @efs/solidity` (Solidity source + remap). One repo, two clear install paths. | ||
| - Changesets gates every PR on a stated version intent; CI opens a "Version Packages" PR and publishes on merge. | ||
| - The package names cross the npm boundary, so renaming after external adoption is a breaking change — hence settling the `@efs` scope pre-publish. | ||
| - Toolchain specifics (bundler, test runner, lint) are recorded in ADR-0002+ and the package configs; they are Ephemeral and revisable. | ||
|
|
||
| ## Alternatives considered | ||
|
|
||
| - **Single package** holding both TS and Solidity — rejected: the two have different consumers, toolchains, and release cadences; one version line couples them artificially. | ||
| - **yarn workspaces** (for parity with `contracts`) — rejected: consistency with a legacy scaffold doesn't outweigh pnpm's correctness and ecosystem momentum. | ||
| - **Two separate repos** — rejected by the design's Q1: they share docs, examples, and a coordinated story; one repo keeps them in sync. |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.