from groq import Groq import json from solders.keypair import Keypair from solana.rpc.async_api import AsyncClient from .mongodbconnection import provideClient client=provideClient() db=client["agentpaymentdb"] coll=db["agentpaymentcol"] rpc=AsyncClient("https://mainnet.helius-rpc.com/?api-key=4e833ada-d32c-48c5-b020-c11b2253f25b") async def create_keypair(agent): """Create a new keypair and return it as MongoDB-friendly format""" try: keypair = Keypair() keypair_data = { "agent_id": agent, "public_key": str(keypair.pubkey()), "secret_key": bytes(keypair).hex() } await coll.update_one( {"owner": "system"}, {"$push": {"agents": keypair_data}} ) except Exception as e: print(e) raise def load_keypair(agent): document=coll.find_one({"owner":"system"}) keypair=None agents=document.get("agents") print(agents) for doc in agents: if doc["agent_id"]==agent: keypair=doc["secret_key"] secret_key_bytes =bytes.fromhex(keypair) keypair = Keypair.from_bytes(secret_key_bytes) print(f"✅ Keypair loaded") print(f"📍 Public Key: {keypair.pubkey()}") publickey=str(keypair.pubkey()) return publickey async def transfer_sol(agent_id, to_pubkey, amount_sol): """Transfer SOL from one account to another""" try: from_publickey=load_keypair(agent_id) lamports = int(amount_sol * 1e9) transfer_ix = transfer( TransferParams( from_pubkey=from_publickey, to_pubkey=to_pubkey, lamports=lamports )) recent_blockhash =rpc.get_latest_blockhash() txn = Transaction(recent_blockhash=recent_blockhash.value.blockhash) txn.add(transfer_ix) txn.sign(from_keypair) result = await rpc.client.send_transaction(txn, from_keypair) print(f"✅ SOL Transfer successful!") print(f"📝 Signature: {result.value}") return True except Exception as e: print(f"❌ Transfer failed: {e}") return False class VelocityPayableAgent(): def __init__(self): self.tools = [transfer_sol] def execute_tool_call(self,tool_call): """Parse and execute a single tool call""" function_name = tool_call.function.name function_to_call = available_functions[function_name] function_args = json.loads(tool_call.function.arguments) return function_to_call(**function_args) async def Agentinit(self,agent): await create_keypair(agent) def Agent(self,user_input): client = Groq(api_key="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") available_functions= { "transfer_sol":transfer_sol, } transfer_sol_tool = { "type": "function", "function": { "name": "transfer_sol", "description": "Transfer SOL from one account to other on Solana.", "parameters": { "type": "object", "properties": { "agent_id": { "type": "string", "description": "id of the agent" }, "to_pubkey": { "type": "string", "description": "Destination public key." }, "amount_sol": { "type": "number", "description": "Amount of SOL to send." } }, "required": ["from_keypair", "to_pubkey", "amount_sol"] } } } messages=[ {"role":"system","content":""" You are a tool-only agent. Rules: 1. You MUST call a tool for every query from the user. 2. You are NOT allowed to answer directly. 3. Always return tool call in the correct function-calling JSON format. 4. When unsure, still pick a tool instead of answering directly. 5. Do not apologize, do not explain, do not output reasoning—only valid tool calls. """}, {"role": "user", "content": user_input}] response = client.chat.completions.create( model="llama-3.1-8b-instant", messages=messages, tools=self.tools, ) messages.append(response.choices[0].message) if response.choices[0].message.tool_calls: for tool_call in response.choices[0].message.tool_calls: function_response = execute_tool_call(tool_call) messages.append({ "role": "tool", "tool_call_id": tool_call.id, "name": tool_call.function.name, "content": str(function_response) }) final = client.chat.completions.create( model="llama-3.1-8b-instant", messages=messages ) print(final.choices[0].message.content) return final.choices[0].message.content