TESTNET ONLINE: PECORINO PECORINO

Transactor Integration Guide

The Transactor contract creates transactions on Signet from Ethereum. Transactions made via the Transactor always execute on Signet at the end of the current block, bypassing any possibility of builder censorship.

Consult the Pecorino Quickstart guide for contract addresses and RPC endpoints.

Setup

  • The Transactor ABI can be downloaded here: Transactor ABI.
    • $ curl -O https://signet.sh/docs/abis/Transactor.abi.json
  • The Transactor Contract is also open source.
    • $ forge install https://github.com/init4tech/zenith
  • Rust alloy bindings are available via the signet-bindings crate.
    • $ cargo add signet-bindings

Overview

Transactor.sol exposes a basic EVM transaction as a single function:

1function transact(
2    address to,
3    bytes calldata data,
4    uint256 value,
5    uint256 gas,
6    uint256 maxFeePerGas
7) external payable

Calling the transact function results in a system transaction being issued on Signet from the address of the caller. This allows Ethereum contracts to own assets on Signet, and to trigger contract execution on Signet from Ethereum with native authentication.

The value field is the amount of ETH in wei to send on the rollup. The msg.value of the transact call will be bridged to Signet, and could be more or less than value. I.e. the call transactor.transact{value: 5 ether}(.., 1 ether, ...) will send 5 ETH to Signet, but only 1 ETH will be used to invoke the to address.

Transactions are executed at the end of the Signet block. Contract creation via Transactor is not currently supported.

The Transactor emits a Transact event that can be monitored. The Signet node listens for these events directly, so if the event fired, the transaction was included in Signet (although it may revert or be dropped by the Signet Orders system).

When to Use Transactor

Use Transactor when:

  • You need guaranteed transaction inclusion
  • You want to trigger Signet actions from Ethereum
  • You’re building cross-chain workflows
  • You need censorship resistance

Don’t use Transactor when:

  • You’re just moving assets (use Passage instead)
  • Gas cost is a primary concern (direct Signet txs are cheaper)
  • You don’t need L1-triggered execution

Code Examples

Solidity

 1contract YourContract {
 2    Transactor public transactor;
 3
 4    constructor(Transactor _transactor) {
 5        transactor = _transactor;
 6    }
 7
 8    // Execute a function on Signet from Ethereum
 9    function executeOnSignet(
10        address signetTarget,
11        bytes calldata functionData
12    ) external {
13        transactor.transact(
14            signetTarget,
15            functionData,
16            0, // value on Signet
17            1_000_000, // gas limit on Signet
18            100 gwei // max fee per gas on Signet
19        );
20    }
21
22    // Emergency action on Signet
23    function emergencyAction(address signetContract) external onlyOwner {
24        // Encode the emergency function call
25        bytes memory data = abi.encodeWithSignature("emergencyPause()");
26        executeOnSignet(signetContract, data);
27    }
28}

Monitoring Transactor Activity in JavaScript/TypeScript

Listen for Transactor events to track Host-driven transactions:

 1import { ethers } from "ethers";
 2
 3const provider = new ethers.JsonRpcProvider("https://eth.llamarpc.com");
 4const transactor = new ethers.Contract(
 5  TRANSACTOR_ADDRESS,
 6  TRANSACTOR_ABI, // Get ABI from contract source
 7  provider
 8);
 9
10// Listen for Host-driven transactions
11// Event name and signature from Transactor.sol
12transactor.on("Transact", (...args) => {
13  console.log("Host-driven execution:", args);
14
15  // Decode the calldata if needed
16  const [from, to, data] = args; // Adjust based on actual event
17  console.log(`${from} Host-driven execution on ${to}`);
18});