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.
Method A: Using the SDK (Recommended)¶
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¶
Verify Revenue Reports¶
Or query the REST API:
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.