Field renderers
Compute metadata fields from onchain state.
A field renderer is a view contract that computes one metadata field. It can produce an SVG, an
attributes array, or another value without a browser or hosted renderer.
Set a field's representation to renderer and store the renderer address as its value.
Interface
interface IAbxFieldRenderer {
function render(
address token,
uint256 tokenId,
bytes32 field
) external view returns (string memory contentType, bytes memory data);
}The metadata renderer embeds content bytes in the JSON document. If the content type is
text/uri-list, it uses the returned bytes as a locator.
Rules
A field renderer should:
- Return a stable result for the same chain state.
- Handle missing state with a sensible fallback.
- Return the right content type.
- Keep output small enough for a normal
eth_call. - Avoid upgradeable dependencies when the project claims permanence.
A revert or malformed return can break the full tokenURI call. Test unminted IDs, unset parameters,
the collection surface at type(uint256).max, and ordinary token IDs.
Reading parameters
Scalar parameters use:
tokenParam(tokenId, key)
contractParam(key)Read token scope first, then fall back to contract scope. String and Bytes use
tokenParamData and contractParamData; the scalar read contains only their hash.
A Select stores an index. Read its label from selectOption(key, index) rather than copying the
option table into the renderer.
An augment hook does not reach a custom field renderer automatically. The renderer must call the hook or read the same underlying state itself.
Example shape
A small SVG renderer can derive color from a token parameter:
function render(address token, uint256 tokenId, bytes32 field)
external
view
returns (string memory contentType, bytes memory data)
{
if (field != bytes32("image")) {
return ("text/plain", "");
}
string memory color = _palette(token, tokenId);
return (
"image/svg+xml",
abi.encodePacked(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">',
'<rect width="400" height="400" fill="', color, '"/>',
'</svg>'
)
);
}Use the scaffold and test against a local ABX deployment before wiring the address:
abx scaffold renderer --out ./my-rendererLocal preview
forge test checks behavior but does not display the output. The scaffold's
script/Preview.s.sol calls IAbxFieldRenderer.render against mock parameters and writes the result
to preview-out/:
cd my-renderer
forge script script/Preview.s.sol
open preview-out/image.svgEach input has a default and an environment variable override:
PREVIEW_TOKEN_ID=42 PREVIEW_SEED=0x00...abc PREVIEW_PALETTE=0x00...ff3366 forge script script/Preview.s.solThe script reports reverts. Its gas output comes from a local EVM, not the production network. Deploy
and read tokenURI on the target chain for a production measurement.
Wiring and locks
Set a renderer during deployment or later:
abx set-field <contract> --collection --field image --representation renderer --value <renderer-address>
abx set-field <contract> --collection --field attributes --representation renderer --value <renderer-address>Omit --collection and pass --token <id> for one token. The field lock freezes the renderer
address, not code behind it.
For a fully onchain metadata path, also set the contract's metadata renderer and lock URI configuration when ready. Check Metadata before making a permanence claim.