Tempo is a new L1 optimized specifically for stablecoin payments. The chain processes payments for less than $0.001 per transaction, achieves sub-second finality, and implements native compliance, multi-currency gas payments, and passkey authentication.

We will walk through key parts of the technical architecture, key design decisions, and get you started building on Tempo. It is an exciting step forward in many ways.

Resources:

Core Features

Payment-First Architecture

Traditional blockchains treat all transactions equally. Tempo implements dedicated payment lanes directly into the protocol, recognizing that payment transactions have different requirements than smart contract execution.

The TIP-20 token standard (Tempo’s enhanced ERC-20) includes:

  • Payment lanes: Segregated transaction pools for predictable throughput
  • On-chain memos: Native reconciliation support with transaction metadata
  • Built-in compliance: TIP-403 policy registry for shared KYC/AML rules
  • Sub-block architecture: Parallel processing for higher throughput
// Send a payment with TIP-20 transfers 
import { parseUnits } from 'viem'
import { client } from './viem.config'
 
const { receipt } = await client.token.transferSync({
  amount: parseUnits('100', 6), // 100 tokens (6 decimals)
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
  token: '0x20c0000000000000000000000000000000000001', // AlphaUSD
})

Multi-Currency Gas

Users pay gas in any supported stablecoin, while validators receive their preferred currency. A built-in Fee AMM automatically converts between stablecoins at market rates.

Signature Types

Tempo transactions support three signature types natively:

  • Secp256k1: Standard Ethereum signatures
  • P256: Passkey/WebAuthn signatures
  • WebAuthn: Full passkey authentication with biometrics
import { Account, WebAuthnP256 } from 'tempo.ts/viem'
import { parseEther } from 'viem'

// 1. Create a new passkey credential
const credential = await WebAuthnP256.createCredential({
  name: 'My App Account'
})

// 2. Instantiate account from credential
const account = Account.fromWebAuthnP256(credential)

// 3. Store public key for future use (recommended)
await store.set(credential.id, credential.publicKey)

// 4. Sign a transaction
const hash = await account.signTransaction({
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
  value: parseEther('1.0'),
  // ... other transaction fields
})

Implementation: crates/primitives/src/transaction/tempo_transaction.rs:28-38

Protocol-Level Account Abstraction

Tempo Transactions (Type 0x76) provide account abstraction features natively at the protocol level rather than through smart contracts.

Batched Transactions:

import { client } from './viem.config'

// Execute multiple operations atomically
const { address, hash, id } = await client.sendTransaction({
  calls: [
    { to: tokenAddress, data: approveCalldata },
    { to: dexAddress, data: swapCalldata },
    { to: recipient, value: amount, data: transferCalldata }
  ]
  // All execute atomically - succeed together or fail together
})

2D Nonce System for Parallelization:

import { client } from './viem.config'

// Send multiple transactions concurrently from same account
// First parallel sequence
await client.sendTransaction({
  calls: [...],
  nonceKey: 1n,
  nonce: 0n,
})

// Second parallel sequence (can be in same block)
await client.sendTransaction({
  calls: [...],
  nonceKey: 2n,
  nonce: 0n,
})

// Continue first sequence
await client.sendTransaction({
  calls: [...],
  nonceKey: 1n,
  nonce: 1n,
})

Fee Sponsorship:

import { parseUnits } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { client } from './viem.config'

// Option 1: Local account sponsorship
const sponsorAccount = privateKeyToAccount('0x...')

const { receipt } = await client.token.transferSync({
  amount: parseUnits('100', 6),
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
  token: '0x20c0000000000000000000000000000000000001',
  feePayer: sponsorAccount,  // Sponsor pays the transaction fee
})

// Option 2: Relay-based sponsorship (requires withFeePayer transport)
const { receipt } = await client.token.transferSync({
  amount: parseUnits('100', 6),
  to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
  token: '0x20c0000000000000000000000000000000000001',
  feePayer: true,  // Use configured fee relay service
})

Scheduled Transactions:

import { client } from './viem.config'

// Transaction only valid in specific time window
await client.sendTransaction({
  calls: [...],
  validAfter: 1735689600,  // Not before Jan 1, 2025
  validBefore: 1767225600, // Not after Jan 1, 2026
})

Key Authorization Provisioning:

import { client } from './viem.config'

