Skip to main content
The tempo-alloy crate provides Alloy integration for Tempo, including network types, provider implementations, transaction request builders, and RPC type conversions.

Installation

[dependencies]
tempo-alloy = "0.1.0"

Network Types

TempoNetwork

The Tempo-specific implementation of Alloy’s Network trait.
use tempo_alloy::TempoNetwork;
use alloy_network::Network;

// TempoNetwork defines:
// - TxType: TempoTxType (Legacy, EIP-2930, EIP-1559, EIP-7702, AA)
// - TxEnvelope: TempoTxEnvelope
// - UnsignedTx: TempoTypedTransaction
// - ReceiptEnvelope: ReceiptWithBloom<TempoReceipt>
// - Header: TempoHeader
// - TransactionRequest: TempoTransactionRequest
// - TransactionResponse: Transaction<TempoTxEnvelope>
// - ReceiptResponse: TempoTransactionReceipt
Source: crates/alloy/src/network.rs:26-41
use tempo_alloy::TempoFillers;
use alloy_provider::fillers::NonceFiller;

// Type alias: JoinFill<NonceFiller, JoinFill<GasFiller, ChainIdFiller>>
type Fillers = TempoFillers<NonceFiller>;
Source: crates/alloy/src/network.rs:20-23

Transaction Requests

TempoTransactionRequest

Extends Ethereum’s TransactionRequest with Tempo-specific fields for Account Abstraction.
use tempo_alloy::rpc::TempoTransactionRequest;
use alloy_primitives::{Address, U256, Bytes};

// Build a standard transaction
let tx = TempoTransactionRequest::default()
    .with_to(Address::ZERO)
    .with_value(U256::from(1000))
    .with_gas_limit(21000);

// Build an AA transaction with custom fee token
let aa_tx = TempoTransactionRequest::default()
    .with_fee_token(token_address)
    .with_nonce_key(U256::from(1))
    .with_calls(vec![call1, call2]);
AA-Specific Fields:
fee_token
Address
Token address to pay gas fees in (instead of native currency)
nonce_key
U256
Custom nonce key for 2D nonce system (enables parallel transactions)
calls
Vec<Call>
Array of calls for multi-call batching
tempo_authorization_list
Vec<TempoSignedAuthorization>
EIP-7702 style authorizations with Tempo signature types
key_authorization
SignedKeyAuthorization
Authorization to use a delegated signing key
key_id
Address
ID of the signing key to use
valid_before
u64
Unix timestamp after which transaction is invalid
valid_after
u64
Unix timestamp before which transaction is invalid
Source: crates/alloy/src/rpc/request.rs

Transaction Builder Extensions

use tempo_alloy::rpc::TempoCallBuilderExt;

// Extension trait for building AA transactions
trait TempoCallBuilderExt {
    fn with_fee_token(self, token: Address) -> Self;
    fn with_nonce_key(self, key: U256) -> Self;
    fn with_calls(self, calls: Vec<Call>) -> Self;
    fn with_valid_before(self, timestamp: u64) -> Self;
    fn with_valid_after(self, timestamp: u64) -> Self;
}

RPC Types

TempoTransactionReceipt

Transaction receipt with Tempo-specific fields.
use tempo_alloy::rpc::TempoTransactionReceipt;
use alloy_rpc_types_eth::TransactionReceipt;

pub struct TempoTransactionReceipt {
    /// Standard Ethereum receipt fields
    pub inner: TransactionReceipt,
    
    /// Token used to pay transaction fees (null for free transactions)
    pub fee_token: Option<Address>,
    
    /// Address that paid for the transaction fees
    pub fee_payer: Address,
}
Source: crates/alloy/src/rpc/receipt.rs

TempoHeaderResponse

Block header with Tempo-specific fields.
use tempo_alloy::rpc::TempoHeaderResponse;

