Tenzro Testnet is live. Get testnet TNZO

Settlement

The settlement engine provides payment settlement for immediate settlements, escrow-based transactions, micropayment channels, and batch processing.

Settlement Types

Immediate Settlement

Funds transferred directly from payer to payee on-chain. Used for one-time payments and high-value transactions.

Escrow-Based Settlement

Funds locked in escrow until proof is provided. Used for AI inference payments where proof of computation is verified before release.

Micropayment Channels

Off-chain payment channels for per-token billing. Used for streaming AI inference where payment occurs per token generated.

Batch Settlement

Atomic processing of multiple settlements in a single transaction. Used for aggregating many small payments to reduce gas costs.

Immediate Settlement

let settlement = SettlementRequest {
    settlement_id: "settle_abc123".to_string(),
    payer: "tenzro1abc...xyz".to_string(),
    payee: "tenzro1def...uvw".to_string(),
    amount: 100.0,
    asset: "TNZO".to_string(),
    settlement_type: SettlementType::Immediate,
    metadata: HashMap::from([
        ("service".to_string(), "inference".to_string()),
    ]),
    proof: None,
};

let receipt = engine.settle(&settlement).await?;
// Receipt includes settlement_tx hash on Tenzro Ledger

Escrow-Based Settlement

Escrow settlements lock funds until cryptographic proof is provided, enabling trustless payments for AI services.

Escrow Flow

  1. Lock — Payer locks funds in escrow contract
  2. Service — Provider delivers AI inference or other service
  3. Proof — Provider generates ZK proof of computation
  4. Verify — System verifies proof on-chain
  5. Release — Funds automatically released to provider
  6. Receipt — Settlement receipt issued to both parties
// Create escrow settlement
let settlement = SettlementRequest {
    settlement_id: "settle_escrow_123".to_string(),
    payer: "tenzro1abc...xyz".to_string(),
    payee: "tenzro1model...provider".to_string(),
    amount: 5.0,
    asset: "TNZO".to_string(),
    settlement_type: SettlementType::Escrow,
    metadata: HashMap::from([
        ("inference_request_id".to_string(), "req_xyz789".to_string()),
    ]),
    proof: Some(vec![0xAB, 0xCD, ...]), // ZK proof
};

// Verify proof and release funds
let receipt = engine.settle(&settlement).await?;

Micropayment Channels

Micropayment channels enable off-chain per-token billing for streaming AI inference, settling on-chain only when the channel closes.

Channel Lifecycle

1. Open Channel

let channel_id = manager.open_channel(
    "tenzro1payer...abc".to_string(),
    "tenzro1provider...xyz".to_string(),
    1000.0, // Initial deposit (TNZO)
    "TNZO".to_string(),
    7200, // Timeout (2 hours)
).await?;

2. Update State (Off-chain)

// For each token generated
manager.update_channel_state(
    &channel_id,
    0.001, // Cost per token
).await?;

// State updated locally, no on-chain transaction

3. Close Channel (On-chain Settlement)

let settlement_tx = manager.close_channel(&channel_id).await?;
// Final state settled on Tenzro Ledger
// Remaining balance returned to payer
// Provider receives accumulated payments

Example: Streaming Inference

// Open channel for 1000 TNZO
let channel = manager.open_channel(
    payer, provider, 1000.0, "TNZO", 7200
).await?;

// Generate 50,000 tokens at $0.001 per token
for token in generated_tokens {
    manager.update_channel_state(&channel.id, 0.001).await?;
}
// Total: 50 TNZO charged (off-chain)

// Close channel
let tx = manager.close_channel(&channel.id).await?;
// On-chain: 50 TNZO to provider, 950 TNZO refund to payer

Nanopayment Batching

NanopaymentBatcher aggregates many sub-cent payments into periodic on-chain settlements, saving gas by replacing N individual transactions with a single batch settlement.

  • Configurable Window: Default 60-second batch window with configurable minimum and maximum batch sizes
  • Cryptographic Signatures: Each nanopayment is individually signed and stored off-chain until settlement
  • Threshold Triggers: Settlement fires when the batch window expires or the batch size threshold is reached
  • Atomic Settlement: All payments in a batch are settled atomically — if any fails, the entire batch rolls back
  • Gas Savings: Instead of N on-chain transactions, 1 batch settlement covers all accumulated payments
use tenzro_settlement::nanopayments::NanopaymentBatcher;

let batcher = NanopaymentBatcher::new(
    settlement_engine,
    BatchConfig {
        window_secs: 60,
        min_batch_size: 10,
        max_batch_size: 1000,
    },
);