// Provision a new access key in the same transaction
await client.sendTransaction({
  calls: [...],
  keyAuthorization: {
    keyType: 'p256',  // or 'secp256k1', 'webauthn'
    expiry: timestamp,
    limits: [{ token: usdcAddress, limit: maxAmount }],
    keyId: newKeyAddress
  }
  // Transaction signature verified with new key
})

Implementation: crates/primitives/src/transaction/tempo_transaction.rs:150-223

Architecture

Dual-Layer Design

Tempo separates execution and consensus into distinct layers:

Execution Layer: Reth

  • Paradigm’s Ethereum client implementation
  • Full EVM compatibility (Osaka hardfork target)
  • Compatible with Solidity, Foundry, Hardhat
  • Custom precompiles for payment features

Consensus Layer: Commonware Simplex

  • Sub-second finality in normal conditions
  • BLS12-381 threshold signatures
  • Graceful degradation under network stress
  • DKG for validator set changes

Source: https://github.com/commonwarexyz/monorepo

Integration: crates/commonware-node/src/lib.rs:1-192

Custom Precompiles

Payment-critical features are implemented as native Rust precompiles:

Precompile Address Range Purpose
TIP20 0x20C0... Enhanced ERC-20 with payment lanes
TIP20Factory 0x20FC000... Token creation and management
TIP403Registry Fixed address Compliance policy registry
AccountKeychain Fixed address Multi-key management + passkeys
StablecoinExchange Fixed address Native DEX for stablecoin swaps
TipFeeManager Fixed address Fee token selection and conversion
NonceManager Fixed address 2D nonce system management
ValidatorConfig Fixed address Validator configuration

Implementation: crates/precompiles/src/lib.rs:77-111

Specification approach:

  • Solidity reference: docs/specs/src/*.sol
  • Rust production: crates/precompiles/src/*/mod.rs
  • Cross-validated with Foundry fuzz testing

Performance Optimizations

1. ASM-Keccak (2-5x faster hashing)

  • Assembly-optimized keccak256 using AVX2/SSE
  • Critical for signature verification and storage operations
  • Enabled by default: bin/tempo/Cargo.toml:42

2. Jemalloc (~10% overall improvement)

  • Facebook’s multi-threaded memory allocator
  • Better fragmentation and cache locality
  • Reduces memory overhead under high load

3. Link-Time Optimization (~15% improvement)

  • Thin LTO for release builds
  • Fat LTO for maximum performance (--profile maxperf)
  • Cross-crate inlining and dead code elimination
[profile.release]
lto = "thin"
opt-level = 3

4. Parallel Block Building (8-16x more iterations)

  • Up to 16 concurrent payload builders
  • Each tries different transaction orderings
  • Best payload selected at deadline
DefaultPayloadBuilderValues::default()
    .with_max_payload_tasks(16)
    .with_interval(Duration::from_millis(100))
    .with_deadline(4)

Configuration: bin/tempo/src/defaults.rs:21-28

Combined result: Sustained >1000 TPS for payment transactions with sub-second finality.

Getting Started

Run a Node

# Install from source
git clone https://github.com/tempoxyz/tempo
cd tempo
cargo build --release --features "asm-keccak,jemalloc"

# Start node
./target/release/tempo node \
  --chain andantino \
  --http \
  --http.addr 0.0.0.0 \
  --http.port 8545

Build an Application

// Install SDK
npm install tempo.ts

// Setup client with Tempo extensions
import { createClient, http, walletActions } from 'viem'
import { tempo, tempoActions } from 'tempo.ts/chains'
import { parseEther } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'

const client = createClient({
  account: privateKeyToAccount('0x...'),
  chain: tempo({ feeToken: '0x20c0000000000000000000000000000000000001' }),
  transport: http(),
})
  .extend(walletActions)
  .extend(tempoActions())

// Send a batched Tempo transaction
const hash = await client.sendTransaction({
  calls: [
    {
      to: tokenAddress,
      value: 0n,
      data: approveCalldata
    },
    {
      to: recipientAddress,
      value: parseEther("1.0"),
      data: "0x"
    }
  ],
  nonceKey: 1n,  // Parallel transaction sequence
  feeToken: '0x20c0000000000000000000000000000000000001',  // Pay gas in AlphaUSD
})

console.log('Transaction hash:', hash)

