Extensions

Currently, enabling an extension requires writing and deploying a customized smart contract with the desired extension functions and logic using a Solidity IDE like remix. Once deployed, the contract can be registered to a base Creator Core contract using the registerExtension function.

Writing Extensions

Any contract written in solidity on the Ethereum network can be registered as an extension to a base Creator Contract. The extension will only be recognized by your Creator Contract for the purpose of overriding various functions by implementing specific interfaces.

Override TokenURI Functionality

To override Token URI functionality implement interface ICreatorExtensionTokenURI. This is applicable to both ERC721 and ERC1155 contracts:

interface ICreatorExtensionTokenURI is IERC165 {
    /**
     * Get the uri for a given creator/tokenId
     */
    function tokenURI(address creator, uint256 tokenId) external view returns (string memory);
}

If you intend on using this functionality DO NOT pass in URI or baseURI values when you call mintExtension functions on the Creator Core contracts. Doing so will cause the Creator Core contracts to ignore the overridden tokenURI logic.

Receive a Burn Callback

To receive an onBurn callback (pre-burn hook) whenever a token the extension created is burned implement either the IERC721CreatorExtensionBurnable or IERC1155CreatorExtensionBurnable interface. Whenever a token created by the extension is burned using the Creator Core's burn function, this hook will fire.

ERC721

interface IERC721CreatorExtensionBurnable is IERC165 {
    /**
     * @dev callback handler for burn events
     */
    function onBurn(address owner, uint256 tokenId) external;
}

ERC1155

interface IERC1155CreatorExtensionBurnable is IERC165 {
    /**
     * @dev callback handler for burn events
     */
    function onBurn(address owner, uint256[] calldata tokenIds, uint256[] calldata amounts) external;
}

Receive a Transfer Callback

To receive a transfer callback (pre-transfer hook) whenever a token the extension created is transferred implement either the IERC721CreatorExtensionApproveTransfer or IERC1155CreatorExtensionApproveTransfer interface. Whenever a token created by the extension is transferred using the Creator Core's transfer function this hook will fire.

If your extension has implemented the Transfer Callback interface, it will automatically be enabled once the extension is installed. You can disable the callback by having the extension call setApproveTransferExtenstion(false). See the suggested implementation below the CreatorExtensionApproveTransfer interfaces.

ERC721

interface IERC721CreatorExtensionApproveTransfer is IERC165 {

    /**
     * @dev Set whether or not the creator will check the extension for approval of token transfer
     */
    function setApproveTransfer(address creator, bool enabled) external;

    /**
     * @dev Called by creator contract to approve a transfer
     */
    function approveTransfer(address operator, address from, address to, uint256 tokenId) external returns (bool);
}

ERC1155

interface IERC1155CreatorExtensionApproveTransfer is IERC165 {

    /**
     * @dev Set whether or not the creator contract will check the extension for approval of token transfer
     */
    function setApproveTransfer(address creator, bool enabled) external;

    /**
     * @dev Called by creator contract to approve a transfer
     */
    function approveTransfer(address operator, address from, address to, uint256[] calldata tokenIds, uint256[] calldata amounts) external returns (bool);
}

Suggested implementation for extensions with a transfer callback

abstract contract ERC1155CreatorExtensionApproveTransfer is AdminControl, IERC1155CreatorExtensionApproveTransfer {

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(AdminControl, IERC165) returns (bool) {
        return interfaceId == type(IERC1155CreatorExtensionApproveTransfer).interfaceId
            || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC1155CreatorExtensionApproveTransfer-setApproveTransfer}
     */
    function setApproveTransfer(address creator, bool enabled) external override adminRequired {
        require(ERC165Checker.supportsInterface(creator, type(IERC1155CreatorCore).interfaceId), "creator must implement IERC1155CreatorCore");
        IERC1155CreatorCore(creator).setApproveTransferExtension(enabled);
    }

}

Overriding Royalties

To override Token URI functionality implement interface ICreatorExtensionRoyalties. This is applicable to both ERC721 and ERC1155 contracts:

interface ICreatorExtensionRoyalties is IERC165 {

    /**
     * Get the royalties for a given creator/tokenId
     */
    function getRoyalties(address creator, uint256 tokenId) external view returns (address payable[] memory, uint256[] memory);
}

Adding and Removing Extensions

Once deployed on the Ethereum network, extensions can be added or removed using the registerExtension and unregisterExtension functions. An extension can also be blacklisted via the blacklistExtension function, preventing future registrations of the address and destroying all references to metadata associate with tokens created by the extension.

For detailed extensions functions information see Extensions Functions.

Depending on how they've been written, some extensions may require configuration before registration (e.g. setting a token range or other piece of data). If you've incorporate custom interfaces that need configuration, be sure to do this before registration.

Last updated