Skip to content
Lattice

IStarknetGatewayAdapter

Git Source

Title: IStarknetGatewayAdapter

Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Modified from Starknet (https://github.com/starkware-libs/cairo-lang)

Surface of the L1-side (Ethereum-only) Starknet L1 <-> L2 connector: fee-escrowed outbound sendMessage toward an ERC-7930 Starknet (felt252) recipient, initiator-gated two-step cancellation, and a permissionless keeper-driven inbound consumeMessage pull.

DELIBERATELY BESPOKE, not an IERC7786GatewaySource: ERC-7786's sendMessage returns a sendId for a symmetric receive-side dedup that does not exist here (the inbound path is a PULL-based consume against a core-side COUNTER, not a pushed message with an id), ERC-7786 attributes cannot express the escrowed non-refundable fee + the two-step cancellation lifecycle, and the Starknet wire payload is a felt252 array, not opaque bytes. It is never routed through OpenBridge / CrosschainLink.

WIRE FORMAT (Lattice felt-chunk convention v1 — the Cairo l1_handler must mirror it): felts[0] = payload byte count; felts[1..] = consecutive 31-byte big-endian chunks of the payload, the last chunk right-padded with zeros. Each chunk is &lt; 2**248 &lt; FIELD_PRIME by construction.

FEE WARNING: the L1 -> L2 message fee (msg.value) is escrowed by the Starknet core and NEVER refunded — not even when the message is cancelled.

Functions

starknetCore

The Starknet core (StarknetMessaging) contract on this chain.

function starknetCore() external view returns (address);

Returns

NameTypeDescription
<none>address

expectedChainReference

The ERC-7930 chain reference this adapter accepts (UTF-8 chain-id string, e.g. SN_MAIN).

function expectedChainReference() external view returns (bytes memory);

Returns

NameTypeDescription
<none>bytes

l1HandlerSelector

The registered l1_handler selector for l2Target (0 = unregistered).

function l1HandlerSelector(uint256 l2Target) external view returns (uint256);

Parameters

NameTypeDescription
l2Targetuint256

Returns

NameTypeDescription
<none>uint256

isTrustedL2Sender

Whether fromAddress is a trusted L2 sender for the inbound consume path.

function isTrustedL2Sender(uint256 fromAddress) external view returns (bool);

Parameters

NameTypeDescription
fromAddressuint256

Returns

NameTypeDescription
<none>bool

initiatorOf

The initiator recorded for an in-flight outbound message (address(0) = unknown/cancelled).

function initiatorOf(bytes32 msgHash) external view returns (address);

Parameters

NameTypeDescription
msgHashbytes32

Returns

NameTypeDescription
<none>address

starknetSelector

Computes the Starknet selector (starknet_keccak) of an l1_handler entry-point name: uint256(keccak256(bytes(name))) & ((1 &lt;&lt; 250) - 1) (keccak256 masked to its low 250 bits).

Convenience for admins registering handlers — selectors CANNOT be derived from the ERC-7930 address, they are a property of the target contract's Cairo code.

function starknetSelector(string calldata name) external pure returns (uint256);

Parameters

NameTypeDescription
namestring

Returns

NameTypeDescription
<none>uint256

registerL2Handler

Registers the l1_handler selector to invoke when sending to l2Target. Both values must be non-zero felt252s. Admin only.

function registerL2Handler(uint256 l2Target, uint256 selector) external;

Parameters

NameTypeDescription
l2Targetuint256
selectoruint256

setTrustedL2Sender

Sets the trusted flag of the L2 sender fromAddress (a non-zero felt252) for the inbound consume path. Admin only.

function setTrustedL2Sender(uint256 fromAddress, bool trusted) external;

Parameters

NameTypeDescription
fromAddressuint256
trustedbool

sendMessage

Sends payload (felt-chunk encoded) to the ERC-7930 Starknet recipient's registered l1_handler, escrowing msg.value as the message fee.

The fee is escrowed by the Starknet core and NEVER refunded — cancellation included. The caller is recorded as the message's initiator and is the only party able to cancel it.

function sendMessage(bytes calldata recipient, bytes calldata payload)
        external
        payable
        returns (bytes32 msgHash, uint256 nonce);

Parameters

NameTypeDescription
recipientbytesThe ERC-7930 interoperable recipient (starknet chainType + chain reference + felt252).
payloadbytesThe raw bytes payload (encoded per the felt-chunk convention v1 on the wire).

Returns

NameTypeDescription
msgHashbytes32The core-computed message hash.
nonceuint256The core-minted message nonce (keep it — cancellation needs it).

startCancellation

Starts the two-step cancellation of a previously sent message, re-derived from the ORIGINAL recipient/selector/payload/nonce. Initiator only.

selector is the SEND-TIME l1_handler selector (emitted in StarknetMessageSent) — passed explicitly and NOT re-read from the mutable handler registry, so an admin re-registering the target's selector while the message is in flight cannot lock the initiator out of cancelling. The core enforces a messageCancellationDelay() wait between this call and cancel.

function startCancellation(bytes calldata recipient, uint256 selector, bytes calldata payload, uint256 nonce)
        external
        returns (bytes32 msgHash);

Parameters

NameTypeDescription
recipientbytes
selectoruint256
payloadbytes
nonceuint256

Returns

NameTypeDescription
msgHashbytes32

cancel

Completes the cancellation started by startCancellation (same arguments), at least messageCancellationDelay() seconds later. Initiator only. The escrowed fee is NOT refunded.

function cancel(bytes calldata recipient, uint256 selector, bytes calldata payload, uint256 nonce)
        external
        returns (bytes32 msgHash);

Parameters

NameTypeDescription
recipientbytes
selectoruint256
payloadbytes
nonceuint256

Returns

NameTypeDescription
msgHashbytes32

consumeMessage

Permissionless keeper-driven pull: consumes an L2 -> L1 message from the trusted L2 sender fromAddress addressed to this diamond, and emits it. Emit-only in v1.

The core is the real authenticator (it only consumes messages addressed to msg.sender — the diamond — and reverts when the message counter is zero). Counter semantics: duplicates are N DISTINCT consumes, not replays — consuming the same message twice requires the L2 to have SENT it twice. NOT routed into CrosschainLink / OpenBridge.

function consumeMessage(uint256 fromAddress, bytes calldata payload) external returns (bytes32 msgHash);

Parameters

NameTypeDescription
fromAddressuint256
payloadbytes

Returns

NameTypeDescription
msgHashbytes32

Events

StarknetMessageSent

Emitted when an L1 -> L2 message is sent to the Starknet core.

event StarknetMessageSent(
        address indexed initiator,
        uint256 indexed toAddress,
        uint256 selector,
        bytes32 msgHash,
        uint256 nonce,
        uint256 fee,
        bytes payload
    );

Parameters

NameTypeDescription
initiatoraddressThe L1 caller recorded as the only party allowed to cancel this message.
toAddressuint256The L2 target contract (felt252).
selectoruint256The registered l1_handler selector invoked on the target.
msgHashbytes32The core-computed message hash.
nonceuint256The core-minted message nonce (needed for cancellation).
feeuint256The escrowed, NON-REFUNDABLE message fee (wei).
payloadbytesThe raw bytes payload (pre felt-chunk encoding).

StarknetCancellationStarted

Emitted when a two-step cancellation is started for msgHash by its initiator.

event StarknetCancellationStarted(address indexed initiator, bytes32 indexed msgHash, uint256 nonce);

Parameters

NameTypeDescription
initiatoraddress
msgHashbytes32
nonceuint256

StarknetMessageCancelled

Emitted when msgHash is cancelled by its initiator (the escrowed fee is NOT refunded).

event StarknetMessageCancelled(address indexed initiator, bytes32 indexed msgHash, uint256 nonce);

Parameters

NameTypeDescription
initiatoraddress
msgHashbytes32
nonceuint256

StarknetMessageConsumed

Emitted when an L2 -> L1 message from fromAddress is consumed from the core.

event StarknetMessageConsumed(uint256 indexed fromAddress, bytes32 msgHash, bytes payload);

Parameters

NameTypeDescription
fromAddressuint256
msgHashbytes32
payloadbytes

RegisteredL2Handler

Emitted when an L2 target's l1_handler selector is registered.

event RegisteredL2Handler(uint256 indexed l2Target, uint256 selector);

Parameters

NameTypeDescription
l2Targetuint256
selectoruint256

SetTrustedL2Sender

Emitted when an L2 sender's trusted flag is set for the inbound consume path.

event SetTrustedL2Sender(uint256 indexed fromAddress, bool trusted);

Parameters

NameTypeDescription
fromAddressuint256
trustedbool

Errors

StarknetZeroAddress

The Starknet core address was zero at init.

error StarknetZeroAddress();

StarknetEmptyChainReference

The expected chain reference was empty at init.

error StarknetEmptyChainReference();

StarknetWrongChainType

The ERC-7930 recipient's chainType is not the starknet ChainType key (0x0003).

error StarknetWrongChainType(bytes2 chainType);

Parameters

NameTypeDescription
chainTypebytes2

StarknetChainReferenceMismatch

The ERC-7930 recipient's chain reference does not match this adapter's configured Starknet chain (e.g. SN_GOERLI recipient on an SN_MAIN adapter) — fail-closed.

error StarknetChainReferenceMismatch();

StarknetTargetNotRegistered

No l1_handler selector is registered for the L2 target decoded from the recipient.

error StarknetTargetNotRegistered(uint256 toAddress);

Parameters

NameTypeDescription
toAddressuint256

StarknetZeroFee

sendMessage was called with zero msg.value (the core requires a non-zero fee).

error StarknetZeroFee();

StarknetNotInitiator

The caller is not the recorded initiator of the message being cancelled.

error StarknetNotInitiator(bytes32 msgHash, address caller);

Parameters

NameTypeDescription
msgHashbytes32
calleraddress

StarknetUntrustedSender

The inbound L2 sender is not on the trusted-senders allow-list.

error StarknetUntrustedSender(uint256 fromAddress);

Parameters

NameTypeDescription
fromAddressuint256

StarknetNotAFelt

An admin-supplied value is not a valid non-zero felt252 (0 &lt; value &lt; FIELD_PRIME).

error StarknetNotAFelt(uint256 value);

Parameters

NameTypeDescription
valueuint256

StarknetMalformedFeltPayload

A felt array does not follow the Lattice felt-chunk convention v1 (bad length prefix, chunk >= 2**248, or non-zero padding in the final chunk).

error StarknetMalformedFeltPayload();