Last active
June 4, 2025 23:49
-
-
Save tynes/0f565318646292d22b20bf425fbcfa85 to your computer and use it in GitHub Desktop.
Ithaca Account OP Stack Interop Signer Auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.23; | |
import {IIthacaAccount} from "./interfaces/IIthacaAccount.sol"; | |
import {ISigner} from "./interfaces/ISigner.sol"; | |
struct Identifier { | |
address origin; | |
uint256 blockNumber; | |
uint256 logIndex; | |
uint256 timestamp; | |
uint256 chainId; | |
} | |
interface ICrossL2Inbox { | |
function validateMessage(Identifier calldata _id, bytes32 _msgHash) external; | |
} | |
// most simple implementation, requires a change to IthacaAccount | |
contract InteropSigner is ISigner { | |
address internal constant CROSS_L2_INBOX = 0x4200000000000000000000000000000000000022; | |
bytes4 internal constant _MAGIC_VALUE = 0x8afc93b4; | |
// this is static called by the IthacaAccount but interop validation uses LOG opcode | |
// if updated to use call, this should work, but need to not double hash digest with sha2 | |
function isValidSignatureWithKeyHash(bytes32 digest, bytes32, bytes memory signature) | |
public | |
returns (bytes4 magicValue) | |
{ | |
Identifier memory id = abi.decode(signature, (Identifier)); | |
// | |
ICrossL2Inbox(CROSS_L2_INBOX).validateMessage(id, digest); | |
return _MAGIC_VALUE; | |
} | |
} | |
// If there is no desire to change the static call into a call, we can do an alternative approach | |
// 1. user calls `validateMessage`, stores the hash after its been validated | |
// 2. IthacaAccount calls `isValidSignatureWithKeyHash` | |
contract InteropSigner is ISigner { | |
bytes4 internal constant _MAGIC_VALUE = 0x8afc93b4; | |
bytes4 internal constant _FAIL_VALUE = 0xffffffff; | |
mapping(bytes32 => bool) valid; | |
function validateMessage(Identifier calldata _id, bytes32 _msgHash) external { | |
ICrossL2Inbox(CROSS_L2_INBOX).validateMessage(_id, _msgHash); | |
valid[_msgHash] = true; | |
} | |
// not exactly sure how to do replay protection | |
function isValidSignatureWithKeyHash(bytes32 digest, bytes32, bytes memory signature) | |
public | |
view | |
returns (bytes4 magicValue) | |
{ | |
if (valid[_msgHash]) return _MAGIC_VALUE; | |
return _FAIL_VALUE; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment