Contracts — PDLibraryRegistry
The registry is the platform's on-chain shelf of blessed JavaScript libraries — the p5.js a Project's script depends on, stored on Ethereum so the art's dependencies are as permanent as the art. Entries are written in chunks, finalized, and then frozen forever: no edit, no delete, no overwrite, by any key, ever. A mutable registry would be a back door into already-sold art; append-only is the hard rule. New versions are new entries.
How an entry is stored
Each library is a named, versioned byte blob written across SSTORE2 chunks (each within the EVM's 24,575-byte data-contract ceiling) over multiple transactions, then finalized:
function createLibrary(...) external onlyAdmin; // open an entry
function appendChunk(uint256 libraryId, bytes calldata data) external onlyAdmin;
function finalize(uint256 libraryId) external onlyAdmin; // freeze forever
Library text is stored as the base64 of its gzipped source — artwork pages embed it verbatim and decode it client-side, which keeps write costs sane and reads free of on-chain re-encoding. The registry also stores the raw inflater tool (setInflater) that artwork documents inline to do that decoding — so even the decompressor the art depends on lives on-chain.
Every entry is one of two kinds, named when it is created. A library is that base64 text. A tool is raw JavaScript inlined as it is: the inflater, which defines PD_INFLATE. Only a finalized tool can be designated the inflater (setInflater reverts NotFinalized or WrongKind otherwise), and a Project binds only a library (its deployment reverts WrongLibraryKind otherwise).
How Projects use it
A Project binds at most one library, fixed at createProject time; the factory enforces that only finalized entries can be bound. The Project also copies the registry's current inflater at deployment and keeps it forever, so designating a new inflater only changes Projects deployed after it (and createProject takes the inflater id the artist previewed with, reverting if it has changed since). At render time, tokenURI inlines that inflater, the library blob, and a bootstrap that decodes and injects the library as synchronous script text before the artist's first line runs. See PDProject.
The binding is also where every Output's Language attribute comes from: the entry's exact "name version" (p5.js 1.11.13) is copied into the Project at deployment and rides its metadata forever — the artist's tool, versioned and stored on Ethereum, not a label anyone typed. Vanilla Projects read JavaScript.
The supported languages
PD launches with one blessed library, written to the registry as its own frozen entry:
| Library | For |
|---|---|
| p5.js 1.11.13 | The lingua franca of creative coding, in the version most existing sketches target |
The entry is the library's official npm build, gzipped and base64'd, and it decodes back to the original byte for byte through the on-chain unzipper. What each gives your script is on Writing for the Chain.
Vanilla JavaScript is always available and needs no registry entry at all. The vocabulary extends itself the day a new library is blessed — a new entry, finalized and frozen, with no list anywhere to maintain.
function isFinalized(uint256 libraryId) external view returns (bool);
function readLibrary(uint256 libraryId) external view returns (bytes memory);
function libraryInfo(uint256 libraryId) external view returns (...); // name, version, size
function chunkCount(uint256 libraryId) external view returns (uint256);
Governance
Deliberately none of its own. Writes are gated by a live read of the factory's admin() — the registry adds no second governance surface. One wrinkle from deploy order: the factory takes the registry's address as a constructor immutable, so the registry deploys first and its deployer wires the factory address exactly once (wireFactory); after wiring, the deployer key holds no power at all. No pause, no upgrades.
Further reading
- PDProject — the render pipeline that reads this
- PDFactory — the admin whose key gates writes
- Contracts Overview