// Add nanopayments (accumulated off-chain)
batcher.add_payment(payer, payee, 100_000, "inference-token-42")?;
batcher.add_payment(payer, payee, 150_000, "inference-token-43")?;

// Flush manually or wait for window expiry
let settlement = batcher.flush().await?;
println!("Settled {} payments, total: {}", settlement.count, settlement.total);

Payment-Settlement Wiring

The PaymentSettlementCallback trait bridges the payment gateway to the settlement engine. When a payment is verified — whether via MPP credential, x402 payload, or AP2 authorization — the callback triggers on-chain settlement and returns the receipt to the payment layer for inclusion in the HTTP response.

// Payment gateway automatically settles via callback
impl PaymentSettlementCallback for TenzroSettlement {
    async fn on_payment_verified(
        &self,
        payer: &Address,
        payee: &Address,
        amount: u128,
        asset: &str,
        receipt_id: &str,
    ) -> Result<SettlementReceipt> {
        self.engine.settle_immediate(payer, payee, amount, asset).await
    }
}

Batch Settlement

Batch processing enables atomic settlement of multiple payments in a single transaction, reducing gas costs and ensuring atomicity.

let settlements = vec![
    SettlementRequest {
        settlement_id: "settle_1".to_string(),
        payer: "tenzro1abc...".to_string(),
        payee: "tenzro1provider1...".to_string(),
        amount: 10.0,
        asset: "TNZO".to_string(),
        settlement_type: SettlementType::Immediate,
        metadata: HashMap::new(),
        proof: None,
    },
    SettlementRequest {
        settlement_id: "settle_2".to_string(),
        payer: "tenzro1abc...".to_string(),
        payee: "tenzro1provider2...".to_string(),
        amount: 15.0,
        asset: "TNZO".to_string(),
        settlement_type: SettlementType::Immediate,
        metadata: HashMap::new(),
        proof: None,
    },
];

// Process atomically: all succeed or all fail
let receipts = batch_processor.process_batch(settlements).await?;

Fee Collection

The FeeCollector manages network fees on all settlements:

  • Network Fee: 0.5% on all settlements (configurable)
  • Collection: Fees automatically deducted and routed to treasury
  • Multi-Asset: Fees collected in the payment asset (TNZO, USDC, etc.)
  • Transparency: All fees recorded on-chain in settlement receipts
// Example: 100 TNZO settlement with 0.5% fee
Amount: 100.0 TNZO
Network Fee: 0.5 TNZO (0.5%)
To Payee: 99.5 TNZO
To Treasury: 0.5 TNZO

// Receipt includes fee breakdown
{
  "settlement_id": "settle_abc123",
  "amount": "100.0",
  "fee": "0.5",
  "net_amount": "99.5",
  "fee_recipient": "treasury"
}

Settlement Receipt

Every settlement generates a cryptographically signed receipt:

{
  "settlement_id": "settle_abc123",
  "payer": "tenzro1abc...xyz",
  "payee": "tenzro1def...uvw",
  "amount": "100.0",
  "asset": "TNZO",
  "settlement_type": "Immediate",
  "settlement_tx": "0x789abc...",
  "fee": "0.5",
  "net_amount": "99.5",
  "timestamp": "2026-03-20T12:30:45Z",
  "block_height": 1207,
  "metadata": {
    "service": "inference",
    "request_id": "req_xyz789"
  },
  "signature": "0xdef456..."
}

Verification

Settlement receipts can be verified via the Web Verification API:

# Verify settlement receipt
curl -X POST http://localhost:8080/verify/settlement \
  -H "Content-Type: application/json" \
  -d '{
    "receipt": {
      "settlement_id": "settle_abc123",
      "amount": "100.0",
      "proof": "0xabc..."
    }
  }'

# Response
{
  "valid": true,
  "settlement_confirmed": true
}

Integration with Payments

Settlement is automatically triggered by payment protocol verification:

// MPP payment verification triggers settlement
let receipt = mpp_server.verify_credential(&credential).await?;

// Settlement happens automatically:
// 1. Funds transferred from payer to payee
// 2. Network fee collected
// 3. Settlement receipt generated
// 4. Receipt included in MPP receipt

// Payment receipt includes settlement_tx
{
  "receipt_id": "rcpt_xyz789",
  "amount": "0.05 TNZO",
  "settlement_tx": "0x789abc...", // On-chain settlement
  "session_token": "sess_mno345"
}