ABIs and the protocol manifest
This page documents the machine-readable files themselves. For task-oriented recipes that use them (reading state, checking eligibility, watching events, running keeper actions), start at AI agents.
Everything a program (or an agent) needs to work with the protocol is served as static JSON from the docs site. Four entry points:
| Path | What it is |
|---|---|
/protocol-manifest.json |
addresses, ABI paths, and docs links for every protocol contract |
/abis/<ContractName>.json |
the raw ABI array for each contract, e.g. /abis/Patron.json |
/llms.txt |
LLM orientation file: a one-paragraph protocol summary plus a linked index of every docs page |
/docs-search-index.json |
the docs search corpus, an array of {path, page, heading, anchor, text} entries |
The protocol manifest
/protocol-manifest.json is the single machine-readable root. Top-level
fields: name, chainId, deployBlock, canonicalPoolId (the official
V4 pool id), docs, and llms. Under contracts, one entry per protocol
contract keyed by contract name:
{
"contracts": {
"Patron": {
"address": "0xC8ED01ffd957f5a62b1526d58E309c8bf2BB4A4c",
"abi": "/abis/Patron.json",
"docs": "/docs/contracts/patron",
"role": "…one-sentence description…"
}
},
"external": {
"token": {"address": "0x61C9d89fe1212F6b55fF888816A151463287B8ae", "label": "The $111 token (ArtCoinsToken)"},
"hook": {"address": "0x636c050296B5Cc528D8785169Bf8923716FCa9cc", "label": "Skim hook (ArtCoinsHookSkimFee)"}
}
}external carries the launch-stack and reference addresses that aren't
protocol contracts with their own reference pages: the
$111 token, the
skim hook, the LP locker, the MEV module, and
the sealed PunksData dataset. The human-readable version of the same table
is the addresses page.
Served ABIs
Each file under /abis/ is a plain JSON ABI array, directly usable as the
abi argument in viem, ethers, or wagmi. Available contract names:
Protocol contracts (each with a matching reference page under
/docs/contracts/):
PermanentCollection, Patron, ReturnAuctionModule,
ReturnAuctionEscrow, PunkVault, LiveBidAdapter, BuybackBurner,
VaultBurnPool, ProtocolFeePhaseAdapter, ReferralPayout,
PunkVaultTitleAuction, PCSwapContext, TokenAdminPoker,
ProtocolAdmin, RendererRegistry, PermanentCollectionMosaicRenderer,
PermanentCollectionProofRenderer, PunkSvgFragmentCache,
TraitIconCache
Launch stack and external contracts:
ArtCoinsHookSkimFee (the skim hook),
CryptoPunksMarket (the 2017 market), PunksData and CryptoPunksData
(the sealed trait dataset)
Also present in the served set, not part of the deployed protocol:
UnipegDispatcher (a demo callback dispatcher),
PermanentCollectionRendererV4 and VaultBurnAdapter (repo artifacts with
no mainnet deployment).
Loading the manifest with viem
import {createPublicClient, getContract, http} from 'viem';
import {mainnet} from 'viem/chains';
const ORIGIN = 'https://permanentcollection.art';
const manifest = await fetch(`${ORIGIN}/protocol-manifest.json`).then((r) => r.json());
const entry = manifest.contracts.Patron;
const abi = await fetch(`${ORIGIN}${entry.abi}`).then((r) => r.json());
const client = createPublicClient({
chain: mainnet,
transport: http('https://ethereum-rpc.publicnode.com'),
});
const patron = getContract({address: entry.address, abi, client});
const liveBidWei = await patron.read.bidBalance();The same pattern works for any contract in the manifest; swap the key and the function.
Importing from the repo
The site is built from the public repo at
github.com/ripe0x/permanent-collection.
The ABI files live at
app/lib/abis/,
each as both a raw <Name>.json and a typed TypeScript module <Name>.ts
exporting abi with as const typing for viem/wagmi type inference:
import {abi as patronAbi} from '@/lib/abis/Patron';If you vendor ABIs into your own project, prefer copying from the repo (or
fetching /abis/) over hand-writing fragments; the checked-in files are
generated from the compiled contracts and match the deployed bytecode.