Securing AI Agent Interactions in Web3: A Guide to Blockchain Transaction Models

security

Secure AI agents in Web3 blockchain transactions. This guide explores custodial and non-custodial models, outlines risks, and demonstrates building safe, user-centric systems with Google Cloud tools.

Google Cloud is positioned at the nexus of two revolutionary technologies: AI and Web3. The emergence of AI agents that can interact with blockchains promises significant advancements, including automated financial strategies, rapid payments, and sophisticated operations like executing complex DeFi operations and bridging assets across multiple chains.

However, the successful implementation of this new paradigm critically depends on who hosts the agent and who holds the private key for these operations.

The core issue is straightforward. Since most cryptocurrency users are unlikely to run their own secure servers to manage agent keys, providers typically adopt one of two primary architectures: a custodial model, where users delegate funds to a third-party agent that controls a private key, or a non-custodial model, where the agent only crafts transactions for the user to sign with their own private key.

Most current examples show agents directly holding a private key, and many cryptocurrency model context protocol (MCP) servers require configuration with a private key. However, this is not the only viable approach.

The Agent-Controlled Model

This model is designed for a future where users primarily interact with agents hosted by a third party—a realistic assumption for mainstream adoption. In this scenario, you do not provide your private key to the agent. Instead, the agent possesses its own key, and you grant it an allowance to spend on your behalf.

How it works

Agent-controlled model sequence diagram.

  • Agent Gets a Wallet: The agent holds one or multiple private keys, securely managed by the agent's host, never by you.
  • User Delegates Funds: From your personal wallet (e.g., MetaMask or a hardware wallet), you send a specific amount to the agent’s public address.
  • Agent Gains Autonomy: The agent then has full, autonomous control over the funds in its wallet. It can use its key to sign and execute transactions—such as swapping tokens, buying NFTs, or paying other agents for data—until the pre-paid balance is exhausted.

The inherent risks

While this model offers automation, it introduces significant risks that are shifted from you to the agent and its host.

  • Performance Risk: The agent might perform poorly. For instance, a trading agent could execute a flawed strategy and lose the delegated funds.
  • Malice Risk: A poorly designed or intentionally malicious agent could misuse funds. For example, it could send its balance to an unauthorized address. To mitigate this, the hosting platform should implement robust safeguards, audits, and rules to constrain agent behavior. Another option is to secure agent funds within a smart contract that guarantees specific usage.
  • Security Risk: The third-party host becomes a custodian of your delegated funds. If their platform is compromised and agent private keys are exposed, your pre-paid balance would be a primary target.

The Self-Hosted Variant

A small minority of technically advanced users may prefer to run this model on a personal server. Given the nascent stage of AI agent development, this group of developers and early adopters represents the current primary user base.

Consequently, this self-hosted model is commonly encountered today, and most crypto MCP servers are built to support it. In this context, it is technically viable to give the agent a private key because the key remains within the user's controlled environment.

Self-hosted agent model sequence diagram.

However, this approach also carries a very high risk. Your private key can be compromised if your machine is hacked, and erratic, unauthorized agent behavior can lead to significant losses.

For example, if you instruct, “I want to swap 500 USD for UNI,” the agent might mistakenly sell UNI, buy the wrong UNI token, or mismanage slippage. This approach is recommended only for testing purposes.

The Transaction-Crafter Model

This is the non-custodial and fundamentally more secure alternative for most user interactions. Here, the agent never holds any of your funds. Its purpose is identical to the agent-controlled model, but instead of signing and sending the transaction, it returns the unsigned transaction for the user to sign and submit to the blockchain network.

How it works

Transaction crafter model sequence diagram.

  • User Instructs Agent: You ask the agent to perform a task, such as “swap my ETH for USDC.”
  • Agent Crafts the Transaction: The agent analyzes your query and constructs the raw transaction (e.g., a swap transaction).
  • User Signs the Transaction: The agent passes this data back to you. Your wallet displays a pop-up showing precisely what you are about to do. Only you can approve and sign it with your private key.

How to Build the Agent with Google Cloud Tools

To demonstrate this model, a sample agent was built using a suite of Google Cloud tools. The agent’s reasoning is powered by the Gemini 2.0 Flash model and orchestrated using the Google Agent Development Kit (ADK). For testing, funds were acquired from the public Google Cloud Ethereum Faucet, a key resource for developers.

Developing agents with ADK is straightforward and includes useful features such as a web UI for simple testing and development, powerful integration with Agent Engine and Google Cloud Run for easy production deployment, a simple method to run the agent as an API server for frontend connection, and a toolbox for connecting to MCP Servers, Agent-to-Agent (A2A) protocol, and tools like Google Search.

For more details on building agents using the Google Cloud stack, refer to relevant documentation.

Diagram showing agent and frontend interaction.

The two main components of this application are the agent that crafts transactions and the frontend that retrieves the crafted transaction from the agent and sends it to MetaMask for signature and submission.

The agent development using Google ADK is relatively simple, though the craft_eth_transaction function can be quite complex depending on the types of operations supported (chains, assets, swaps):

