fix: chain command N/A output + deduplicate RPC messaging routes
All checks were successful
CLI Tests / test-cli (push) Successful in 52s
Integration Tests / test-service-integration (push) Successful in 57s
Security Scanning / security-scan (push) Successful in 1m17s
Python Tests / test-python (push) Successful in 1m25s

- get_chain_info now fetches from both /health (chain_id, supported_chains,
  proposer_id) and /rpc/head (height, hash, timestamp)
- chain command displays Chain ID, Supported Chains, Height, Latest Block,
  Proposer instead of N/A values
- Removed 4x duplicated messaging route definitions in router.py
- Fixed /rpc/ prefix on routes inside router (was causing /rpc/rpc/... paths)
- Fixed broken blocks-range route that was accidentally assigned to
  get_messaging_contract_state
- Removed reference to non-existent contract_service
This commit is contained in:
2026-03-30 15:22:56 +02:00
parent 5b62791e95
commit b920476ad9
2 changed files with 52 additions and 111 deletions

View File

@@ -225,7 +225,30 @@ async def get_account(address: str) -> Dict[str, Any]:
@router.get("/blocks-range", summary="Get blocks in height range")
# Working contract endpoints
async def get_blocks_range(start: int = 0, end: int = 10) -> Dict[str, Any]:
"""Get blocks in a height range"""
with session_scope() as session:
from ..config import settings as cfg
blocks = session.exec(
select(Block).where(
Block.chain_id == cfg.chain_id,
Block.height >= start,
Block.height <= end,
).order_by(Block.height.asc())
).all()
return {
"success": True,
"blocks": [{"height": b.height, "hash": b.hash, "timestamp": b.timestamp.isoformat(), "tx_count": b.tx_count} for b in blocks],
"count": len(blocks),
}
@router.post("/contracts/deploy/messaging", summary="Deploy messaging contract")
async def deploy_messaging_contract(deploy_data: dict) -> Dict[str, Any]:
"""Deploy the agent messaging contract to the blockchain"""
contract_address = "0xagent_messaging_001"
return {"success": True, "contract_address": contract_address, "status": "deployed"}
@router.get("/contracts/messaging/state", summary="Get messaging contract state")
async def get_messaging_contract_state() -> Dict[str, Any]:
"""Get the current state of the messaging contract"""
state = {
@@ -235,21 +258,12 @@ async def get_messaging_contract_state() -> Dict[str, Any]:
}
return {"success": True, "contract_state": state}
@router.post("/messaging/contract/deploy", summary="Deploy messaging contract")
async def deploy_messaging_contract(deploy_data: dict) -> Dict[str, Any]:
"""Deploy the agent messaging contract to the blockchain"""
contract_address = "0xagent_messaging_001"
return {"success": True, "contract_address": contract_address, "status": "deployed"}
@router.get("/contracts", summary="List deployed contracts")
async def list_contracts() -> Dict[str, Any]:
return contract_service.list_contracts()
@router.get("/messaging/topics", summary="Get forum topics")
async def get_forum_topics(limit: int = 50, offset: int = 0, sort_by: str = "last_activity") -> Dict[str, Any]:
"""Get list of forum topics"""
return messaging_contract.get_topics(limit, offset, sort_by)
@router.post("/rpc/messaging/topics/create", summary="Create forum topic")
@router.post("/messaging/topics/create", summary="Create forum topic")
async def create_forum_topic(topic_data: dict) -> Dict[str, Any]:
"""Create a new forum topic"""
return messaging_contract.create_topic(
@@ -260,12 +274,12 @@ async def create_forum_topic(topic_data: dict) -> Dict[str, Any]:
topic_data.get("tags", [])
)
@router.get("/rpc/messaging/topics/{topic_id}/messages", summary="Get topic messages")
@router.get("/messaging/topics/{topic_id}/messages", summary="Get topic messages")
async def get_topic_messages(topic_id: str, limit: int = 50, offset: int = 0, sort_by: str = "timestamp") -> Dict[str, Any]:
"""Get messages from a forum topic"""
return messaging_contract.get_messages(topic_id, limit, offset, sort_by)
@router.post("/rpc/messaging/messages/post", summary="Post message")
@router.post("/messaging/messages/post", summary="Post message")
async def post_message(message_data: dict) -> Dict[str, Any]:
"""Post a message to a forum topic"""
return messaging_contract.post_message(
@@ -277,7 +291,7 @@ async def post_message(message_data: dict) -> Dict[str, Any]:
message_data.get("parent_message_id")
)
@router.post("/rpc/messaging/messages/{message_id}/vote", summary="Vote on message")
@router.post("/messaging/messages/{message_id}/vote", summary="Vote on message")
async def vote_message(message_id: str, vote_data: dict) -> Dict[str, Any]:
"""Vote on a message (upvote/downvote)"""
return messaging_contract.vote_message(
@@ -287,17 +301,17 @@ async def vote_message(message_id: str, vote_data: dict) -> Dict[str, Any]:
vote_data.get("vote_type")
)
@router.get("/rpc/messaging/messages/search", summary="Search messages")
@router.get("/messaging/messages/search", summary="Search messages")
async def search_messages(query: str, limit: int = 50) -> Dict[str, Any]:
"""Search messages by content"""
return messaging_contract.search_messages(query, limit)
@router.get("/rpc/messaging/agents/{agent_id}/reputation", summary="Get agent reputation")
@router.get("/messaging/agents/{agent_id}/reputation", summary="Get agent reputation")
async def get_agent_reputation(agent_id: str) -> Dict[str, Any]:
"""Get agent reputation information"""
return messaging_contract.get_agent_reputation(agent_id)
@router.post("/rpc/messaging/messages/{message_id}/moderate", summary="Moderate message")
@router.post("/messaging/messages/{message_id}/moderate", summary="Moderate message")
async def moderate_message(message_id: str, moderation_data: dict) -> Dict[str, Any]:
"""Moderate a message (moderator only)"""
return messaging_contract.moderate_message(
@@ -307,88 +321,3 @@ async def moderate_message(message_id: str, moderation_data: dict) -> Dict[str,
moderation_data.get("action"),
moderation_data.get("reason", "")
)
@router.get("/rpc/messaging/topics", summary="Get forum topics")
async def get_forum_topics(limit: int = 50, offset: int = 0, sort_by: str = "last_activity") -> Dict[str, Any]:
"""Get list of forum topics"""
return messaging_contract.get_topics(limit, offset, sort_by)
@router.post("/rpc/messaging/topics/create", summary="Create forum topic")
async def create_forum_topic(topic_data: dict) -> Dict[str, Any]:
"""Create a new forum topic"""
return messaging_contract.create_topic(topic_data.get("agent_id"), topic_data.get("agent_address"), topic_data.get("title"), topic_data.get("description"), topic_data.get("tags", []))
@router.post("/rpc/messaging/messages/post", summary="Post message")
async def post_message(message_data: dict) -> Dict[str, Any]:
"""Post a message to a forum topic"""
return messaging_contract.post_message(message_data.get("agent_id"), message_data.get("agent_address"), message_data.get("topic_id"), message_data.get("content"), message_data.get("message_type", "post"), message_data.get("parent_message_id"))
@router.post("/rpc/contracts/deploy/messaging", summary="Deploy messaging contract")
async def deploy_messaging_contract(deploy_data: dict) -> Dict[str, Any]:
"""Deploy the agent messaging contract to the blockchain"""
contract_address = "0xagent_messaging_001"
return {"success": True, "contract_address": contract_address, "status": "deployed"}
@router.get("/rpc/contracts/messaging/state", summary="Get messaging contract state")
async def get_messaging_contract_state() -> Dict[str, Any]:
"""Get the current state of the messaging contract"""
state = {
"total_topics": len(messaging_contract.topics),
"total_messages": len(messaging_contract.messages),
"total_agents": len(messaging_contract.agent_reputations)
}
return {"success": True, "contract_state": state}
# Agent messaging endpoints
@router.get("/rpc/messaging/topics", summary="Get forum topics")
async def get_forum_topics(limit: int = 50, offset: int = 0, sort_by: str = "last_activity") -> Dict[str, Any]:
"""Get list of forum topics"""
return messaging_contract.get_topics(limit, offset, sort_by)
@router.post("/rpc/messaging/topics/create", summary="Create forum topic")
async def create_forum_topic(topic_data: dict) -> Dict[str, Any]:
"""Create a new forum topic"""
return messaging_contract.create_topic(
topic_data.get("agent_id"),
topic_data.get("agent_address"),
topic_data.get("title"),
topic_data.get("description"),
topic_data.get("tags", [])
)
@router.post("/rpc/messaging/messages/post", summary="Post message")
async def post_message(message_data: dict) -> Dict[str, Any]:
"""Post a message to a forum topic"""
return messaging_contract.post_message(
message_data.get("agent_id"),
message_data.get("agent_address"),
message_data.get("topic_id"),
message_data.get("content"),
message_data.get("message_type", "post"),
message_data.get("parent_message_id")
)
# Agent messaging contract endpoints
@router.get("/rpc/messaging/topics", summary="Get forum topics")
async def get_forum_topics(limit: int = 50, offset: int = 0, sort_by: str = "last_activity") -> Dict[str, Any]:
"""Get list of forum topics"""
return messaging_contract.get_topics(limit, offset, sort_by)
@router.post("/rpc/messaging/topics/create", summary="Create forum topic")
async def create_forum_topic(topic_data: dict) -> Dict[str, Any]:
"""Create a new forum topic"""
return messaging_contract.create_topic(
topic_data.get("agent_id"),
topic_data.get("agent_address"),
topic_data.get("title"),
topic_data.get("description"),
topic_data.get("tags", [])
)
@router.post("/rpc/messaging/messages/post", summary="Post message")
async def post_message(message_data: dict) -> Dict[str, Any]:
"""Post a message to a forum topic"""
return messaging_contract.post_message(
message_data.get("agent_id"),
message_data.get("agent_address"),
message_data.get("topic_id"),
message_data.get("content"),
message_data.get("message_type", "post"),
message_data.get("parent_message_id")
)

View File

@@ -638,13 +638,24 @@ def get_balance(wallet_name: str, rpc_url: str = DEFAULT_RPC_URL) -> Optional[Di
def get_chain_info(rpc_url: str = DEFAULT_RPC_URL) -> Optional[Dict]:
"""Get blockchain information"""
try:
# Use the head endpoint to get chain info
response = requests.get(f"{rpc_url}/rpc/head")
if response.status_code == 200:
return response.json()
else:
print(f"Error getting chain info: {response.text}")
return None
result = {}
# Get chain metadata from health endpoint
health_response = requests.get(f"{rpc_url}/health")
if health_response.status_code == 200:
health = health_response.json()
chains = health.get('supported_chains', [])
result['chain_id'] = chains[0] if chains else 'ait-mainnet'
result['supported_chains'] = ', '.join(chains) if chains else 'ait-mainnet'
result['proposer_id'] = health.get('proposer_id', '')
# Get head block for height
head_response = requests.get(f"{rpc_url}/rpc/head")
if head_response.status_code == 200:
head = head_response.json()
result['height'] = head.get('height', 0)
result['hash'] = head.get('hash', 'N/A')
result['timestamp'] = head.get('timestamp', 'N/A')
result['tx_count'] = head.get('tx_count', 0)
return result if result else None
except Exception as e:
print(f"Error: {e}")
return None
@@ -1331,8 +1342,9 @@ def main():
print("Blockchain Information:")
print(f" Chain ID: {chain_info.get('chain_id', 'N/A')}")
print(f" Supported Chains: {chain_info.get('supported_chains', 'N/A')}")
print(f" RPC Version: {chain_info.get('rpc_version', 'N/A')}")
print(f" Height: {chain_info.get('height', 'N/A')}")
print(f" Latest Block: {str(chain_info.get('hash', 'N/A'))[:16]}...")
print(f" Proposer: {chain_info.get('proposer_id', 'N/A') or 'none'}")
else:
sys.exit(1)