Interfaces

The protocol is the event spine plus a small set of on-chain read interfaces. The interfaces let a service read a token's state by calling it, and reading state by call returns the same answer as replaying the events.

Minting

interface IAbxSequentialMint {
    function mint(address to) external returns (uint256 tokenId);
}

mint issues the next token in order (0, 1, 2, ...) to to and returns the id. The caller never chooses the id. It is advertised through ERC-165, so a minter checks support with supportsInterface and targets the interface rather than a concrete contract. This is the protocol's only opinion on minting. A token that does not advertise it, such as the one-shot 1/1 OneOfOneImage, is not a target for the shared minter.

Metadata rendering

interface IAbxMetadataRenderer {
    function tokenURI(address token, uint256 tokenId) external view returns (string memory);
    function contractURI(address token) external view returns (string memory);
}

interface IAbxFieldRenderer {
    function render(address token, uint256 tokenId, bytes32 field)
        external view returns (string memory contentType, bytes memory data);
}

interface IAbxOnChainReader {
    function read(address pointer) external view returns (bytes memory);
}

IAbxMetadataRenderer is a stateless, spec-versioned (specVersion()) contract that assembles the metadata JSON from a token's on-chain fields. IAbxFieldRenderer computes one field's value at read time; collection-scope reads pass tokenId = type(uint256).max. IAbxOnChainReader reads stored bytes and hides storage details such as SSTORE2 and compression.

Mint-time randomness

interface IAbxSeedSource {
    function seed(uint256 tokenId, address to) external returns (bytes32);
}

If a contract sets a seed source, it calls seed at mint and stores the result as the token's seed parameter. See code projects.

Standard reads

An ABX contract exposes the standard read surface: tokenURI (ERC-721), contractURI (ERC-7572), supportsInterface (ERC-165), and royaltyInfo (ERC-2981). It also exposes totalSupply(), the live minted-minus-burned count, which is separate from the supply cap. ABX does not advertise ERC-721 Enumerable, because its per-index reads are gas-heavy; enumeration is derived from the Transfer events instead.

Extension reads

Each extension that has a read surface exposes it, advertised through ERC-165:

  • Royalty: royaltyInfo.
  • Primary payee: primaryPayee().
  • External minter: minter().
  • Max invocations: the supply cap.
  • Paused: paused().
  • On-chain metadata: tokenField(tokenId, field) and contractField(field), with per-field lock reads.
  • On-chain script: scriptChunkCount() and scriptChunk(index).
  • Dependencies: dependencyCount(), dependencyByIndex(index), and dependencyRegistry().
  • Seed source: seedSource().
  • URI config: tokenURIRenderer() and contractURIRenderer() (zero means off-chain), and tokenURILocked() and contractURILocked().

Events-only extensions such as Royalty have no read interface. The AbxDeployed beacon and the per-extension version events are the signals a service relies on.

Configuration and batching

  • Deploy-time configuration happens in one transaction. The factory runs initialize, which takes the owner, the initial mint, the name and symbol, both URI pointers and renderers, the royalty, and the initial on-chain fields.
  • Same-contract batching uses Multicallable: multicall(bytes[]) -> bytes[]. It preserves msg.sender, reverts atomically, and rejects a non-zero msg.value.
  • Cross-contract atomicity is left to the account, such as an EIP-7702 EOA, ERC-4337, or a Safe, not built into the factory.