l1_handler
fn new(target: ContractAddress, selector: felt252) -> L1Handler
Returns an L1Handler
structure which can be used to mock sending messages from L1 for the contract to handle in function marked with #[l1_handler]
.
#[derive(Drop, Clone)]
pub struct L1Handler {
target: ContractAddress,
selector: felt252,
}
fn execute(self: L1Handler) -> SyscallResult<()>
Mocks an L1 -> L2 message from Ethereum handled by the given L1 handler function.
Example
Let's consider a very simple contract, which receives an L1 message with an array of numbers them:
#[starknet::contract]
mod L1HandlerExample {
#[storage]
struct Storage {}
#[l1_handler]
fn handle_l1_message(ref self: ContractState, from_address: felt252, numbers: Array<felt252>) {
assert!(from_address == 0x123456789012345678901234567890123456789, "Unexpected address");
assert!(numbers.len() == 3, "Expected exactly 3 numbers");
}
}
Test code:
use snforge_std::cheatcodes::contract_class::DeclareResultTrait;
use snforge_std::{ContractClassTrait, L1HandlerTrait, declare};
#[test]
fn test_l1_handler() {
// 1. Declare and deploy the Starknet contract
let example_contract = declare("L1HandlerExample").unwrap().contract_class();
let (contract_address, _) = example_contract.deploy(@array![]).unwrap();
// 2. Define the L1 handler to be called
let l1_handler = L1HandlerTrait::new(contract_address, selector!("handle_l1_message"));
// 3. Define Ethereum address of the message sender
let eth_address = 0x123456789012345678901234567890123456789;
// 4. The payload to be sent to the L1 handler
let payload = array![1, 2, 3];
let mut serialized_payload = array![];
payload.serialize(ref serialized_payload);
// 5. Execute the L1 handler with the Ethereum address and payload
// This will trigger the `handle_l1_message` function of the contract
l1_handler.execute(eth_address, serialized_payload.span()).unwrap();
}
Let's run the test:
$ snforge test test_l1_handler
Output:
Collected 1 test(s) from cheatcodes_reference package
Running 1 test(s) from tests/
[PASS] cheatcodes_reference_integrationtest::test_l1_handler::test_l1_handler ([..])
Running 0 test(s) from src/
Tests: 1 passed, 0 failed, 0 ignored, [..] filtered out