contract WizardGuildInterface is IERC721, WizardGuildInterfaceId {

    /// @notice Returns the information associated with the given Wizard
    ///         owner - The address that owns this Wizard
    ///         innatePower - The innate power level of this Wizard, set when minted and entirely
    ///               immutable
    ///         affinity - The Elemental Affinity of this Wizard. For most Wizards, this is set
    ///               when they are minted, but some exclusive Wizards are minted with an affinity
    ///               of 0 (ELEMENT_NOTSET). A Wizard with an NOTSET affinity should NOT be able
    ///               to participate in Tournaments. Once the affinity of a Wizard is set to a non-zero
    ///               value, it can never be changed again.
    ///         metadata - A 256-bit hash of the Wizard's metadata, which is stored off chain. This
    ///               contract doesn't specify format of this hash, nor the off-chain storage mechanism
    ///               but, let's be honest, it's probably an IPFS SHA-256 hash.
    ///
    ///         NOTE: Series zero Wizards have one of four Affinities:  Neutral (1), Fire (2), Water (3)
    ///               or Air (4, sometimes called "Wind" in the code). Future Wizard Series may have
    ///               additional Affinities, and clients of this API should be prepared for that
    ///               eventuality.
    function getWizard(uint256 id) external view returns (address owner, uint88 innatePower, uint8 affinity, bytes32 metadata);

    /// @notice Sets the affinity for a Wizard that doesn't already have its elemental affinity chosen.
    ///         Only usable for Exclusive Wizards (all non-Exclusives must have their affinity chosen when
    ///         conjured.) Even Exclusives can't change their affinity once it's been chosen.
    ///
    ///         NOTE: This function can only be called by the series minter, and (therefore) only while the
    ///         series is open. A Wizard that has no affinity when a series is closed will NEVER have an Affinity.
    ///         BTW- This implies that a minter is responsible for either never minting ELEMENT_NOTSET
    ///         Wizards, or having some public mechanism for a Wizard owner to set the Affinity after minting.
    /// @param wizardId The id of the wizard
    /// @param newAffinity The new affinity of the wizard
    function setAffinity(uint256 wizardId, uint8 newAffinity) external;

    /// @notice A function to be called that conjures a whole bunch of Wizards at once! You know how
    ///         there's "a pride of lions", "a murder of crows", and "a parliament of owls"? Well, with this
    ///         here function you can conjure yourself "a stench of Cheeze Wizards"!
    ///
    ///         Unsurprisingly, this method can only be called by the registered minter for a Series.
    /// @param powers the power level of each wizard
    /// @param affinities the Elements of the wizards to create
    /// @param owner the address that will own the newly created Wizards
    function mintWizards(
        uint88[] calldata powers,
        uint8[] calldata affinities,
        address owner
        ) external returns (uint256[] memory wizardIds);

    /// @notice A function to be called that conjures a series of Wizards in the reserved ID range.
    /// @param wizardIds the ID values to use for each Wizard, must be in the reserved range of the current Series
    /// @param affinities the Elements of the wizards to create
    /// @param powers the power level of each wizard
    /// @param owner the address that will own the newly created Wizards
    function mintReservedWizards(
        uint256[] calldata wizardIds,
        uint88[] calldata powers,
        uint8[] calldata affinities,
        address owner
        ) external;

    /// @notice Sets the metadata values for a list of Wizards. The metadata for a Wizard can only be set once,
    ///         can only be set by the COO or Minter, and can only be set while the Series is still open. Once
    ///         a Series is closed, the metadata is locked forever!
    /// @param wizardIds the ID values of the Wizards to apply metadata changes to.
    /// @param metadata the raw metadata values for each Wizard. This contract does not define how metadata
    ///         should be interpreted, but it is likely to be a 256-bit hash of a complete metadata package
    ///         accessible via IPFS or similar.
    function setMetadata(uint256[] calldata wizardIds, bytes32[] calldata metadata) external;

    /// @notice Returns true if the given "spender" address is allowed to manipulate the given token
    ///         (either because it is the owner of that token, has been given approval to manage that token)
    function isApprovedOrOwner(address spender, uint256 tokenId) external view returns (bool);

    /// @notice Verifies that a given signature represents authority to control the given Wizard ID,
    ///         reverting otherwise. It handles three cases:
    ///             - The simplest case: The signature was signed with the private key associated with
    ///               an external address that is the owner of this Wizard.
    ///             - The signature was generated with the private key associated with an external address
    ///               that is "approved" for working with this Wizard ID. (See the Wizard Guild and/or
    ///               the ERC-721 spec for more information on "approval".)
    ///             - The owner or approval address (as in cases one or two) is a smart contract
    ///               that conforms to ERC-1654, and accepts the given signature as being valid
    ///               using its own internal logic.
    ///
    ///        NOTE: This function DOES NOT accept a signature created by an address that was given "operator
    ///               status" (as granted by ERC-721's setApprovalForAll() functionality). Doing so is
    ///               considered an extreme edge case that can be worked around where necessary.
    /// @param wizardId The Wizard ID whose control is in question
    /// @param hash The message hash we are authenticating against
    /// @param sig the signature data; can be longer than 65 bytes for ERC-1654
    function verifySignature(uint256 wizardId, bytes32 hash, bytes calldata sig) external view;

    /// @notice Convenience function that verifies signatures for two wizards using equivalent logic to
    ///         verifySignature(). Included to save on cross-contract calls in the common case where we
    ///         are verifying the signatures of two Wizards who wish to enter into a Duel.
    /// @param wizardId1 The first Wizard ID whose control is in question
    /// @param wizardId2 The second Wizard ID whose control is in question
    /// @param hash1 The message hash we are authenticating against for the first Wizard
    /// @param hash2 The message hash we are authenticating against for the first Wizard
    /// @param sig1 the signature data corresponding to the first Wizard; can be longer than 65 bytes for ERC-1654
    /// @param sig2 the signature data corresponding to the second Wizard; can be longer than 65 bytes for ERC-1654
    function verifySignatures(
        uint256 wizardId1,
        uint256 wizardId2,
        bytes32 hash1,
        bytes32 hash2,
        bytes calldata sig1,
        bytes calldata sig2) external view;
}
/// @title The public interface of the Wizard Guild
/// @notice The methods listed in this interface (including the inherited ERC-721 interface),
///         make up the public interface of the Wizard Guild contract. Any contracts that wish
///         to make use of Cheeze Wizard NFTs (such as Cheeze Wizards Tournaments!) should use
///         these methods to ensure they are working correctly with the base NFTs.
function mintReservedWizards(
    uint256[] calldata wizardIds,
    uint88[] calldata powers,
    uint8[] calldata affinities,
    address owner
    ) external;

/// @notice A function to be called that conjures a series of Wizards in the reserved ID range.
/// @param wizardIds the ID values to use for each Wizard, must be in the reserved range of the current Series
/// @param affinities the Elements of the wizards to create
/// @param powers the power level of each wizard
/// @param owner the address that will own the newly created Wizards