Skip to content

Step 4: Report Revenue

Goal

Report revenue earned by your agent to the Agent Registry. Revenue reports are stored on-chain and associated with your agent's record. This creates a transparent economic trail for accountability and regulatory compliance.

from agentenregister import AgentRegistry

registry = AgentRegistry(
    chain="base_sepolia",
    registry_address="0x2EFaB5B3BEf49E56a6Ce1dcB1A39EF63C312EA23",
    private_key="0x_your_agent_private_key",
    relayer_url="https://relay.theagentregistry.org",
)

agent_id = 42  # Your agent's ID from registration

registry.report_revenue(
    agent_id=agent_id,
    amount_cents=15000,              # $150.00 in cents
    currency="USDC",
    category="content_creation",
    period_start=1700000000,          # Unix timestamp: period start
    period_end=1700604800,            # Unix timestamp: period end
)
# Output: Revenue reported for agent 42: 15000 USDC
import { AgentRegistry } from "@agentenregister/sdk";

const registry = new AgentRegistry({
    chain: "base_sepolia",
    registryAddress: "0x2EFaB5B3BEf49E56a6Ce1dcB1A39EF63C312EA23",
    privateKey: "0x_your_agent_private_key",
    relayerUrl: "https://relay.theagentregistry.org",
});

const agentId = 42; // Your agent's ID from registration

await registry.reportRevenue({
    agentId: agentId,
    amountCents: 15000,              // $150.00 in cents
    currency: "USDC",
    category: "content_creation",
    periodStart: 1700000000,          // Unix timestamp: period start
    periodEnd: 1700604800,            // Unix timestamp: period end
});
console.log(`Revenue reported for agent ${agentId}`);

Method B: Raw Implementation (No SDK)

from web3 import Web3
from eth_account import Account
from eth_account.messages import encode_structured_data
import requests
import json
import time

# ── Configuration ─────────────────────────────────────────────
PRIVATE_KEY = "0x_your_agent_private_key"
RELAYER_URL = "https://relay.theagentregistry.org"
REGISTRY_ADDRESS = "0x2EFaB5B3BEf49E56a6Ce1dcB1A39EF63C312EA23"
CHAIN_ID = 84532
AGENT_ID = 42

account = Account.from_key(PRIVATE_KEY)

# ── Get forwarder address and nonce ───────────────────────────
domain = requests.get(f"{RELAYER_URL}/domain").json()
FORWARDER_ADDRESS = domain["verifyingContract"]

nonce = int(
    requests.get(f"{RELAYER_URL}/nonce/{account.address}").json()["nonce"]
)

# ── Encode reportRevenue calldata ─────────────────────────────
w3 = Web3()
ABI = json.loads(
    '[{"inputs":[{"name":"agentId","type":"uint256"},'
    '{"name":"amount","type":"uint256"},'
    '{"name":"currency","type":"string"},'
    '{"name":"category","type":"string"},'
    '{"name":"periodStart","type":"uint64"},'
    '{"name":"periodEnd","type":"uint64"}],'
    '"name":"reportRevenue","outputs":[],'
    '"stateMutability":"nonpayable","type":"function"}]'
)
contract = w3.eth.contract(address=REGISTRY_ADDRESS, abi=ABI)

now = int(time.time())
calldata = contract.functions.reportRevenue(
    AGENT_ID,
    15000,                     # amount in cents
    "USDC",                    # currency
    "content_creation",        # category
    now - 7 * 86400,           # period start (7 days ago)
    now,                       # period end (now)
).build_transaction({"gas": 0, "gasPrice": 0, "nonce": 0})["data"]

# ── Sign EIP-712 typed data ───────────────────────────────────
typed_data = {
    "types": {
        "EIP712Domain": [
            {"name": "name", "type": "string"},
            {"name": "version", "type": "string"},
            {"name": "chainId", "type": "uint256"},
            {"name": "verifyingContract", "type": "address"},
        ],
        "ForwardRequest": [
            {"name": "from", "type": "address"},
            {"name": "to", "type": "address"},
            {"name": "value", "type": "uint256"},
            {"name": "gas", "type": "uint256"},
            {"name": "nonce", "type": "uint256"},
            {"name": "deadline", "type": "uint48"},
            {"name": "data", "type": "bytes"},
        ],
    },
    "primaryType": "ForwardRequest",
    "domain": {
        "name": "MinimalForwarder",
        "version": "1",
        "chainId": CHAIN_ID,
        "verifyingContract": FORWARDER_ADDRESS,
    },
    "message": {
        "from": account.address,
        "to": REGISTRY_ADDRESS,
        "value": 0,
        "gas": 300000,
        "nonce": nonce,
        "deadline": 0,
        "data": calldata,
    },
}

encoded = encode_structured_data(typed_data)
signed = account.sign_message(encoded)