from google.adk.agents import Agent
from web3 import Web3

ETH_RPC_URL = "RPC URL"

# (This is the tool function defined in the next section)
def craft_eth_transaction(to_address: str, amount: float, from_address: str, chain_id: int):
   # Step 1: Fetch the sender's next transaction count (nonce)
   # Step 2: Determine transaction type (ETH transfer or smart contract call)
   # Step 3: Construct the 'data' field using ABI
   # Step 4: Assemble and return the final, unsigned transaction

# The Agent is defined with a simple, non-custodial instruction
root_agent = Agent(
   name="transaction_crafter_agent",
   model="gemini-2.0-flash",
   description="An agent that crafts Ethereum transactions for a front-end to send via MetaMask.",
   instruction=(
       "You are an agent that crafts ETH transactions. "
       "Your only job is to collect the information from the user to craft Ethereum transactions.. "
       "The sender's address will be provided to you as context, along with the chain ID." \
       "Use the `craft_eth_transaction` tool to generate the transaction object. " \
       "The tool will return a JSON object that is ready to be sent to MetaMask. " \
       "Leave gas and gasPrice fields empty; MetaMask will set them." \
       "**IMPORTANT:** After using the tool, you must present the final transaction JSON in the response, formatted exactly like this:
"
       "   ```json
"
       "   {
"
       "     \"to\": \"0x...\",
"
       "     \"from\": \"0x...\",
"
       "     \"value\": \"0x...\",
"
       "     \"nonce\": \"0x...\",
"
       "     \"chainId\": \"0xaa36a7\"
"
       "   }
"
       "   ```
"
   ),
   tools=[craft_eth_transaction],
)

On the client-side, the logic is clean and focused on Web3 interactions. The frontend does not need to understand large-language models (LLMs) or agent orchestration. It calls the agent's API endpoint (hosted on Google Cloud Run), receives a standard JSON transaction object, and passes it to MetaMask.

ADK’s ability to easily run the agent as an API server provides this clear separation of concerns. The two main frontend functions involve extracting the transaction from the agent’s response and sending it to MetaMask. Here’s an example of these functions:

/**
* Step 1: Process the agent's response to extract the crafted transaction data.
* The agent's only output is a standard, unsigned transaction object.
*/
function extractTransactionFromAgentResponse(agentEvents) {
   const functionResponse = agentEvents.find(
       e => e.content?.parts?.[0]?.functionResponse?.name === 'craft_eth_transaction'
   )?.content.parts[0].functionResponse;

   if (functionResponse?.response?.success) {
       // The raw transaction object, ready for the user's wallet
       return functionResponse.response.transaction;
   }
   return null;
}

/**
* Step 2: Pass the crafted transaction to the user's wallet for execution.
* This function triggers a MetaMask pop-up, putting the user in full control.
*/
async function executeMetaMaskTransaction(txData) {
   if (!txData || typeof window.ethereum === 'undefined') {
       console.error("Invalid transaction data or MetaMask not found.");
       return;
   }

   try {
       // The 'eth_sendTransaction' call asks the wallet to sign and send.
       // The private key is never exposed to our web application.
       const txHash = await window.ethereum.request({
           method: 'eth_sendTransaction',
           params: [txData], // txData is the JSON object from the agent
       });

       console.log(`Transaction sent successfully! Hash: ${txHash}`);
       return txHash;

   } catch (error) {
       // This error typically means the user rejected the transaction in MetaMask.
       console.error("Transaction failed or was rejected by user:", error);
   }
}

How the Agent Confirms Intent

While the agent’s operation facilitates the dialogue leading to a decision, the MetaMask pop-up represents the conclusion of that conversation. It functions as the digital equivalent of a financial advisor explaining a strategy and then presenting the final document for signature. The signature serves as the deliberate, necessary confirmation that you understand and consent to the action, providing crucial peace of mind.

Especially considering that an agent’s interpretation can vary significantly based on the underlying LLM, conversational context, and available data, it is always prudent to double-check a wallet transaction before approval.

MCP Servers Should Serve Both Realities

The vision of a future where agents autonomously pay other agents for services necessitates the agent-controlled model, as agents in this economy will require their own capital to operate.

However, the transaction-crafter model offers a secure bridge to that future. It can be safely used to fund an agent or to execute one-off transactions for simpler operations, providing essential flexibility.

From a developer's perspective, adding this capability should not be a major undertaking. If an MCP server can already prepare and sign a transaction with a key it holds, it should be capable of performing the same logic without the final signing step, returning the unsigned transaction instead. This minor modification enables a much safer and more flexible paradigm for users and can even facilitate more complex designs, such as a dedicated “signer agent” within a multi-agent system.

Therefore, any robust MCP server designed for broad adoption should provide developers with the flexibility to build applications that can:

  • Advise and craft for secure, user-centric financial decisions.
  • Execute with delegated funds for specialized, automated, and clearly defined tasks.

We recommend pursuing this dual support to foster genuine innovation while protecting users.