For React applications using Wagmi:

import { Hooks } from 'tempo.ts/wagmi'
import { parseUnits } from 'viem'

function SendPayment() {
  const sendPayment = Hooks.token.useTransferSync()

  const handleSend = () => {
    sendPayment.mutate({
      amount: parseUnits('100', 6),
      to: '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEbb',
      token: '0x20c0000000000000000000000000000000000001',
    })
  }

  return (
    <button onClick={handleSend} disabled={sendPayment.isPending}>
      Send Payment
    </button>
  )
}

Deploy a Token

// Using Wagmi hooks (React)
import { Hooks } from 'tempo.ts/wagmi'

function CreateStablecoin() {
  const create = Hooks.token.useCreateSync()

  const handleCreate = () => {
    create.mutate({
      name: "My Stablecoin",
      symbol: "MYUSD",
      currency: 'USD',
    })
  }

  return (
    <button onClick={handleCreate} disabled={create.isPending}>
      Create Stablecoin
    </button>
  )
}

// Using Viem actions directly
import { Actions } from 'tempo.ts/viem'
import { client } from './viem.config'

const { token, receipt } = await Actions.token.createSync(client, {
  name: "My Stablecoin",
  symbol: "MYUSD",
  currency: 'USD',
})

console.log('Token created at:', token)

Reference

Specification-Driven Development

Each precompile has two implementations:

  1. Solidity reference (docs/specs/src/) - Source of truth
  2. Rust production (crates/precompiles/src/) - Optimized implementation

Foundry tests validate the Rust implementation against the Solidity spec:

// tempo-foundry integration tests Rust precompiles
// against Solidity reference implementations
#[test]
fn test_tip20_transfer_matches_spec() {
    // Test Rust precompile behavior
    let result = TIP20Token::transfer(sender, recipient, amount);

    // Compare against Solidity reference
    assert_eq!(result, solidity_reference_impl());
}

Codebase Structure

tempo/
├── bin/                    # Binaries
│   ├── tempo/             # Main node (production binary)
│   ├── tempo-bench/       # Benchmarking and load testing
│   └── tempo-sidecar/     # Metrics and monitoring
│
├── crates/                # 30+ modular crates
│   ├── precompiles/       # Native payment features (Rust)
│   ├── primitives/        # Core types and transactions
│   ├── consensus/         # Consensus validation logic
│   ├── commonware-node/   # Simplex consensus integration
│   ├── payload/builder/   # Parallel block construction
│   ├── transaction-pool/  # Custom pool with 2D nonces
│   ├── evm/               # EVM configuration
│   └── node/              # Node builder and RPC extensions
│
└── docs/                  # Vocs documentation site
    ├── specs/             # Solidity reference implementations
    └── pages/             # SDK guides and tutorials

Language breakdown:

  • Rust 2024 edition (requires 1.88)
  • 13,758 lines in Cargo.lock
  • Solidity for reference specs
  • TypeScript for documentation and SDKs

Chain Configuration

Chain parameters:

  • Chain ID: 42429 (testnet)
  • Target block time: 1 second
  • Gas limit: Dynamic based on network load
  • Shared gas limit: 1/4 of total (for payment lanes)
  • General gas limit: 1/10 of remaining (for non-payments)

Transaction pool:

  • 50,000 pending transactions
  • 50,000 queued transactions
  • 150,000 max account slots (for 2D nonces)
  • 8 parallel validation tasks

Configuration: bin/tempo/src/defaults.rs:30-51

Consensus:

  • Simplex with BLS12-381 threshold signatures
  • ED25519 for P2P authentication
  • Epoch-based validator reconfiguration
  • DKG for threshold key generation

Source: crates/commonware-node/src/consensus/

Implemented features:

  • TIP-20 tokens with payment lanes
  • Multi-currency gas payments
  • Tempo transactions (batching, fee sponsorship, scheduling)
  • WebAuthn/passkey signatures
  • Native DEX for stablecoin swaps
  • Compliance policy registry
  • Sub-second finality
  • Full EVM compatibility

Upcoming features:

  • Account keychain (multi-key management) - Post-Allegretto hardfork
  • Enhanced reward distribution system
  • Validator delegation and staking
  • Cross-chain bridges to Ethereum L2s

Testnet (andantino-1) is live. Mainnet launch planned for Q1 2026.

Links: