Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
245 commits
Select commit Hold shift + click to select a range
a5a03e2
chore: scaffold the EFS SDK monorepo
JamesCarnley Jun 10, 2026
7f0f5b7
docs(adr): note the lightweight MADR-style lineage
JamesCarnley Jun 10, 2026
c8e5a19
chore: adopt @efs npm scope; trim ADR system per validation
JamesCarnley Jun 10, 2026
885a0ad
docs: add docs/specs/ — plain-language "how it works" layer
JamesCarnley Jun 10, 2026
7994df5
ci: fix scope rename in CI; add OIDC release workflow (ADR-0004)
JamesCarnley Jun 10, 2026
117b1b4
ci: fix Solidity forge-std install and changeset gate
JamesCarnley Jun 11, 2026
daa503a
ci: harden workflows per review
JamesCarnley Jun 11, 2026
eadb898
fix(solidity): forge fmt clean + drop stub warnings
JamesCarnley Jun 11, 2026
bd6f0a3
ci/sdk: address Codex review — release build scope + stale version
JamesCarnley Jun 11, 2026
ba5c8b1
adr: ADR-0005 — per-chain deployments registry; SDK is a client not a…
JamesCarnley Jun 11, 2026
d1e88d3
fix: address SDK-relevant findings from holistic review (cheap defects)
JamesCarnley Jun 11, 2026
cf3025e
plan: beta-slice implementation spec (review-hardened)
JamesCarnley Jun 11, 2026
85c7d3d
ci: unblock Changesets version PR + make solidity tests self-bootstra…
JamesCarnley Jun 11, 2026
2c88bc2
feat(content): contentHash = bare SHA-256 (ADR-0006) + real hashing m…
JamesCarnley Jun 11, 2026
39653f6
style: biome-format verifyContent signature (CI lint fix)
JamesCarnley Jun 11, 2026
e71548b
ci: disable auto-publish until launch (Codex P1)
JamesCarnley Jun 11, 2026
5e92a8d
feat(sdk): namespaced client (F) + EAS layer, lenses, deployments, er…
JamesCarnley Jun 11, 2026
c70a66f
fix(sdk): async fs stubs + honest integrity-check docs (review)
JamesCarnley Jun 11, 2026
145e590
docs: fix package README quickstart to namespaced API (Codex P2)
JamesCarnley Jun 11, 2026
9e5467f
fix(eas): forward resolver value as msg.value in attest builders (Cod…
JamesCarnley Jun 11, 2026
4017c17
refactor(sdk): foundation hardening batch 1 — types, write-gating, seams
JamesCarnley Jun 11, 2026
82d5b03
docs: quickstart uses the actual ReadOptions key `lens` (Codex P2)
JamesCarnley Jun 11, 2026
f9733fc
chore(sdk): foundation hardening batch 2 — exports, attw/publint, ADRs
JamesCarnley Jun 11, 2026
cdd250f
docs: standards-foundation spec (7-domain EIP/ERC/CAIP research pass)
JamesCarnley Jun 11, 2026
1ca8d9e
fix(solidity): exports map exposes the documented src/*.sol import (C…
JamesCarnley Jun 11, 2026
3443be8
feat(sdk): EIP-1193 provider boundary (standard at the edge, viem ins…
JamesCarnley Jun 11, 2026
69239b1
fix(solidity): _efsPinFile locks the emit happy-path shape (Codex P2)
JamesCarnley Jun 11, 2026
3e1233e
docs: future-proofing doctrine (9-domain research pass 2)
JamesCarnley Jun 11, 2026
97230fe
docs: recover dropped pass-2 findings (completeness sweep + sim seam)
JamesCarnley Jun 11, 2026
d4e413c
review: apply verified API + standards review (40 findings)
JamesCarnley Jun 11, 2026
449c286
feat: build freeze-independent foundation (fetch engine, classifier, …
JamesCarnley Jun 11, 2026
ae1d1c0
fix(ci): scope noNonNullAssertion off for tests, keep src strict
JamesCarnley Jun 11, 2026
78a6a6c
fix(mirror): block canonical hex IPv4-mapped IPv6 in SSRF guard (P1)
JamesCarnley Jun 11, 2026
a0c0d83
fix(mirror): re-check redirect targets in SSRF guard (P1)
JamesCarnley Jun 11, 2026
59253c1
fix(mirror): trailing-dot host bypass (P1) + data: URI size cap (P2)
JamesCarnley Jun 11, 2026
2fa8bf9
harden(mirror): IPv6 transition SSRF, decompression bomb, data: decod…
JamesCarnley Jun 11, 2026
db195ad
harden(mirror): reject gateway path traversal in ipfs/arweave subpath…
JamesCarnley Jun 11, 2026
335762d
harden(mirror): require / boundary in gateway namespace check (P2)
JamesCarnley Jun 11, 2026
0e6a859
feat: build on merged on-chain tag-exclusion filter + folder Overview…
JamesCarnley Jun 15, 2026
310ef5f
chore(size): raise budget to 10 kB for the view ABI + filter/Overview…
JamesCarnley Jun 15, 2026
8481394
fix(mirror,errors): UTF-8 data: cap + walk cause chain for error code…
JamesCarnley Jun 15, 2026
f4f9bb5
fix(mirror): exclude base64 padding/whitespace from data: cap prechec…
JamesCarnley Jun 15, 2026
fa56b11
fix(mirror,eas): byte-wise data: octet decode + EAS error fragments (…
JamesCarnley Jun 15, 2026
be24b0c
fix(mirror): percent-decode base64 data: bodies before decoding (P2)
JamesCarnley Jun 15, 2026
28a0bd8
fix(mirror): bound-aware data: octet decode — enforce cap DURING deco…
JamesCarnley Jun 15, 2026
1f0541f
fix(mirror): size-check percent-encoded base64 before materializing (P2)
JamesCarnley Jun 15, 2026
47dd93b
fix(mirror): trim media type before ;base64 test + surrogate-safe flush
JamesCarnley Jun 15, 2026
6e39a25
feat(chain): reshape deployments registry to the frozen 9-schema set …
JamesCarnley Jun 18, 2026
2be9b88
fix(eas,mirror): ABI-aware schema parse (tuples) + abort before inlin…
JamesCarnley Jun 18, 2026
b4f5d6b
fix(mirror): redact data: payloads from error/attempt records (P2)
JamesCarnley Jun 18, 2026
586aad9
fix(mirror): summarize failed URL strings + require 43-char Arweave t…
JamesCarnley Jun 18, 2026
2ad3f83
fix(mirror,content): final redirect URL in urlUsed + reject non-canon…
JamesCarnley Jun 19, 2026
3556c6b
fix(mirror): block IPv6 multicast (ff00::/8) in SSRF guard (P2)
JamesCarnley Jun 19, 2026
6d2e1dd
feat(writes): file-write graph builder — the shared core of both subm…
JamesCarnley Jun 19, 2026
d4322db
feat: write path + read ABIs + on-chain EFSWriter routine + local-for…
JamesCarnley Jun 19, 2026
3bd4fdf
feat(sdk): wire fs.write (Tier-1) + read verbs end-to-end
JamesCarnley Jun 19, 2026
f5fc542
fix(sdk): write contentHash as bare ADR-0006 digest, not 0x-prefixed
JamesCarnley Jun 19, 2026
8f59bfa
refactor(sdk): read surface — read/locate/info/exists, fields+expand,…
JamesCarnley Jun 19, 2026
3376e80
feat(sdk): on-chain (web3:// SSTORE2) write default + read round-trip
JamesCarnley Jun 20, 2026
3db8e3c
feat(sdk): createParents (mkdir -p) for nested writes
JamesCarnley Jun 20, 2026
8b0114a
feat(sdk): default createParents to true (mkdir -p on by default)
JamesCarnley Jun 20, 2026
9448c13
fix(sdk): review P1 correctness + quick wins
JamesCarnley Jun 20, 2026
17b395b
fix(sdk): emit ancestor folder-visibility TAGs on write
JamesCarnley Jun 20, 2026
8602021
fix(sdk): open the WriteMechanism union (+ eip7702)
JamesCarnley Jun 20, 2026
df6af60
feat(sdk): schema-UID deployment integrity gate (1.0 trust blocker)
JamesCarnley Jun 20, 2026
02c8c4d
feat(solidity): EFSReader — first-class on-chain read wrappers
JamesCarnley Jun 20, 2026
e318ca6
feat(sdk): complete escape hatches — efs.raw instances, efs.eas verbs…
JamesCarnley Jun 20, 2026
0f34ed6
docs(sdk): scope the integrity-gate forgery-resistance claim accurately
JamesCarnley Jun 20, 2026
4e93a04
refactor(sdk): route writes through the pluggable Submitter seam (AA-…
JamesCarnley Jun 20, 2026
3b26d33
feat(solidity): write wrappers for tag/property/anchor/place/list pri…
JamesCarnley Jun 20, 2026
075ac9f
feat(sdk): edge/value write primitives — efs.graph.tags / props / gra…
JamesCarnley Jun 20, 2026
22ba660
fix(solidity): property key-anchors use PROPERTY_SCHEMA_UID forSchema
JamesCarnley Jun 20, 2026
12480b8
feat(sdk): lists read surface (efs.lists.*) + deferred sorts stub
JamesCarnley Jun 20, 2026
a72cb02
feat(sdk): lists write surface (efs.lists.create/add/remove)
JamesCarnley Jun 20, 2026
c518142
docs(sdk): clarify lists dedupe is defensive; annotate impossible-sta…
JamesCarnley Jun 20, 2026
9290bb1
feat(solidity): REDIRECT resolution + setRedirect wrapper (ADR-0050)
JamesCarnley Jun 20, 2026
64f36e8
feat(sdk): REDIRECT (alias) support — read-time resolution + write ve…
JamesCarnley Jun 20, 2026
81a1df4
feat(sdk): folder Overviews + on-chain tag-exclusion filtered list (A…
JamesCarnley Jun 20, 2026
492d239
feat(sdk): standalone mirror writes — efs.mirrors.add/remove/list
JamesCarnley Jun 20, 2026
e4c19bb
fix(sdk): unresolvable exclude label fails closed, not with a leaked …
JamesCarnley Jun 20, 2026
4bbdbbf
feat(sdk): bigint-safe efs.toJSON + AnchorUID brand (P3 DX polish)
JamesCarnley Jun 20, 2026
dd1a387
fix(solidity): ship vendored EAS sources + remappings in tarball; fix…
JamesCarnley Jun 21, 2026
2e08e15
fix(sdk): normalize ar:// mirrors, honor WriteOptions.signal; fix REA…
JamesCarnley Jun 21, 2026
6294bdc
fix(reads): cross-chain DataRef guard + enforce web3:// byte cap duri…
JamesCarnley Jun 21, 2026
6971aca
fix(writes): per-mirror transport resolution; fail closed on resume
JamesCarnley Jun 21, 2026
7214646
fix: paginate props.list; gate edge writes; abort between deploys; do…
JamesCarnley Jun 21, 2026
9a57021
fix(reads/writes): overview render cap, DataRef expand hydration, unb…
JamesCarnley Jun 21, 2026
1042784
fix: file anchors use DATA_SCHEMA_UID forSchema, not generic (P1)
JamesCarnley Jun 21, 2026
650556b
feat(chain): seed live Sepolia (11155111) deployment in the built-in …
JamesCarnley Jun 21, 2026
ba7a156
fix(sdk): reject plaintext-HTTP transport, bound base64 filler, split…
JamesCarnley Jun 21, 2026
f5c3db4
fix: fail-closed no-claim value reads; Hardhat EAS dep; solidity fmt
JamesCarnley Jun 21, 2026
d042767
fix(reads): file leaves from DATA anchor slot; attested contentType +…
JamesCarnley Jun 21, 2026
8d029bf
fix: list lens scope, http gateway guard, plan-before-deploy, zero li…
JamesCarnley Jun 21, 2026
84f6e29
chore: update pnpm-lock.yaml for @efs/solidity eas-contracts dependency
JamesCarnley Jun 21, 2026
5bd8f68
fix: web3 transport on-chain fallback; empty property round-trip; cla…
JamesCarnley Jun 21, 2026
0a541b5
fix(writes/reads): reuse anchors on overwrite/update; resume list cursor
JamesCarnley Jun 21, 2026
fd99b46
fix: fs.list initial cursor + zero-limit guard; solidity listChildren…
JamesCarnley Jun 21, 2026
72f14bb
style: biome format list.ts comment (fix CI lint)
JamesCarnley Jun 21, 2026
3eefe9f
fix: web3 transport -> /transports/onchain anchor; solidity writeFile…
JamesCarnley Jun 21, 2026
2c2f1d7
fix(reads/writes): overview fails closed on bad verification; hardlin…
JamesCarnley Jun 21, 2026
89d4bfb
fix(writes): props.list enumerates canonical key-anchors; reject sche…
JamesCarnley Jun 21, 2026
aeaf032
fix(reads/writes): info absent expand bag; wire fs.write onProgress
JamesCarnley Jun 21, 2026
ebe5f97
fix(lists/solidity): finite toArray caps; EFSWriter property update path
JamesCarnley Jun 21, 2026
60b528b
fix(writes): reject an explicitly empty mirrors list
JamesCarnley Jun 21, 2026
75ee8e0
fix(writes): classify on-chain storage wallet/RPC errors
JamesCarnley Jun 21, 2026
7988118
fix(reads): filtered list scans the DATA-schema child bucket, not ANCHOR
JamesCarnley Jun 21, 2026
971cfdf
feat(writes): deploy ERC-5219 EFSBytesStore for on-chain files
JamesCarnley Jun 21, 2026
0bd625c
fix(solidity/reads): placeExisting anchor reuse; fs.list integer limi…
JamesCarnley Jun 21, 2026
45b8906
fix(types): unbrand receipt step uid; drop unimplemented expand tokens
JamesCarnley Jun 21, 2026
fc191a0
fix(writes): signatureCount counts the on-chain storage deploys
JamesCarnley Jun 21, 2026
9e0bc52
fix(reads/writes): unfiltered dir page tuple decode (P1); write chain…
JamesCarnley Jun 21, 2026
39e5683
fix(writes): wrong-chain guard for standalone edge/value writes
JamesCarnley Jun 21, 2026
269330b
fix(eas/web3): chain guard on revokes; accept mixed-case web3 addresses
JamesCarnley Jun 21, 2026
23ef14c
fix(reads): declared size can't raise the fetch cap (P1); forward abo…
JamesCarnley Jun 21, 2026
96a8bc5
fix(writes/web3): reject empty mirror URIs; read raw single-SSTORE2 w…
JamesCarnley Jun 21, 2026
49bc089
fix(mirrors/web3): reject empty mirror URI in add; scope raw-SSTORE2 …
JamesCarnley Jun 21, 2026
c318c82
fix(writes): reject oversized mirror URIs before submitting (8192-byt…
JamesCarnley Jun 21, 2026
a17c78f
fix(writes): reject an unsupported (foreign) write lens instead of ig…
JamesCarnley Jun 21, 2026
31a05a4
fix(writes): wrong-chain guard queries the live provider chain, not b…
JamesCarnley Jun 21, 2026
87642ab
feat(chain): seed the community devnet (chainId 26001993) in the regi…
JamesCarnley Jun 23, 2026
1889c88
fix(reads/raw): resolve reads from the live chain; guard raw writes' …
JamesCarnley Jun 23, 2026
3227866
fix(raw): guard raw writes regardless of bound account; guard raw rea…
JamesCarnley Jun 23, 2026
79a102d
fix(writes): standalone-namespace reads resolve from the live chain
JamesCarnley Jun 23, 2026
055937c
fix(writes/eas): guard public-client chain on writes; eas.getAttestat…
JamesCarnley Jun 23, 2026
9a5a6bf
fix(account): key capabilities() probe by the live chain, not constru…
JamesCarnley Jun 23, 2026
884b637
fix(writes): re-assert the live chain before each write tx, not just …
JamesCarnley Jun 23, 2026
09aba23
fix(reads): validate maxBytes cap; reject chainless ViemConfig client…
JamesCarnley Jun 23, 2026
41ee47b
fix(writes): guard standalone-write planning reads against a drifted …
JamesCarnley Jun 23, 2026
e9adb0f
fix(writes): guard file-write planning reads and receipt waits agains…
JamesCarnley Jun 23, 2026
23e661d
fix(writes): guard setOverview and mirrors.add planning reads against…
JamesCarnley Jun 23, 2026
66a010a
feat(reads): scaffold pluggable ReadSource + trust provenance seams (…
JamesCarnley Jun 23, 2026
040b374
chore(size): raise budget to 38 kB for the ReadSource foundation
JamesCarnley Jun 23, 2026
dd5de95
refactor(types): revise TrustDescriptor per expert naming review; siz…
JamesCarnley Jun 23, 2026
0fc48eb
fix(reads): guard readContext reads against a post-resolution chain d…
JamesCarnley Jun 23, 2026
5d44417
fix: validate engine maxBytes; isolate progress-hook throws; guard na…
JamesCarnley Jun 23, 2026
4363d01
fix(reads): pin all props.list reads to one chain; validate lists.has…
JamesCarnley Jun 23, 2026
16bf2c9
fix(reads): read empty files (size 0); hydrate top-level item UIDs in…
JamesCarnley Jun 23, 2026
e1d1de6
fix(raw): pin verifyDeployment probes to the resolved chain (TOCTOU)
JamesCarnley Jun 23, 2026
95c8c95
fix(writes,reads): partial-error on mid-write drift; let WrongChain e…
JamesCarnley Jun 23, 2026
87e4ca8
fix(writes): wrap mid-write aborts as partial failures; scope capabil…
JamesCarnley Jun 23, 2026
5e6d64d
fix(reads): accept terminal redirect at the hop cap; expose read name…
JamesCarnley Jun 23, 2026
6ba6eb7
fix(content): contentHash is the canonical multibase-multihash (specs…
JamesCarnley Aug 7, 2026
002b2d0
fix(names): canonical anchor-segment codec per specs/02 (NFC + upperc…
JamesCarnley Aug 7, 2026
de84c15
fix(redirects): implement the ratified resolution algorithm (specs/09…
JamesCarnley Aug 7, 2026
23970ea
fix(redirects): complete the EFSIndexer indexing lifecycle on set/rem…
JamesCarnley Aug 8, 2026
bda186b
fix(deployments): hardened Sepolia view trio, view-codehash gate, dri…
JamesCarnley Aug 8, 2026
f5bd087
feat(trust): land ADR-0015 read-trust provenance; close the six stand…
JamesCarnley Aug 8, 2026
c3452c5
feat(profile): the EFS v1 profile boundary (ADR-0019 — the review's R…
JamesCarnley Aug 8, 2026
df86a74
fix(review): four adversarial-review findings — reverted-tx honesty, …
JamesCarnley Aug 8, 2026
114f4ea
fix(review): round-2 findings — revoke-leg honesty, decoded-form NFC,…
JamesCarnley Aug 8, 2026
98e1a87
fix(solidity,writes): ratify the Solidity redirect follower; chain-gu…
JamesCarnley Aug 8, 2026
60f5de5
chore(solidity): forge fmt the followKind test edit
JamesCarnley Aug 8, 2026
d26feea
fix(validation): reject non-finite caps; truthful urlUsed + toJSON co…
JamesCarnley Aug 8, 2026
ee29325
fix(validation): sweep the remaining numeric entry points; pin the ca…
JamesCarnley Aug 8, 2026
8eb5d81
fix(verify,artifacts): enforce size:0 claims post-fetch; practical bu…
JamesCarnley Aug 8, 2026
3a4734e
fix(web3,artifacts,onchain): cancellable web3 reads; strict receipt f…
JamesCarnley Aug 8, 2026
4322508
fix(mirror): race the web3 attempt against the abort signal
JamesCarnley Aug 8, 2026
ffc71f8
fix(onchain,reads,artifacts): landed-chunk partial state; revoked-exc…
JamesCarnley Aug 8, 2026
a9ca3f2
fix(writes,artifacts): storage state through attestation failures; mi…
JamesCarnley Aug 8, 2026
c8b16f2
fix(reads,writes,web3): size claim is consistency not cap; full visib…
JamesCarnley Aug 8, 2026
5e82ba3
fix(raw,mirror,web3): real raw type gate; opaque redirects fail close…
JamesCarnley Aug 8, 2026
25e1bd7
fix(detect,artifacts): honest probe caching; closed reason discrimina…
JamesCarnley Aug 8, 2026
7ab8a54
fix(reads,mirror,guard): honor transports:[]; post-read chain re-chec…
JamesCarnley Aug 8, 2026
2a569b1
fix(writes,mirror): guard the write-planning reads; propagate aborts …
JamesCarnley Aug 8, 2026
8ad5607
fix(mirror,reads): fail non-streamable bodies (P1 cap bypass); timer-…
JamesCarnley Aug 8, 2026
3942221
fix(writes,index,types): storage on preflight failures; last raw plan…
JamesCarnley Aug 8, 2026
1e5aad3
fix(overview): derive source from the mirror actually used, not mirro…
JamesCarnley Aug 8, 2026
164c09b
fix(raw,props,docs): read-only type for no-wallet raw builder; guard …
JamesCarnley Aug 8, 2026
63c869c
fix(reads): withhold placement PIN provenance when the slot advanced …
JamesCarnley Aug 8, 2026
ad62a04
fix(tags,artifacts,indexer): guard tag definition walk; envelope-pres…
JamesCarnley Aug 8, 2026
5dae505
fix(lists,redirects): pin list config reads to the write deployment; …
JamesCarnley Aug 8, 2026
f19c0b4
fix(submit): distinct WriteUidsUnknownError for mined-with-unknown-UI…
JamesCarnley Aug 8, 2026
104c579
style(submit): precompute WriteNotSent guidance string (biome useTemp…
JamesCarnley Aug 8, 2026
99965d2
fix(lenses): finalize custom lens output at the resolveLens boundary
JamesCarnley Aug 8, 2026
eb107fd
fix(account,artifacts): capabilities refresh lever; rebrand nested re…
JamesCarnley Aug 8, 2026
ebcd3a2
fix(deployments,lenses): canonicalize schema UIDs at resolution; vali…
JamesCarnley Aug 8, 2026
bec207e
fix(mirrors,submit,lenses,reads): raw-count mirror paging; uncertain-…
JamesCarnley Aug 8, 2026
9e9ddca
fix(redirects): recheck revocation at the EAS decode (scan/decode TOC…
JamesCarnley Aug 8, 2026
ac5c5fe
fix(redirects,onchain): re-select within the winning attester after a…
JamesCarnley Aug 8, 2026
b44aa52
fix(onchain): unknown-send state for the chunk deploy (transport loss)
JamesCarnley Aug 8, 2026
a11c6fc
fix(solidity,graph): self-authorship gate on placeExisting; overview …
JamesCarnley Aug 8, 2026
bfbdcb5
fix(types): write-capable overload requires an account-bound wallet c…
JamesCarnley Aug 8, 2026
dfe075b
fix(solidity): atomic REDIRECT indexing lifecycle in setRedirect + re…
JamesCarnley Aug 8, 2026
29139e1
fix(graph,solidity): hardlink metadata contract; ownership gate on pl…
JamesCarnley Aug 8, 2026
07a42e5
fix(props,file,solidity): raw-count property paging; pre-storage tran…
JamesCarnley Aug 8, 2026
c2d2679
fix(submit,lists,pins): hardlink authorship gate at submission; list …
JamesCarnley Aug 8, 2026
0d02ef5
fix(submit,eas): DATA-schema check in the hardlink gate; unknown-send…
JamesCarnley Aug 8, 2026
d7355a5
fix(pins,submit): authorship+schema gates on pins.place; hardlink gat…
JamesCarnley Aug 8, 2026
442c841
fix(submit): fail-closed hardlink targets; active-mirror readability …
JamesCarnley Aug 8, 2026
2b834be
fix(pins,solidity): active-mirror readability proof on pins.place and…
JamesCarnley Aug 8, 2026
1a7d14e
fix(pins,solidity): the PIN definition must be an ANCHOR
JamesCarnley Aug 8, 2026
b4f4a1a
fix(submit,solidity): validate reused concrete file-ANCHORs before pl…
JamesCarnley Aug 8, 2026
db67484
fix(solidity): validate reused file-ANCHOR in writeFile before minting
JamesCarnley Aug 8, 2026
822e0cb
fix(edge,submit): gate the raw placement pair via plan stamps; bind r…
JamesCarnley Aug 8, 2026
414fa0b
fix(submit,pins,solidity): unconditional DATA-bucket check; Solidity …
JamesCarnley Aug 8, 2026
e1093db
fix(submit,edge): land the real unconditional bucket check; property-…
JamesCarnley Aug 8, 2026
846835e
fix(graph): mint the file-ANCHOR atomically with DATA (same layer)
JamesCarnley Aug 8, 2026
7318424
fix(lists): re-select an evaporated leader on RESUMED pages too
JamesCarnley Aug 8, 2026
5390383
fix(index,redirects,solidity): unknown-send state for indexer legs; p…
JamesCarnley Aug 8, 2026
68d3d8a
fix(graph): the Overview system TAG targets the DATA, not the file-AN…
JamesCarnley Aug 8, 2026
1223ea1
fix(lists,redirects): attester-bound pagination cursors; remove() thr…
JamesCarnley Aug 8, 2026
cf15969
fix(graph,solidity,redirects): mirror floor on byte writes; symlink→D…
JamesCarnley Aug 8, 2026
f7e400f
fix(edge,submit,solidity,mirror): boundary symlink gate; Solidity set…
JamesCarnley Aug 8, 2026
90c1ac2
fix(graph): validate mirror URIs and metadata correspondence in the e…
JamesCarnley Aug 8, 2026
1a94902
fix(submit,graph): chain assert before boundary gates; reject reuse+m…
JamesCarnley Aug 8, 2026
8478ff6
fix(reads): honor the transports option's priority order, not just it…
JamesCarnley Aug 8, 2026
9012353
fix(graph,submit): preflight mirror transport definitions before layer 1
JamesCarnley Aug 8, 2026
4f61b2b
fix(file): run the transport-anchor gate before the paid storage deploys
JamesCarnley Aug 8, 2026
d9b45c7
fix(index,edge): chain-guard ENS resolution; structural preflight for…
JamesCarnley Aug 8, 2026
b48366a
fix(edge): parse web3:// locators in the mirror write preflight
JamesCarnley Aug 8, 2026
a03af0c
fix(errors,lists): ambiguous RPC sends are unknown; per-request list …
JamesCarnley Aug 8, 2026
defb3c7
fix(edge): stamp standalone mirror plans so the transport gate covers…
JamesCarnley Aug 8, 2026
63dc6ff
fix(edge): run the URI preflight in buildMirrorPlan
JamesCarnley Aug 8, 2026
43d5cdb
fix(writes): reject a declared attester that is not the signing account
JamesCarnley Aug 8, 2026
910dcfe
fix(props,lists): bound property enumeration; keep the full lens-cand…
JamesCarnley Aug 8, 2026
820a9e5
fix(props): clamp the final key-scan window to the remaining budget
JamesCarnley Aug 8, 2026
e341daa
fix(redirects): enforce the sameAs node budget at discovery, not just…
JamesCarnley Aug 8, 2026
7b50f3d
fix(props,edge): maxKeys clamps to the ceiling; http is a known prefl…
JamesCarnley Aug 8, 2026
3f01435
fix(lists,index): restart ranked scan on an emptied bound attester; g…
JamesCarnley Aug 9, 2026
6273175
fix(graph,submit): validate concrete ancestor tag targets before layer 1
JamesCarnley Aug 9, 2026
0ff0df6
fix(submit,mirror): preflight the whole plan's symbolic refs; decode …
JamesCarnley Aug 9, 2026
75e0f48
fix(mirror): reject unassigned multibase prefixes; scan the NEWEST 50…
JamesCarnley Aug 9, 2026
512878e
fix(mirror): decode every accepted multibase; window the Solidity mir…
JamesCarnley Aug 9, 2026
41a0d6b
fix(writes): share ONE mirror-readability gate across every write path
JamesCarnley Aug 9, 2026
cd2d013
fix(writes): Tier-1 refuses role overrides that diverge from the signer
JamesCarnley Aug 9, 2026
72f7467
fix(mirror): reject incomplete bit-packed multibase CID bodies
JamesCarnley Aug 9, 2026
43e9ed5
fix(writes): validate contentType before the paid deploys
JamesCarnley Aug 9, 2026
581ecce
docs(types): mirrors select transports PER ENTRY, not by the first URI
JamesCarnley Aug 9, 2026
e00aa8b
fix(mirror): refuse the PADDED multibase codes instead of faking them
JamesCarnley Aug 9, 2026
83a86c2
fix(mirror): force ?format=raw ONLY on raw-block CIDs (P1)
JamesCarnley Aug 9, 2026
b038ec9
fix(writes): reject whitespace-padded mirror URIs
JamesCarnley Aug 9, 2026
126dc15
fix(writes): require a real scheme; stop echoing inline data: payloads
JamesCarnley Aug 9, 2026
0c07264
fix(writes): validate contentType on the shared builder, and bound it
JamesCarnley Aug 9, 2026
06527b6
fix(mirror,writes): require canonical varints and real media-type params
JamesCarnley Aug 9, 2026
0ea08d6
fix(writes): gate the Overview TAG definition and reserved contentHash
JamesCarnley Aug 9, 2026
70f6a64
fix(mirror,writes): varint overflow, and pin the Overview TAG to /tag…
JamesCarnley Aug 9, 2026
8256673
fix(mirror,writes): canonical Arweave ids, no media ranges, validate …
JamesCarnley Aug 9, 2026
4603d7b
fix(writes): one shared rule for reserved property values
JamesCarnley Aug 9, 2026
25ba352
fix(mirror): reject credential-bearing URLs and redact userinfo
JamesCarnley Aug 9, 2026
3e61caa
fix(mirror): redact through the FINAL authority @, not the first
JamesCarnley Aug 9, 2026
94a67b6
fix(writes): redact the URI when WRAPPING a parser failure
JamesCarnley Aug 9, 2026
aeb22dc
fix(mirror): redact before truncating in parseWeb3Uri errors
JamesCarnley Aug 9, 2026
1856e91
fix(solidity,mirror): reserved-value contract on-chain; redact past w…
JamesCarnley Aug 9, 2026
788a6e3
fix(solidity): cap EACH media-type name at 127 chars, per RFC 6838
JamesCarnley Aug 9, 2026
37badc4
fix(solidity): media-type OWS parity; reject a dangling semicolon
JamesCarnley Aug 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 5 additions & 0 deletions .changeset/ambiguous-rpc-local-selection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

Two correctness fixes: (1) ambiguous JSON-RPC send errors are no longer treated as proof that nothing was broadcast. `RpcError` is removed from the definite-refusal set — `-32000: already known`, `nonce too low`, and `replacement transaction underpriced` all mean the transaction (or a rival for its nonce) is already in the mempool and may mine, so they now surface as the UNKNOWN-send states (`WriteSendUnknownError` / `EasSendUnknown` / `OnchainSendUnknown` / `IndexSendUnknown`) instead of "not sent". Only wallet/provider refusal codes, decoded reverts, and the SDK's own pre-send guards remain definite. (2) List pagination derives its attester selection per request instead of mutating shared primed state — an attester-bound cursor on one `byPage()` call no longer moves a later unbound `byPage()`, `toArray()`, or iteration off the first-ranked candidate on the same `EfsList` handle.
5 changes: 5 additions & 0 deletions .changeset/ancestor-tag-target-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

Concrete `existingAncestorTagUIDs` are now validated before anything broadcasts: the builder shape-checks them (nonzero bytes32, both content kinds) and stamps them on the plan, and the submission boundary verifies each is an ANCHOR attestation. Their visibility TAGs sit in the LAST layer, so a well-shaped but nonexistent or non-anchor UID previously reverted only after the DATA, file anchor, metadata and placement had mined — a paid, half-applied write.
6 changes: 6 additions & 0 deletions .changeset/anchor-definition-gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@efs/sdk": patch
"@efs/solidity": patch
---

The placement gates now validate BOTH sides of the PIN: `efs.graph.pins.place` and Solidity `EFSLib.place` verify the definition is an ANCHOR attestation (`NotAnchorUID` on the Solidity side, a typed `InvalidArgument` on the TS side) — EdgeResolver accepts any existing attestation as a PIN definition, but path resolution discovers placements by resolving an ANCHOR and only then reading its PIN slot, so a PROPERTY/DATA (or nonexistent) definition confirmed a placement no reader could ever find. The TS check batches into the same `Promise.all` as the target read (multicall-coalesced).
5 changes: 5 additions & 0 deletions .changeset/atomic-anchor-data-layer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

The file-ANCHOR now mints in the SAME `multiAttest` layer as DATA (it depends only on the already-resolved parent — concrete, or the last `mkdir -p` folder from an earlier layer). Two `fs.write` calls racing for the same empty path both probe no-anchor; previously the loser's DATA layer mined before its anchor layer reverted `DuplicateFileName`, leaving paid storage plus an orphaned DATA graph with no file written. With the anchor in DATA's layer the slot collision rolls the whole layer back atomically — the loser lands nothing on the EAS side, its storage deploys ride the partial error's `storage` for reuse, and the retry resolves the winner's anchor into the overwrite path. (The Solidity `writeFile` is single-transaction and was already atomic.)
5 changes: 5 additions & 0 deletions .changeset/attester-must-be-signer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

The declared `attester` must be the account that actually signs. `submitEdgePlan`, `submitEdgePlanWithUID`, and `Tier1Submitter.submit` now reject a mismatch before broadcasting — previously a direct caller of these exported seams could pass an unrelated address, and the confirmed receipt would stamp it into `roles.author`/`signer`/`payer` (and, on the submitter seam, `DataRef.resolvedBy`), attributing on-chain attestations to an address that never authored them and making later reads through that ref resolve under the wrong lens. Rejected rather than silently corrected: a divergent attester means the caller's model of who is writing is wrong. Relayer/paymaster role divergence still rides `roles`, which is unaffected.
11 changes: 11 additions & 0 deletions .changeset/bigint-json-and-anchoruid-brand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@efs/sdk": patch
---

DX polish (review P3): a bigint-safe JSON serializer + an `AnchorUID` brand.

- **`efs.toJSON(value, space?)` + the exported `jsonReplacer`.** EFS result DTOs carry `bigint`s — `FileInfo.size`, `ListConfig.maxEntries`, the TAG weight reads, `WriteEstimate.gas`, the EAS `Attestation` time fields — and bare `JSON.stringify` THROWS on a bigint (`TypeError: Do not know how to serialize a BigInt`). That surprised devs the first time they logged a receipt, persisted a result, or handed a DTO across a serialization boundary (TanStack Query's cache, a Next.js Server→Client component prop, `res.json(...)`). `efs.toJSON` (and the lower-level `jsonReplacer`, a plain `JSON.stringify` replacer) render those bigints as decimal strings. Present on read-only clients too; pure + stateless. Documented round-trip caveat: serialization is lossy of the bigint TYPE — bigints come back as strings on `JSON.parse`, not bigints (there is no safe automatic reviver), so the consumer re-`BigInt(…)`s the fields it knows are numeric (same as viem/wagmi at the JSON boundary).

- **`AnchorUID` brand.** A folder ANCHOR's UID is now branded distinctly from `DataUID` (review P3 / A11): `DirEntry`'s dir variant carries `anchorUID: AnchorUID`, its file variant carries `dataUID: DataUID`. Catches the wrong-UID-kind integration bug at the type level — passing a folder anchor where a file's DATA UID is expected. Both are `Hex` at runtime (zero cost); the distinction is type-only. `AnchorUID` is exported alongside `DataUID`.

New exports: `toJSON`, `jsonReplacer`, `AnchorUID`. No runtime behavior change to existing verbs; no bundle-size-relevant code on the read/write hot paths.
5 changes: 5 additions & 0 deletions .changeset/bound-cursors-remove-unknown-flag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

Two follow-on corrections: (1) list-pagination cursors now BIND their offset to the attester whose listing they index (`<offset>:<attester>`): resuming re-aligns the selection to the bound attester (continuing that listing exactly — no skip, no duplicate — even when it is no longer the ranked leader), and a cursor whose attester left the candidate set is void, restarting the ranked walk at offset 0 instead of silently applying a foreign offset to the new winner. Legacy bare-numeric cursors still parse and apply to the current selection. (2) `redirects.remove` now threads `IndexSendUnknown` onto `IndexingIncomplete.indexBroadcastUnknown` like `set` does — the previous wave's edit script had crashed before applying the remove-branch change, so a lost-response `indexRevocation` send reported `indexBroadcastUnknown: false`, a provably incorrect outcome for the documented recovery field.
6 changes: 6 additions & 0 deletions .changeset/bucket-check-solidity-slot-binding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@efs/sdk": patch
"@efs/solidity": patch
---

The placement-gate matrix completes: (1) the DATA-bucket check is now UNCONDITIONAL in the TS gates — the layered boundary and `pins.place` decode every placement anchor's `(name, forSchema)` payload and refuse anchors outside the DATA file bucket even on standalone plans with no requested slot (a generic-folder or PROPERTY-key ANCHOR passed the schema check but file resolution only discovers DATA-bucket terminals). (2) Solidity `writeFile` and the six-argument `placeExisting` bind reused anchors to the requested `(parent, fileName, DATA)` slot via the shared `_requireAnchorNamesSlot` (reverting the new `AnchorSlotMismatch`), and the standalone `place` enforces the DATA bucket (`NotFileBucketAnchor`) — a valid ANCHOR from another slot previously let the transaction and `EFSFileWritten` confirm while a different path was overwritten or nothing discoverable was placed.
5 changes: 5 additions & 0 deletions .changeset/builder-uri-metadata-preflight.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

The exported graph builder gains the full byte-plan preflight: (1) every mirror URI is validated (`validateMirrorUri` — blank/oversized URIs previously encoded fine and reverted at the layer-2 MirrorResolver AFTER layer 1 mined, leaving a paid partial graph); (2) `contentHash` and `size` are verified against the supplied bytes before any layer is constructed — the `ContentHash` brand checks format only, so a stale hash from changed bytes persisted permanently and made every fail-closed read (`readText` etc.) reject forever, while a wrong size attested false metadata. `hashContent` is synchronous, so the builder stays pure and sync; the orchestrated `fs.write` path derives both values itself and is unaffected.
5 changes: 5 additions & 0 deletions .changeset/canonical-anchor-segment-codec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

Anchor segments are now canonically encoded per contracts specs/02 (NFC + uppercase percent-encoding of the reserved byte set), fixing the P1 where `fs.write('/Q&A: Episode 5/file.txt')` reverted at the ANCHOR layer after storage deployed and a decomposed-Unicode segment silently minted a different permanent slot. One codec module (`names/segment.ts`, new exports `encodeName`/`decodeName`/`isCanonicalName`/`asCanonicalName`/`CanonicalName`/`InvalidAnchorNameError`) mirrors `EFSIndexer._isValidAnchorName` byte-for-byte — including the over-escape rejection the contract enforces but the spec prose omits (flagged upstream). Public `fs.*` path strings and `props`/`fields` keys are HUMAN; encoding happens once at the resolution choke points (`splitPathToCanonical`, `resolvePathToAnchor`, `resolveOrPlanParents`, `readReservedProperty`, `props.set`), validated BEFORE any chain read or storage deploy. A raw string is never sniffed as canonical (provably ambiguous: `100%25` is both a legal human name and a legal canonical form) — the `CanonicalName` brand on `ParentPlan`/`FileWriteGraphInput`/`buildPropertyPlan` is the boundary, with a dev-guard in `buildFileWriteGraph`. Chain-out names decode back to human: `DirEntry.name` and `props.list()` keys now return the strings you wrote (fail-soft verbatim for non-canonical foreign data). BREAKING vs the unreleased scaffold: a pre-encoded segment passed as a path is now treated as human and double-encodes — callers holding canonical forms must `decodeName` first (or use the exported codec); `ParentPlan.fileName`/`missingSegments` are `CanonicalName`. New error code `InvalidAnchorName`. Spec vectors (`Q%26A%3A%20Episode%205`, composed/decomposed `é`, literal `%`, the full reserved-byte table) imported as tests.
11 changes: 11 additions & 0 deletions .changeset/canonical-arweave-media-name-and-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@efs/sdk": patch
---

Three write-time validation fixes on values that become authoritative.

Arweave transaction ids must now be canonical base64url. 43 base64url characters carry 258 bits but the id is a 32-byte hash, so the final character's low two bits are padding and must be zero — the length-and-alphabet screen accepted a non-canonical spelling that strict base64url and Arweave parsers reject, and `fs.write` could confirm it as a file's only mirror.

`contentType` no longer accepts media RANGES. Both halves used the HTTP token grammar, which permits the wildcard character, so `text/` + wildcard passed — that is what a client sends in `Accept`, not what a file is, and stored as authoritative metadata it even reads as displayable text because `fs.overview()` keys on the `text/` prefix. Type and subtype now use the RFC 6838 restricted-name grammar; parameter names and values keep the token grammar.

The reserved `size` property is now validated on the shared builder alongside `contentType` and `contentHash`. A malformed value does not degrade gracefully as it first appears: every reader's `parseSize` returns `undefined`, and in `reads/overview.ts` that `undefined` skips the documented pre-fetch `too-large` short-circuit entirely, so the overview attempts a fetch and fails at the render cap instead of returning `{kind: 'too-large'}` without touching the network. `fs.info()` simply omits the size. The canonical non-negative decimal form that file writes emit is required.
5 changes: 5 additions & 0 deletions .changeset/canonical-schema-uids-lens-address-validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

Two boundary-validation fixes: (1) `resolveDeployment` now canonicalizes every schema UID on the returned record to `0x` + 64 lowercase hex (memoized copy; the source record is never mutated) and rejects values it cannot consume with a typed error — verification was already value-tolerant of how a custom record writes a UID (uppercase, leading-zero-shortened), but the non-canonical form then broke strict-equality consumers (the symlink walk reported valid redirect targets as dangling) and `bytes32` ABI encoding. (2) `resolveLens` validates every address at the common lens boundary with `isAddress` — a malformed template-compatible literal (`'0x1234'`) or a custom lens's bad output now fails immediately with a typed error instead of surfacing later as a generic ABI/RPC read failure.
9 changes: 9 additions & 0 deletions .changeset/canonical-varints-and-strict-media-params.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@efs/sdk": patch
---

Two strictness fixes on values that reach the chain irreversibly.

CID varints must now be minimally encoded. `unsigned-varint` requires the shortest form, but the decoder returned the numeric value without checking, so `81 00` and `01` both read as version 1 — meaning a valid CID with a redundant byte spliced in cleared the entire write preflight and could be minted as a file's only mirror, while strict CID parsers and gateways reject the locator outright.

`contentType` parameters are now validated against the real RFC 9110 grammar. The quoted-value branch was `"[^"]*"`, which accepts raw control characters, and the separator used `\s*`, which admits CR and LF. A value like `text/plain; note="a<CR><LF>b"` therefore passed and was persisted as the authoritative PROPERTY and as the ERC-5219 store's reported MIME — a CRLF that any gateway echoing the header would emit verbatim. The quoted branch now spells out `qdtext` and `quoted-pair`, and whitespace is restricted to HTTP `OWS` (SP/HTAB). Legitimate quoted parameters, including escaped quotes, are unaffected.
12 changes: 12 additions & 0 deletions .changeset/capabilities-live-chain-key.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@efs/sdk": patch
---

`efs.account.capabilities()` now keys the account probe by the LIVE provider chain
instead of the construction-time `publicClient.chain.id`. The `getCode` classification
and EIP-5792 `getCapabilities` already land on the provider's current chain, so a mutable
EIP-1193 provider that switched networks after the client was built could mix new-chain
bytecode/capabilities into an old-chain cache slot and return the wrong `kind`/gasless
status. Querying `publicClient.getChainId()` for the cache key keeps detection consistent
with the chain the reads actually hit — the last live-chain gap, matching the read and
write paths.
5 changes: 5 additions & 0 deletions .changeset/capabilities-refresh-nested-brand.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

Two review fixes: (1) `efs.account.capabilities()` accepts `{ refresh: true }` — the client-level invalidation lever for the capability-profile cache. The probed inputs are mutable on-chain state (a counterfactual smart-account deploy or an EIP-7702 delegation added/removed changes the account's code without changing the cache key), and provider-form callers cannot reach the internally-created wallet object that scopes the cache; the option evicts the live-chain cache entry and re-probes. (2) `parseWriteReceipt` now REBUILDS the nested `data` ref (validated fields + `__brand: 'DataRef'` + profile) instead of spreading the payload through — an external artifact could omit or forge the brand and violate the branded `WriteReceipt.data: DataRef` contract; the construction is shared with `parseDataRef` via one helper.
5 changes: 5 additions & 0 deletions .changeset/chunk-send-unknown.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@efs/sdk": patch
---

The SSTORE2 chunk deploy gets the same send-outcome honesty as the manager leg and the layered submitter: a code-less transport failure during the chunk send (connection drop after the request may have reached the node) now throws the new `OnchainSendUnknown` — broadcast state unknown, the deploy may still mine and bill gas, no hash to reconcile by — instead of an ordinary classified error that invited a `fs.write` retry paying for duplicate storage. A refusal response (wallet/node error code, decoded revert) still propagates as the classified error, where a retry is clean.
12 changes: 12 additions & 0 deletions .changeset/classify-onchain-storage-errors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@efs/sdk": patch
---

The default `fs.write(path, bytes)` on-chain (SSTORE2) storage path now routes its
wallet/RPC calls through the same `classifyError` funnel the submitter uses. A wallet
rejection or RPC failure during the chunk deploy, manager deploy, or receipt wait now
surfaces as the documented EFS error tree (`UserRejected` / `RpcError` / typed write
errors) instead of a raw viem/provider error — so callers handling the EFS error tree no
longer miss the common quickstart write path. Abort (`signal`) still propagates as the
caller's `AbortError` (the pre-send checks stay outside the funnel), and typed errors like
`MultiChunkUnsupported` pass through unchanged (the classifier is idempotent).
6 changes: 6 additions & 0 deletions .changeset/concrete-anchor-validation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@efs/sdk": patch
"@efs/solidity": patch
---

Reused concrete file-ANCHORs are now validated before broadcast: (1) the builder stamps plans with `anchorSchemaUID` + `existingAnchorUID` when an overwrite/relink reuses a concrete anchor, and `submitLayeredTier1` verifies the reused definition IS an ANCHOR attestation (fail-closed on a missing stamp or a read-incapable context) — an arbitrary `existingFileAnchorUID` executed through the exported layered submitter previously skipped the anchor mint and could confirm a placement `fs.*` can never discover. (2) Solidity's six-argument `placeExisting` applies the same `NotAnchorUID` check to a nonzero reused anchor before attesting the PIN. For `fs.write` (which resolves the UID via `resolveAnchor` — an ANCHOR by construction) this is one extra defense-in-depth read per overwrite.
11 changes: 11 additions & 0 deletions .changeset/config.json
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": []
}
6 changes: 6 additions & 0 deletions .changeset/content-hash-multibase-multihash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@efs/sdk": patch
"@efs/solidity": patch
---

`contentHash` now conforms to the ratified v1 encoding (contracts specs/10, SDK ADR-0016 superseding ADR-0006). `hashContent` emits the canonical multibase-base16 multihash string — `f1220` + 64 lowercase sha2-256 hex chars (69 chars) — instead of a bare digest, and the `ContentHash` brand now means that canonical string. The read path gains an algorithm-aware accepted-form decoder (`decodeContentHash`, new export with `CONTENT_HASH_CODES`): `f`/base16 and `b`/base32 (RFC 4648 lowercase, no padding) forms of the two registered functions (`0x12` sha2-256 canonical, `0x1b` keccak-256 alternate) decode, and `verifyContent` compares at DIGEST level, so a base32 or keccak-alternate claim of matching content verifies `matches-author`. Bare digests (the old ADR-0006 form), `0x`-prefixed values, uppercase, and unregistered codes report `malformed-claim` — deliberately, with no bare-digest tolerance: no SDK-written durable data exists, and the only legacy Sepolia population (debug-UI `0x`-keccak values) already read `malformed-claim` before. The mirror engine's `statusFor` now delegates to `verifyContent` (one decode/verify implementation). `FileWriteGraphInput.contentHash` is typed as `ContentHash` so a non-canonical string cannot re-enter the non-revocable PROPERTY persistence path. specs/10 §7 conformance vectors imported as tests. `@efs/solidity`: `EFSLib.ReservedKey` doc updated to the canonical form (comment-only).
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@efs/sdk": patch
"@efs/solidity": patch
---

Close the two gaps left by the previous mirror fixes. The IPFS CID check no longer has an alphabet-only path: every accepted multibase (base2/8/10/16/32 families, base36, base58btc, base58flickr) is really decoded and the bytes face the same version/codec/multihash parse, so `ipfs://k0000000000` — well-formed base36, not a CID — is refused. And the Solidity SDK's `_requireActiveMirror` now scans the newest 500 raw slots like the TypeScript reader and `EFSRouter`, instead of the oldest 500: an active mirror stranded below the readable window no longer lets a placement through, and one past the 500th slot no longer blocks a readable DATA.
Loading
Loading