A2A Protocol

The Starknet A2A Adapter implements Google's Agent-to-Agent (A2A) protocol for Starknet-native agents. It bridges on-chain identity (ERC-8004) with A2A discovery, enabling agents to find and communicate with each other.

Overview

A2A is an open protocol for agent interoperability. It defines:

  • Agent Cards - JSON documents describing an agent's capabilities
  • Discovery - Standard endpoint at /.well-known/agent.json
  • Task Protocol - Request/response pattern for agent interactions

The Starknet A2A Adapter adds:

  • On-chain Identity - Agent Cards generated from ERC-8004 registry data
  • Reputation Integration - Reputation scores included in Agent Cards
  • Transaction Tracking - A2A tasks mapped to Starknet transactions

Installation

npm install @starknet-agentic/a2a starknet

Quick Start

import { createStarknetA2AAdapter } from "@starknet-agentic/a2a";

const adapter = createStarknetA2AAdapter({
  rpcUrl: process.env.STARKNET_RPC_URL,
  identityRegistryAddress: "0x...",
  reputationRegistryAddress: "0x...",  // Optional
  validationRegistryAddress: "0x...",  // Optional
});

// Generate Agent Card from on-chain identity
const card = await adapter.generateAgentCard(agentId);

API Reference

createStarknetA2AAdapter(config)

Creates a new adapter instance.

Parameters:

ParameterTypeRequiredDescription
rpcUrlstringYesStarknet JSON-RPC endpoint
identityRegistryAddressstringYesERC-8004 Identity Registry address
reputationRegistryAddressstringNoERC-8004 Reputation Registry address
validationRegistryAddressstringNoERC-8004 Validation Registry address

Returns: StarknetA2AAdapter


adapter.generateAgentCard(agentId)

Generates an A2A Agent Card from on-chain identity data.

Parameters:

ParameterTypeDescription
agentIdstringAgent's on-chain ID (NFT token ID)

Returns: Promise<AgentCard>

interface AgentCard {
  name: string;
  description: string;
  url?: string;
  version: string;
  skills: string[];
  starknetIdentity?: {
    registryAddress: string;
    agentId: string;
    reputationScore?: number;
    validationCount?: number;
    walletAddress?: string;
  };
}

Example:

const card = await adapter.generateAgentCard("42");
console.log(card);
// {
//   name: "TradingBot",
//   description: "Autonomous DeFi trading agent",
//   url: "https://trading-bot.example.com",
//   version: "1.0",
//   skills: ["swap", "stake", "lend"],
//   starknetIdentity: {
//     registryAddress: "0x...",
//     agentId: "42",
//     reputationScore: 85,
//     validationCount: 3,
//   }
// }

adapter.registerAgent(account, metadata)

Registers a new agent identity on-chain.

Parameters:

ParameterTypeDescription
accountAccountstarknet.js Account instance
metadata.namestringAgent display name
metadata.descriptionstringAgent description
metadata.a2aEndpointstringOptional A2A endpoint URL
metadata.capabilitiesstring[]Optional list of capabilities

Returns: Promise<string> - Transaction hash

Example:

import { Account, RpcProvider } from "starknet";

const account = new Account(provider, address, privateKey);

const txHash = await adapter.registerAgent(account, {
  name: "MyAgent",
  description: "A helpful trading assistant",
  a2aEndpoint: "https://my-agent.example.com",
  capabilities: ["swap", "transfer", "stake"],
});

adapter.generateWellKnownAgentJson(agentId, baseUrl)

Generates the /.well-known/agent.json content for A2A discovery.

Parameters:

ParameterTypeDescription
agentIdstringAgent's on-chain ID
baseUrlstringBase URL where the agent is hosted

Returns: Promise<object>

Example:

const wellKnown = await adapter.generateWellKnownAgentJson(
  "42",
  "https://my-agent.example.com"
);

// Serve at /.well-known/agent.json
// {
//   "@context": "https://a2a-protocol.org/schema/1.0",
//   "type": "Agent",
//   "id": "https://my-agent.example.com/.well-known/agent.json",
//   "name": "TradingBot",
//   "description": "Autonomous DeFi trading agent",
//   "url": "https://my-agent.example.com",
//   "version": "1.0",
//   "capabilities": ["swap", "stake", "lend"],
//   "identity": {
//     "starknet": { ... }
//   },
//   "endpoints": {
//     "tasks": "https://my-agent.example.com/api/tasks",
//     "status": "https://my-agent.example.com/api/tasks/:id"
//   }
// }

adapter.createTaskFromTransaction(transactionHash, prompt)

Creates an A2A task tracker for a Starknet transaction.

Parameters:

ParameterTypeDescription
transactionHashstringStarknet transaction hash
promptstringTask description/prompt

Returns: Task

interface Task {
  id: string;
  state: TaskState;
  prompt: string;
  result?: string;
  transactionHash?: string;
  error?: string;
  createdAt: number;
  updatedAt: number;
}

enum TaskState {
  Submitted = "submitted",
  Working = "working",
  Completed = "completed",
  Failed = "failed",
  Canceled = "canceled",
}

adapter.getTaskStatus(taskId)

Gets task status by checking transaction state on-chain.

Parameters:

ParameterTypeDescription
taskIdstringTask ID (transaction hash)

Returns: Promise<Task>

Example:

const task = await adapter.getTaskStatus(transactionHash);

if (task.state === TaskState.Completed) {
  console.log("Transaction succeeded:", task.result);
} else if (task.state === TaskState.Failed) {
  console.error("Transaction failed:", task.error);
}

Serving Agent Discovery

Generate Agent Card

const wellKnown = await adapter.generateWellKnownAgentJson(
  agentId,
  "https://your-agent.com"
);

Serve at well-known endpoint

// Express.js example
app.get("/.well-known/agent.json", async (req, res) => {
  const agentJson = await adapter.generateWellKnownAgentJson(
    process.env.AGENT_ID,
    `https://${req.hostname}`
  );
  res.json(agentJson);
});

Other agents discover you

// Another agent discovers your agent
const response = await fetch("https://your-agent.com/.well-known/agent.json");
const agentCard = await response.json();

// Verify on-chain identity
const onChainCard = await theirAdapter.generateAgentCard(
  agentCard.identity.starknet.agentId
);

Task Flow Example

// Agent receives a task request
const taskRequest = {
  prompt: "Swap 10 USDC for STRK",
};

// Execute the swap
const { transaction_hash } = await account.execute(swapCall);

// Create task tracker
const task = adapter.createTaskFromTransaction(
  transaction_hash,
  taskRequest.prompt
);

// Return task ID to requester
return { taskId: task.id };

// Later: requester checks status
const status = await adapter.getTaskStatus(taskId);

Integration with ERC-8004

The A2A adapter reads agent data from the ERC-8004 Identity Registry:

A2A FieldERC-8004 Source
nameagentName metadata
descriptionagentDescription metadata
urla2aEndpoint metadata
capabilitiescapabilities metadata (comma-separated)
reputationScoreReputation Registry get_summary()
validationCountValidation Registry get_validation_count()

On-Chain Truth

Agent Cards generated by this adapter reflect the current on-chain state. Updates to the Identity Registry are immediately reflected in generated cards.

Error Handling

try {
  const card = await adapter.generateAgentCard(agentId);
} catch (error) {
  if (error.message.includes("Failed to generate agent card")) {
    // Agent doesn't exist or registry call failed
    console.error("Agent not found:", agentId);
  }
}

References