// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.


package signer_registry

var SolidityStandardInput = "{\"version\":\"v0.8.28+commit.7893614a\",\"language\":\"Solidity\",\"settings\":{\"evmVersion\":\"cancun\",\"libraries\":{},\"metadata\":{\"appendCBOR\":true,\"bytecodeHash\":\"none\",\"useLiteralContent\":false},\"optimizer\":{\"enabled\":true,\"runs\":80000},\"outputSelection\":{\"contracts/interfaces/ISignerRegistry.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"contracts/signerRegistry/SignerRegistry.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2Step.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/IOwnable.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\":{\"\":[\"ast\"],\"*\":[\"abi\",\"evm.bytecode.object\",\"evm.bytecode.sourceMap\",\"evm.bytecode.linkReferences\",\"evm.deployedBytecode.object\",\"evm.deployedBytecode.sourceMap\",\"evm.deployedBytecode.linkReferences\",\"evm.deployedBytecode.immutableReferences\",\"evm.methodIdentifiers\",\"metadata\"]}},\"remappings\":[\"forge-std/=node_modules/@chainlink/contracts/src/v0.8/vendor/forge-std/src/\",\"@chainlink/contracts/=node_modules/@chainlink/contracts/\"],\"viaIR\":true},\"sources\":{\"contracts/interfaces/ISignerRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\nimport {IERC165} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\\\";\\n\\n/// @notice Expose a set of unique signers with key rotation support.\\ninterface ISignerRegistry is IERC165 {\\n  /// @notice Each signer always has 2 addresses, evmAddress should always be non-zero, newEVMAddress can be zero.\\n  /// @dev Each signer should sign with evmAddress if newEVMAddress is zero, and with newEVMAddress otherwise.\\n  /// This arrangement solves the challenge of mismatched timing between keys being updated onchain v.s\\n  /// signers rotating keys offchain, and allows for a zero-down-time key rotation.\\n  ///\\n  /// Key rotation workflow:\\n  /// At T0, signer generates a new key offchain, the new key is not set onchain yet.\\n  ///    onchain state: signer = {evmAddress: 0xkey_0, newEVMAddress:0x0}\\n  ///    at this time, signer signs with 0xkey_0, signatures from 0xkey_0 are valid.\\n  ///\\n  /// At T1, the new key is set onchain.\\n  ///    onchain state: signer = {evmAddress: 0xkey_0, newEVMAddress:0xkey_1}\\n  ///    at this time, signer starts signing with 0xkey_1, signatures from 0xkey_0 and 0xkey_1 both are valid.\\n  ///\\n  /// At T2, the new key is promoted to the regular active key.\\n  ///    onchain state: signer = {evmAddress: 0xkey_1, newEVMAddress:0x0}\\n  ///    at this time, signer signs with 0xkey_1, only signatures from 0xkey_1 are valid.\\n  ///\\n  /// Between T1 and T2, the calling contract needs to ensure there is a clear cut-off point where all signatures\\n  /// from 0xkey_0 no longer need to be valid. For example, in a bridging contract that enforces strictly-increasing\\n  /// sequence numbers without gaps, arrival of a new sequence number signed with 0xkey_1 indicates all previous\\n  /// signatures from 0xkey_0 have been consumed, making promotion of 0xkey_1 safe.\\n  struct Signer {\\n    address evmAddress; // Regular active EVM address of the signer.\\n    address newEVMAddress; // Temporary signing address during key rotation.\\n  }\\n\\n  /// @notice Returns the full signer set.\\n  /// @return signers The signer set.\\n  function getSigners() external view returns (Signer[] memory signers);\\n\\n  /// @notice Returns the number of signers in the registry.\\n  /// @return Number of signers.\\n  function getSignerCount() external view returns (uint256);\\n\\n  /// @notice Checks if an address belongs to a current signer.\\n  /// @param signerAddress The address to check.\\n  /// @return True if the address is a signer, false otherwise.\\n  function isSigner(\\n    address signerAddress\\n  ) external view returns (bool);\\n}\\n\"},\"contracts/signerRegistry/SignerRegistry.sol\":{\"content\":\"// SPDX-License-Identifier: BUSL-1.1\\npragma solidity ^0.8.28;\\n\\nimport {ISignerRegistry} from \\\"../interfaces/ISignerRegistry.sol\\\";\\n\\nimport {Ownable2StepMsgSender} from \\\"@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol\\\";\\nimport {ITypeAndVersion} from \\\"@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol\\\";\\n\\nimport {IERC165} from\\n  \\\"@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\\\";\\n\\n/// @notice This is an implementation of ISignerRegistry with blue/green key rotation support.\\n/// @dev This contract enforces 2 invariants:\\n///     1. Every signer's evmAddress is always non-zero, such that it is always associated with at least 1 key.\\n///     2. Every non-zero key is unique\\n/// These 2 invariants combine to ensure a signer can always be uniquely identified by one of its keys.\\n/// Signer's relative index in the signers array is not guaranteed to be stable, its keys will be used as\\n/// the reliable unique identifier.\\ncontract SignerRegistry is ITypeAndVersion, ISignerRegistry, Ownable2StepMsgSender {\\n  error InvalidSignerAddress(address signerAddress);\\n  error DuplicateSigner(address signerAddress);\\n  error InvalidInputLength();\\n  error MissingNewAddress(address signerAddress);\\n  error TooManySigners(uint256 currentSignerCount, uint256 newSignersCount);\\n  error NoMatchingSignerFound(address signerAddress);\\n\\n  event SignerAdded(address indexed evmAddress);\\n  event SignerRemoved(address indexed evmAddress);\\n  event NewSignerAddressSet(address indexed evmAddress, address previousNewEVMAddress, address newEVMAddress);\\n  event SignerAddressPromoted(address indexed evmAddress, address newEVMAddress);\\n  event SignerNotRemovedDueToNoMatch(address signerAddress);\\n\\n  /// @notice The maximum number of signers that can be registered.\\n  /// @dev This serves to cap the length of the signers array, such that callers can invoke `getSigners()`\\n  /// knowing the worst case gas consumption.\\n  uint256 private immutable i_maxSigners;\\n\\n  /// @dev Array of active signers with their rotation state.\\n  Signer[] private s_signers;\\n\\n  /// @notice Initializes the SignerRegistry with an initial set of signers.\\n  /// @param maxSigners The maximum number of signers that can be registered.\\n  /// @param newSigners Initial set of signers to register.\\n  constructor(uint256 maxSigners, Signer[] memory newSigners) {\\n    i_maxSigners = maxSigners;\\n    addSigners(newSigners);\\n  }\\n\\n  string public constant override typeAndVersion = \\\"SignerRegistry 1.0.0\\\";\\n\\n  /// @inheritdoc IERC165\\n  function supportsInterface(\\n    bytes4 interfaceId\\n  ) public pure override returns (bool) {\\n    return interfaceId == type(ISignerRegistry).interfaceId || interfaceId == type(IERC165).interfaceId;\\n  }\\n\\n  /// @inheritdoc ISignerRegistry\\n  function getSigners() external view override returns (Signer[] memory) {\\n    return s_signers;\\n  }\\n\\n  /// @inheritdoc ISignerRegistry\\n  function getSignerCount() external view returns (uint256) {\\n    return s_signers.length;\\n  }\\n\\n  /// @inheritdoc ISignerRegistry\\n  function isSigner(\\n    address signerAddress\\n  ) external view returns (bool) {\\n    return _findSignerIndex(signerAddress) \\u003e= 0;\\n  }\\n\\n  /// @notice Returns the maximum number of signers that can be registered.\\n  /// @return The maximum number of signers.\\n  function getMaxSigners() external view returns (uint256) {\\n    return i_maxSigners;\\n  }\\n\\n  /// @notice Sets new signer addresses during key rotation for specified signers.\\n  /// @param existingSignerAddresses The addresses that are associated with existing signers.\\n  /// @param newSignerAddresses The addresses to use as the newEVMAddresses for given signers.\\n  /// @dev This initiates the blue/green key rotation process, with the following validation cases:\\n  ///     1. Updating newEVMAddress when it is already non-zero is valid in order to rotate to a different key.\\n  ///     2. Setting newEVMAddress to 0 is valid in order to abort a key rotation.\\n  ///     3. Using newEVMAddress to identify an existing signer is valid.\\n  ///     4. newEVMAddress cannot equal pre-existing evmAddress or newEVMAddress even for the same signer, it breaks\\n  ///        the uniqueness invariant, and it is potentially a sign of issue when Signer is rotating to same key.\\n  function setNewSignerAddresses(\\n    address[] calldata existingSignerAddresses,\\n    address[] calldata newSignerAddresses\\n  ) external onlyOwner {\\n    if (existingSignerAddresses.length != newSignerAddresses.length) revert InvalidInputLength();\\n\\n    for (uint256 i = 0; i \\u003c existingSignerAddresses.length; ++i) {\\n      int256 indexInt = _findSignerIndex(existingSignerAddresses[i]);\\n      if (indexInt \\u003c 0) revert NoMatchingSignerFound(existingSignerAddresses[i]);\\n\\n      Signer storage signer = s_signers[uint256(indexInt)];\\n\\n      // Ensure the new key is unique, this also prevents newEVMAddress == evmAddress case.\\n      if (_findSignerIndex(newSignerAddresses[i]) \\u003e= 0) revert DuplicateSigner(newSignerAddresses[i]);\\n\\n      address previousNewEVMAddress = signer.newEVMAddress;\\n      signer.newEVMAddress = newSignerAddresses[i];\\n\\n      emit NewSignerAddressSet(signer.evmAddress, previousNewEVMAddress, newSignerAddresses[i]);\\n    }\\n  }\\n\\n  /// @notice Promotes newEVMAddress to evmAddress for specified signers, completing key rotation.\\n  /// @param existingSignerAddresses The addresses that are associated with existing signers.\\n  function promoteNewSignerAddresses(\\n    address[] calldata existingSignerAddresses\\n  ) external onlyOwner {\\n    for (uint256 i = 0; i \\u003c existingSignerAddresses.length; ++i) {\\n      int256 indexInt = _findSignerIndex(existingSignerAddresses[i]);\\n      if (indexInt \\u003c 0) revert NoMatchingSignerFound(existingSignerAddresses[i]);\\n\\n      Signer storage signer = s_signers[uint256(indexInt)];\\n\\n      if (signer.newEVMAddress == address(0)) revert MissingNewAddress(existingSignerAddresses[i]);\\n\\n      address previousEvmAddress = signer.evmAddress;\\n\\n      signer.evmAddress = signer.newEVMAddress;\\n      signer.newEVMAddress = address(0);\\n\\n      emit SignerAddressPromoted(previousEvmAddress, signer.evmAddress);\\n    }\\n  }\\n\\n  /// @notice Adds new signers to the registry.\\n  /// @param newSigners The new signers to add.\\n  function addSigners(\\n    Signer[] memory newSigners\\n  ) public onlyOwner {\\n    if (newSigners.length + s_signers.length \\u003e i_maxSigners) {\\n      revert TooManySigners(s_signers.length, newSigners.length + s_signers.length);\\n    }\\n\\n    for (uint256 i = 0; i \\u003c newSigners.length; ++i) {\\n      Signer memory signer = newSigners[i];\\n      if (signer.evmAddress == address(0)) revert InvalidSignerAddress(signer.evmAddress);\\n      if (signer.evmAddress == signer.newEVMAddress) revert DuplicateSigner(signer.newEVMAddress);\\n\\n      // Make sure both addresses of the signer are unique.\\n      if (_findSignerIndex(signer.evmAddress) \\u003e= 0) revert DuplicateSigner(signer.evmAddress);\\n      if (_findSignerIndex(signer.newEVMAddress) \\u003e= 0) revert DuplicateSigner(signer.newEVMAddress);\\n\\n      s_signers.push(newSigners[i]);\\n      emit SignerAdded(newSigners[i].evmAddress);\\n    }\\n  }\\n\\n  /// @notice Removes signers from the registry.\\n  /// @param signersToRemove The addresses that uniquely identify existing signers that should be removed.\\n  function removeSigners(\\n    address[] calldata signersToRemove\\n  ) external onlyOwner {\\n    for (uint256 i = 0; i \\u003c signersToRemove.length; ++i) {\\n      int256 indexInt = _findSignerIndex(signersToRemove[i]);\\n      // If the signer is not found, no-op, skip it.\\n      if (indexInt \\u003c 0) {\\n        emit SignerNotRemovedDueToNoMatch(signersToRemove[i]);\\n        continue;\\n      }\\n\\n      uint256 index = uint256(indexInt);\\n\\n      // Replace with last element if not already the last\\n      if (index != s_signers.length - 1) {\\n        s_signers[index] = s_signers[s_signers.length - 1];\\n      }\\n      s_signers.pop();\\n\\n      emit SignerRemoved(signersToRemove[i]);\\n    }\\n  }\\n\\n  /// @notice Finds the index of a signer in the registry.\\n  /// @param signerAddress The address of the signer to find.\\n  /// @return The index of the signer, or -1 if not found.\\n  function _findSignerIndex(\\n    address signerAddress\\n  ) internal view returns (int256) {\\n    if (signerAddress == address(0)) return -1;\\n\\n    for (uint256 i = 0; i \\u003c s_signers.length; ++i) {\\n      if (s_signers[i].evmAddress == signerAddress || s_signers[i].newEVMAddress == signerAddress) {\\n        // Safe to cast to int256, it is impractical for signers length to exceed int256 range.\\n        return int256(i);\\n      }\\n    }\\n    return -1;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2Step.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {IOwnable} from \\\"../interfaces/IOwnable.sol\\\";\\n\\n/// @notice A minimal contract that implements 2-step ownership transfer and nothing more. It's made to be minimal\\n/// to reduce the impact of the bytecode size on any contract that inherits from it.\\ncontract Ownable2Step is IOwnable {\\n  /// @notice The pending owner is the address to which ownership may be transferred.\\n  address private s_pendingOwner;\\n  /// @notice The owner is the current owner of the contract.\\n  /// @dev The owner is the second storage variable so any implementing contract could pack other state with it\\n  /// instead of the much less used s_pendingOwner.\\n  address private s_owner;\\n\\n  error OwnerCannotBeZero();\\n  error MustBeProposedOwner();\\n  error CannotTransferToSelf();\\n  error OnlyCallableByOwner();\\n\\n  event OwnershipTransferRequested(address indexed from, address indexed to);\\n  event OwnershipTransferred(address indexed from, address indexed to);\\n\\n  constructor(address newOwner, address pendingOwner) {\\n    if (newOwner == address(0)) {\\n      revert OwnerCannotBeZero();\\n    }\\n\\n    s_owner = newOwner;\\n    if (pendingOwner != address(0)) {\\n      _transferOwnership(pendingOwner);\\n    }\\n  }\\n\\n  /// @notice Get the current owner\\n  function owner() public view override returns (address) {\\n    return s_owner;\\n  }\\n\\n  /// @notice Allows an owner to begin transferring ownership to a new address. The new owner needs to call\\n  /// `acceptOwnership` to accept the transfer before any permissions are changed.\\n  /// @param to The address to which ownership will be transferred.\\n  function transferOwnership(address to) public override onlyOwner {\\n    _transferOwnership(to);\\n  }\\n\\n  /// @notice validate, transfer ownership, and emit relevant events\\n  /// @param to The address to which ownership will be transferred.\\n  function _transferOwnership(address to) private {\\n    if (to == msg.sender) {\\n      revert CannotTransferToSelf();\\n    }\\n\\n    s_pendingOwner = to;\\n\\n    emit OwnershipTransferRequested(s_owner, to);\\n  }\\n\\n  /// @notice Allows an ownership transfer to be completed by the recipient.\\n  function acceptOwnership() external override {\\n    if (msg.sender != s_pendingOwner) {\\n      revert MustBeProposedOwner();\\n    }\\n\\n    address oldOwner = s_owner;\\n    s_owner = msg.sender;\\n    s_pendingOwner = address(0);\\n\\n    emit OwnershipTransferred(oldOwner, msg.sender);\\n  }\\n\\n  /// @notice validate access\\n  function _validateOwnership() internal view {\\n    if (msg.sender != s_owner) {\\n      revert OnlyCallableByOwner();\\n    }\\n  }\\n\\n  /// @notice Reverts if called by anyone other than the contract owner.\\n  modifier onlyOwner() {\\n    _validateOwnership();\\n    _;\\n  }\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/access/Ownable2StepMsgSender.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.4;\\n\\nimport {Ownable2Step} from \\\"./Ownable2Step.sol\\\";\\n\\n/// @notice Sets the msg.sender to be the owner of the contract and does not set a pending owner.\\ncontract Ownable2StepMsgSender is Ownable2Step {\\n  constructor() Ownable2Step(msg.sender, address(0)) {}\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/IOwnable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface IOwnable {\\n  function owner() external returns (address);\\n\\n  function transferOwnership(address recipient) external;\\n\\n  function acceptOwnership() external;\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/shared/interfaces/ITypeAndVersion.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity ^0.8.0;\\n\\ninterface ITypeAndVersion {\\n  function typeAndVersion() external pure returns (string memory);\\n}\\n\"},\"node_modules/@chainlink/contracts/src/v0.8/vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC165 standard, as defined in the\\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\\n *\\n * Implementers can declare support of contract interfaces, which can then be\\n * queried by others ({ERC165Checker}).\\n *\\n * For an implementation, see {ERC165}.\\n */\\ninterface IERC165 {\\n    /**\\n     * @dev Returns true if this contract implements the interface defined by\\n     * `interfaceId`. See the corresponding\\n     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\\n     * to learn more about how these ids are created.\\n     *\\n     * This function call must use less than 30 000 gas.\\n     */\\n    function supportsInterface(bytes4 interfaceId) external view returns (bool);\\n}\\n\"}}}"
