Skip to main content

Documentation/Build on Signet/To Ethereum

Off-chain Orders in Rust

Create Signet Orders in Rust

This page will walk you through creating and submitting off-chain Orders using Rust and the Signet SDK.

The Orders contract enables trustless, cross-chain asset swaps between Signet and Ethereum. Signet nodes listen for Order and Filled events, and ensure that all transactions that emit Orders have corresponding Fills executed on the destination chain in the same block.

Order events are emitted on Signet, while Filled events may be emitted on either Ethereum or Signet. Off-chain orders are pre-signed, using Permit2, and may be executed by a third-party filler, allowing users to perform gasless swaps.

Setup

Install the required Signet crates

bash
cargo add signet-zenith
cargo add signet-constants
cargo add signet-types
cargo add signet-tx-cache

Ensure your account has approved Permit2 to spend your input tokens.

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

Creating an Order

The signet-types crate provides a simple order builder via the UnsignedOrder struct, which can be used to build orders. We can start by creating a simple order that swaps 1 WETH on Signet for 1 WETH on Ethereum:

rust
use signet_types::signing::order::{UnsignedOrder};
use signet_constants::parmigiana as constants;

let mut order = UnsignedOrder::default()
    .with_input(
        constants::RU_WETH,
        U256::from(1e18), // 1 WETH
    ).with_output(
        constants::HOST_WETH,
        U256::from(1e18),
        your_address,
        1, // Ethereum mainnet
    );

The UnsignedOrder struct also provides methods to sign orders, using any alloy signer. The signer requires that you provide the constants object, so that the permit2 signer can correctly derive the domain separator.

rust
use signet_types::signing::order::{UnsignedOrder};
use signet_constants::parmigiana as constants;

let signed = UnsignedOrder::default()
    .with_input(token_address, amount)
    .with_output(token_address, amount, recipient, chain_id)
    .with_chain(constants)
    .with_nonce(permit2_nonce)
    .sign(&signer).await?;

Submitting an Order

Once signed, the order can be submitted to the Signet network via the Signet tx cache. The tx cache makes the Order available to Searchers, who will include it in execution bundles.

rust
use signet_tx_cache::TxCache;

let tx_cache = TxCache::parmigiana();
tx_cache.forward_order(signed_order).await?;

Using OrderSender

For long-running services or bots, the signet-orders crate provides OrderSender — a reusable struct that wraps signing and submission into a single interface.

bash
cargo add signet-orders

OrderSender is generic over any alloy Signer and any OrderSubmitter backend. A ready-made OrderSubmitter implementation is provided for TxCache.

rust
use signet_constants::parmigiana;
use signet_orders::OrderSender;
use signet_tx_cache::TxCache;

// Any alloy Signer works: LocalSigner, AwsSigner, LedgerSigner, etc.
let signer = /* your signer */;

let order_sender = OrderSender::new(
    signer,
    TxCache::parmigiana(),
    parmigiana::system_constants(),
);

// Sign and submit in one call
let signed = order_sender.sign_and_send_order(order).await?;

You can also sign and send separately for more control:

rust
let signed = order_sender
    .sign_unsigned_order(
        UnsignedOrder::default()
            .with_input(token_address, amount)
            .with_output(token_address, amount, recipient, chain_id),
    )
    .await?;

// Submit when ready
order_sender.send_order(signed).await?;

If you need to submit orders somewhere other than the tx cache, implement the OrderSubmitter trait:

rust
use signet_orders::OrderSubmitter;
use signet_types::SignedOrder;

struct MySubmitter;

impl OrderSubmitter for MySubmitter {
    type Error = MyError;

    async fn submit_order(&self, order: SignedOrder) -> Result<(), Self::Error> {
        // Forward the order to your backend
        todo!()
    }
}

For on-chain order creation, check out Solidity Orders.

ESC

Start typing to search documentation...

Navigate Select ⌘K Open