---
title: "Filler"
url: "/docs/searchers/filler/index.md"
description: "Build an order filler bot using the signet-orders crate"
---
# Filler

The `Filler` struct from [`signet-orders`](https://docs.rs/signet-orders/latest/signet_orders/)
orchestrates the full order-filling pipeline: fetching pending orders from a
source, signing [Permit2](https://docs.uniswap.org/contracts/permit2/overview)
fills, and submitting them as bundles. It is the main building block for writing
a Signet filler bot.

> **Example implementation:** The [signet-filler](https://github.com/init4tech/signet-filler) repository is an
example filler built on top of `Filler` and `FeePolicySubmitter`. It demonstrates
order filtering, metrics, provider setup, and the overall structure of a filler
service.

## Setup

```bash
cargo add signet-orders signet-types signet-constants signet-tx-cache
cargo add alloy --features provider-http,signers
cargo add futures-util
```

## Architecture

`Filler` is generic over three type parameters:

- **`Sign`**: Any [alloy `Signer`](https://docs.rs/alloy/latest/alloy/signers/trait.Signer.html) — signs Permit2 fill messages
- **`Source`**: An [`OrderSource`](https://docs.rs/signet-orders/latest/signet_orders/trait.OrderSource.html) — provides a stream of pending orders (e.g. from the tx cache)
- **`Submit`**: A [`FillSubmitter`](https://docs.rs/signet-orders/latest/signet_orders/trait.FillSubmitter.html) — handles transaction construction, gas pricing, and bundle submission

```
OrderSource ──▶ Filler ──▶ FillSubmitter ──▶ BundleSubmitter
  (fetch)      (sign)     (build txs)       (submit bundle)
```

The crate provides [`TxCache`](https://docs.rs/signet-tx-cache/latest/signet_tx_cache/)
as a ready-made `OrderSource` and `BundleSubmitter`, and
[`FeePolicySubmitter`](https://docs.rs/signet-orders/latest/signet_orders/struct.FeePolicySubmitter.html)
as a `FillSubmitter` that handles gas pricing and bundle construction.

## Creating a Filler

```rust
use alloy::providers::ProviderBuilder;
use signet_constants::parmigiana;
use signet_orders::{FeePolicySubmitter, Filler, FillerOptions};
use signet_tx_cache::TxCache;

let signer = /* your alloy Signer */;
let wallet = /* EthereumWallet wrapping the same key */;

// Connect providers with gas estimation and wallet signing
let ru_provider = ProviderBuilder::new()
    .wallet(wallet.clone())
    .connect("https://rpc.parmigiana.signet.sh")
    .await?;
let host_provider = ProviderBuilder::new()
    .wallet(wallet)
    .connect("https://eth.llamarpc.com")
    .await?;

let tx_cache = TxCache::parmigiana();
let constants = parmigiana::system_constants();

// FeePolicySubmitter builds fill + initiate transactions and wraps them in a
// SignetEthBundle before forwarding to the BundleSubmitter (here, the tx cache).
let submitter = FeePolicySubmitter::new(
    ru_provider,
    host_provider,
    tx_cache.clone(),
    constants.clone(),
);

let filler = Filler::new(
    signer,
    tx_cache,
    submitter,
    constants,
    FillerOptions::new(),
);
```

## FillerOptions

`FillerOptions` lets you tune fill signing behavior:

- **`deadline_offset`** — seconds from now until the Permit2 signature expires.
  When `None` (default), defaults to 12 seconds.
- **`nonce`** — explicit Permit2 nonce. When `None` (default), a fresh nonce is
  generated from the current timestamp in microseconds.

```rust
let options = FillerOptions::new()
    .with_deadline_offset(30)  // 30 second deadline
    .with_nonce(42);           // explicit nonce
```

## Fetching and Filling Orders

### Fetch orders as a stream

`get_orders()` returns a `Stream` of `SignedOrder`s. You can filter, collect,
or process them however you like:

```rust
use futures_util::{StreamExt, TryStreamExt};

let orders: Vec = filler
    .get_orders()
    .try_filter(|order| {
        // Apply your own filtering logic
        std::future::ready(is_profitable(order))
    })
    .try_collect()
    .await?;
```

### Fill a batch of orders

`fill()` signs Permit2 fills for the orders, builds transactions, and submits
the bundle in one call:

```rust
match filler.fill(orders).await {
    Ok(response) => println!("Bundle submitted: {}", response.id),
    Err(error) => eprintln!("Fill failed: {error}"),
}
```

### Sign fills without submitting

For more control, use `sign_fills()` to get back an `OrdersAndFills` struct
that pairs orders with their signed fills:

```rust
let orders_and_fills = filler.sign_fills(orders).await?;

// Inspect before submitting
println!("Signer: {}", orders_and_fills.signer_address());
println!("Orders: {}", orders_and_fills.orders().len());
println!("Fills per chain: {}", orders_and_fills.fills().len());
```

## Implementing Custom Traits

### OrderSource

Provide orders from a custom source:

```rust
use futures_util::Stream;
use signet_orders::OrderSource;
use signet_types::SignedOrder;

struct MyOrderSource;

impl OrderSource for MyOrderSource {
    type Error = MyError;

    fn get_orders(&self) -> impl Stream> + Send {
        // Return a stream of orders from your source
        todo!()
    }
}
```

### FillSubmitter

Handle fill submission with custom transaction construction or fee logic:

```rust
use signet_orders::{FillSubmitter, OrdersAndFills};

struct MySubmitter;

impl FillSubmitter for MySubmitter {
    type Response = ();
    type Error = MyError;

    async fn submit_fills(&self, orders_and_fills: OrdersAndFills) -> Result {
        // Build and submit transactions your way
        todo!()
    }
}
```

## FeePolicySubmitter

[`FeePolicySubmitter`](https://docs.rs/signet-orders/latest/signet_orders/struct.FeePolicySubmitter.html)
is the provided `FillSubmitter` implementation. It:

1. Builds rollup transactions (fill + order initiate calls)
2. Builds host transactions (fill calls for orders targeting Ethereum)
3. Signs and encodes all transactions using the configured providers
4. Wraps everything in a `SignetEthBundle` and submits via a `BundleSubmitter`

It requires two providers (rollup and host) configured with gas estimation and
wallet fillers, plus any `BundleSubmitter` (e.g. `TxCache`).

## Next Steps

- [signet-filler source](https://github.com/init4tech/signet-filler) — example filler service built on `signet-orders`
- [Off-chain Orders in Rust](/docs/build-on-signet/transfers/exit-signet/index.md#rust) — submit orders (the other side of the market)
- [Simulating Bundles](/docs/build-on-signet/advanced/simulating-bundles/index.md) — test bundles before submission
- [Working with Orders](/docs/build-on-signet/transfers/exit-signet/index.md) — overview of the orders system