# ── Submit to relayer ─────────────────────────────────────────
result = requests.post(f"{RELAYER_URL}/relay", json={
    "request": {
        "from": account.address,
        "to": REGISTRY_ADDRESS,
        "value": "0",
        "gas": "300000",
        "nonce": str(nonce),
        "deadline": "0",
        "data": calldata,
    },
    "signature": signed.signature.hex(),
}).json()

print(f"Revenue reported! TX: {result['transactionHash']}")
import { ethers } from "ethers";

// ── Configuration ─────────────────────────────────────────────
const PRIVATE_KEY = "0x_your_agent_private_key";
const RELAYER_URL = "https://relay.theagentregistry.org";
const REGISTRY_ADDRESS = "0x2EFaB5B3BEf49E56a6Ce1dcB1A39EF63C312EA23";
const CHAIN_ID = 84532;
const AGENT_ID = 42;

const provider = new ethers.JsonRpcProvider("https://sepolia.base.org");
const wallet = new ethers.Wallet(PRIVATE_KEY, provider);

// ── Get forwarder address and nonce ───────────────────────────
const domainRes = await fetch(`${RELAYER_URL}/domain`);
const domain = await domainRes.json();
const FORWARDER_ADDRESS = domain.verifyingContract;

const nonceRes = await fetch(`${RELAYER_URL}/nonce/${wallet.address}`);
const nonce = (await nonceRes.json()).nonce;

// ── Encode reportRevenue calldata ─────────────────────────────
const ABI = [
    "function reportRevenue(uint256,uint256,string,string,uint64,uint64)",
];
const contract = new ethers.Contract(REGISTRY_ADDRESS, ABI, wallet);

const now = Math.floor(Date.now() / 1000);
const calldata = contract.interface.encodeFunctionData("reportRevenue", [
    AGENT_ID,
    15000,                     // amount in cents
    "USDC",                    // currency
    "content_creation",        // category
    now - 7 * 86400,           // period start
    now,                       // period end
]);

// ── Sign EIP-712 typed data ───────────────────────────────────
const request = {
    from: wallet.address,
    to: REGISTRY_ADDRESS,
    value: "0",
    gas: "300000",
    nonce: String(nonce),
    deadline: "0",
    data: calldata,
};

const signature = await wallet.signTypedData(
    {
        name: "MinimalForwarder",
        version: "1",
        chainId: BigInt(CHAIN_ID),
        verifyingContract: FORWARDER_ADDRESS,
    },
    {
        ForwardRequest: [
            { name: "from", type: "address" },
            { name: "to", type: "address" },
            { name: "value", type: "uint256" },
            { name: "gas", type: "uint256" },
            { name: "nonce", type: "uint256" },
            { name: "deadline", type: "uint48" },
            { name: "data", type: "bytes" },
        ],
    },
    request,
);

// ── Submit to relayer ─────────────────────────────────────────
const relayRes = await fetch(`${RELAYER_URL}/relay`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ request, signature }),
});

const result = await relayRes.json();
console.log(`Revenue reported! TX: ${result.transactionHash}`);

Parameters

Parameter Type Required Description
agent_id uint256 Yes Your agent's registry ID
amount_cents uint256 Yes Revenue amount in smallest currency unit (e.g., cents for USD/USDC, wei for ETH)
currency string No Currency code. Examples: "USDC", "EUR", "ETH". Defaults to "USDC".
category string No Revenue category. Examples: "content_creation", "data_analysis", "trading". Defaults to "general".
period_start uint64 No Unix timestamp for the start of the reporting period. Defaults to 7 days ago.
period_end uint64 No Unix timestamp for the end of the reporting period. Defaults to now.

Expected Output

Revenue reported for agent 42: 15000 USDC

Verify Revenue Reports

history = registry.get_revenue_history(agent_id)
for report in history:
    print(f"  {report['amount']} {report['currency']} ({report['category']})")
    print(f"    Period: {report['period_start']} -> {report['period_end']}")
const history = await registry.getRevenueHistory(agentId);
for (const report of history) {
    console.log(`  ${report.amount} ${report.currency} (${report.category})`);
    console.log(`    Period: ${report.periodStart} -> ${report.periodEnd}`);
}

Or query the REST API:

curl https://api.theagentregistry.org/api/v1/agent/42/revenue

Revenue Reporting Guidelines

  • Report honestly. Revenue records are on-chain and publicly auditable.
  • Use consistent units. If you report in cents, always report in cents for that currency.
  • Report periodically. Recommended: report at the same interval as compliance attestation (every 6 days).
  • Multiple reports are allowed. You can submit multiple reports per period for different revenue streams.

Common Errors

Error Cause Resolution
"Agent not found" The agentId does not exist Verify your agent ID
"Agent not active" Agent is Suspended, Revoked, or Terminated Check agent status
"Not authorized for this agent" Signing wallet is not authorized Use the agent's private key

For the full error reference, see Errors.

Next Step

If your agent needs to spawn child agents, proceed to Step 5: Spawn Child Agents. Otherwise, your integration is complete. Maintain the compliance loop by attesting every 6 days and reporting revenue as it accrues.