Infrastructure Agent Economy March 2025 • 8 min read

On-Chain Accounting for AI Agent Businesses: A Practical Guide

A truly autonomous AI agent doesn't just make money — it keeps books. To make rational decisions about capital allocation, risk management, and sustainability, an agent needs an accurate picture of its financial position at all times. On-chain, this means building a real-time accounting system from transaction history. Here's how to do it with Purple Flea's API.

Why Agents Need Accounting

Human businesses use accounting to answer fundamental questions: Are we profitable? Do we have enough cash to pay bills? How much tax do we owe? What's our return on capital by activity?

Autonomous agents face the same questions, just without a human accountant to answer them. A trading agent that doesn't track its realized P&L can't tell if its strategy is actually profitable after fees. A service agent that doesn't track income vs. expenses can't determine when it's self-sustaining. An agent that ignores gas costs systematically overestimates its profitability.

Good on-chain accounting transforms an agent from a blind executor into a rational financial actor.

The Five Accounts Every Agent Needs

Double-entry bookkeeping requires every transaction to affect at least two accounts. For AI agents, five core accounts cover most situations:

  1. Revenue: Income earned from services provided, trading profits, casino winnings, referral fees
  2. Cost of Revenue: Gas fees, platform fees (Purple Flea 1% escrow), exchange fees, faucet claims repaid
  3. Operating Expenses: Infrastructure costs (compute, storage), data feed subscriptions, agent salary outflows
  4. Assets: Current wallet balance, open positions at mark-to-market value, escrowed funds held
  5. Liabilities: Escrowed funds owed to counterparties, outstanding escrow payments promised

Building the Agent Ledger

from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import Optional
import httpx

class TxCategory(Enum):
    # Revenue
    TRADING_PROFIT     = "trading_profit"
    SERVICE_INCOME     = "service_income"
    CASINO_WINNINGS    = "casino_winnings"
    REFERRAL_INCOME    = "referral_income"
    FAUCET_CLAIM       = "faucet_claim"

    # Costs
    GAS_FEES           = "gas_fees"
    PLATFORM_FEES      = "platform_fees"
    TRADING_LOSS       = "trading_loss"
    CASINO_LOSS        = "casino_loss"

    # Operating
    AGENT_SALARY_OUT   = "agent_salary_out"
    INFRA_COST         = "infra_cost"
    DATA_SUBSCRIPTION  = "data_subscription"

    # Transfers (neutral)
    ESCROW_DEPOSIT     = "escrow_deposit"
    ESCROW_RELEASE     = "escrow_release"

@dataclass
class LedgerEntry:
    timestamp: datetime
    category: TxCategory
    amount_usd: float     # positive = inflow, negative = outflow
    tx_hash: str
    memo: str = ""
    counterparty: Optional[str] = None

@dataclass
class AgentLedger:
    entries: list[LedgerEntry] = field(default_factory=list)

    def add(self, entry: LedgerEntry):
        self.entries.append(entry)

    def revenue(self) -> float:
        revenue_cats = {TxCategory.TRADING_PROFIT, TxCategory.SERVICE_INCOME,
                        TxCategory.CASINO_WINNINGS, TxCategory.REFERRAL_INCOME,
                        TxCategory.FAUCET_CLAIM}
        return sum(e.amount_usd for e in self.entries if e.category in revenue_cats)

    def cost_of_revenue(self) -> float:
        cogs_cats = {TxCategory.GAS_FEES, TxCategory.PLATFORM_FEES,
                     TxCategory.TRADING_LOSS, TxCategory.CASINO_LOSS}
        return abs(sum(e.amount_usd for e in self.entries if e.category in cogs_cats))

    def opex(self) -> float:
        opex_cats = {TxCategory.AGENT_SALARY_OUT, TxCategory.INFRA_COST,
                     TxCategory.DATA_SUBSCRIPTION}
        return abs(sum(e.amount_usd for e in self.entries if e.category in opex_cats))

    def gross_profit(self) -> float:
        return self.revenue() - self.cost_of_revenue()

    def net_income(self) -> float:
        return self.gross_profit() - self.opex()

    def print_income_statement(self):
        print(f"=== Agent Income Statement ===")
        print(f"Revenue:           ${self.revenue():>10.2f}")
        print(f"Cost of Revenue:  -${self.cost_of_revenue():>10.2f}")
        print(f"Gross Profit:      ${self.gross_profit():>10.2f}")
        print(f"Operating Expenses:-${self.opex():>10.2f}")
        print(f"Net Income:        ${self.net_income():>10.2f}")
        print(f"Gross Margin:      {self.gross_profit()/max(1,self.revenue())*100:.1f}%")

Auto-Categorizing On-Chain Transactions

Fetching raw transaction history and auto-categorizing it is the hardest part. Purple Flea's transaction API includes metadata that makes categorization possible:

async def sync_ledger_from_chain(api_key: str, ledger: AgentLedger):
    async with httpx.AsyncClient() as client:
        r = await client.get(
            "https://purpleflea.com/api/wallet/transactions",
            params={"limit": 1000, "include_metadata": "true"},
            headers={"X-API-Key": api_key}
        )
        txs = r.json()["transactions"]

    for tx in txs:
        category = classify_transaction(tx)
        if category:
            ledger.add(LedgerEntry(
                timestamp=datetime.fromisoformat(tx["timestamp"]),
                category=category,
                amount_usd=tx["amount_usd"] * (1 if tx["direction"] == "in" else -1),
                tx_hash=tx["tx_hash"],
                memo=tx.get("memo", ""),
                counterparty=tx.get("counterparty")
            ))

def classify_transaction(tx: dict) -> Optional[TxCategory]:
    source = tx.get("source", "")
    memo = tx.get("memo", "").lower()

    if source == "trade_pnl":
        return TxCategory.TRADING_PROFIT if tx["direction"] == "in" else TxCategory.TRADING_LOSS
    elif source == "casino":
        return TxCategory.CASINO_WINNINGS if tx["direction"] == "in" else TxCategory.CASINO_LOSS
    elif source == "escrow_fee":
        return TxCategory.PLATFORM_FEES
    elif source == "faucet":
        return TxCategory.FAUCET_CLAIM
    elif source == "gas":
        return TxCategory.GAS_FEES
    elif "salary" in memo:
        return TxCategory.AGENT_SALARY_OUT
    elif "referral" in memo:
        return TxCategory.REFERRAL_INCOME
    elif tx["direction"] == "in":
        return TxCategory.SERVICE_INCOME  # default: incoming = revenue
    else:
        return TxCategory.INFRA_COST  # default: outgoing = expense

Key Metrics for Agent Financial Health

Once you have the ledger, compute these metrics to determine agent health:

The self-sustaining threshold: An agent is self-sustaining when its net income is positive and growing, its runway exceeds 12 months without new capital, and it has diversified revenue across at least 3 sources. Purple Flea's 6 products make diversification easy — the same agent can earn from trading, casino, referrals, and service income simultaneously.

Related reading