// Includes standard Ethereum header fields plus:
// - generalGasLimit: u64
// - sharedGasLimit: u64  
// - timestampMillisPart: u64
Source: crates/alloy/src/rpc/header.rs

Provider Integration

Wallet Support

use tempo_alloy::TempoNetwork;
use alloy_network::{EthereumWallet, NetworkWallet};
use alloy_signer_local::PrivateKeySigner;

// Create wallet
let signer = PrivateKeySigner::random();
let wallet = EthereumWallet::from(signer);

// Sign transaction
let tx = TempoTransactionRequest::default()
    .with_to(Address::ZERO)
    .with_value(U256::from(1000));
    
let envelope = wallet.sign_transaction_from(
    sender_address,
    tx.build_unsigned()?
).await?;
Source: crates/alloy/src/network.rs:294-319

Pagination

Utility types for cursor-based pagination in RPC queries.
use tempo_alloy::rpc::pagination::PaginationParams;

pub struct PaginationParams<F> {
    /// Maximum number of results to return
    pub limit: Option<u32>,
    
    /// Opaque cursor for fetching next page
    pub cursor: Option<String>,
    
    /// Query-specific filters
    pub filter: F,
}
Source: crates/alloy/src/rpc/pagination.rs

Transaction Fillers

Custom transaction fillers for Tempo-specific fields.
use tempo_alloy::fillers;

// Located in crates/alloy/src/fillers/
// Implements:
// - Fee token filler
// - Nonce key filler
// - Validity window filler
Source: crates/alloy/src/fillers/

Type Conversions

Reth Compatibility

With the tempo-compat feature, convert between Alloy and Reth types.
use tempo_alloy::rpc::compat;

// Convert between Tempo RPC types and Reth internal types
// Requires: tempo-compat feature
Source: crates/alloy/src/rpc/compat.rs

Example: Building and Sending AA Transaction

use tempo_alloy::{
    TempoNetwork,
    rpc::{TempoTransactionRequest, FeeToken},
};
use alloy_provider::{Provider, ProviderBuilder};
use alloy_network::EthereumWallet;
use alloy_primitives::{Address, U256};

#[tokio::main]
async fn main() -> eyre::Result<()> {
    // Setup provider
    let provider = ProviderBuilder::new()
        .network::<TempoNetwork>()
        .with_recommended_fillers()
        .wallet(wallet)
        .on_http("https://rpc.tempo.xyz".parse()?);
    
    // Build AA transaction with custom fee token
    let tx = TempoTransactionRequest::default()
        .with_from(sender)
        .with_to(recipient)
        .with_value(U256::from(1000))
        .with_fee_token(usdc_address) // Pay fees in USDC
        .with_nonce_key(U256::from(1)); // Use custom nonce key
    
    // Send transaction
    let pending = provider.send_transaction(tx).await?;
    let receipt = pending.get_receipt().await?;
    
    println!("Transaction hash: {:?}", receipt.transaction_hash);
    println!("Fee token: {:?}", receipt.fee_token);
    println!("Fee payer: {:?}", receipt.fee_payer);
    
    Ok(())
}

Example: Multi-Call Batching

use tempo_alloy::rpc::TempoTransactionRequest;
use alloy_primitives::{Address, Bytes};

// Build multi-call AA transaction
let tx = TempoTransactionRequest::default()
    .with_calls(vec![
        // Transfer tokens
        Call {
            to: token_address,
            value: None,
            data: transfer_calldata,
        },
        // Approve spender
        Call {
            to: token_address,
            value: None,
            data: approve_calldata,
        },
        // Swap on DEX
        Call {
            to: dex_address,
            value: None,
            data: swap_calldata,
        },
    ])
    .with_fee_token(usdc_address);

// All three operations execute atomically
let receipt = provider.send_transaction(tx).await?.get_receipt().await?;

Features

  • tempo-compat - Enable conversions between Alloy and Reth types
  • asm-keccak - Use optimized assembly Keccak implementation

See Also