Solana Agent Integration with Fetch.ai uAgents
This example shows how to integrate Solana wallets within Fetch.ai’s uAgents framework. We’ll walk through the EscrowAgent, PlayerAgent, and ChallengerAgent scripts, detailing how each agent:
- Registers with the Almanac contract (for discoverability)
- Loads Solana private keys from environment variables
- Executes transfers, checks balances, and handles bet-based business logic via Solana Devnet
- Communicates with other agents through uAgents messaging
Prerequisites
- Solana CLI (configured to Devnet)
- Poetry (for dependency management)
- Python 3.8+
- Fetch.ai’s uagents library
- Solders, requests, etc. (handled by
poetry install
) .env
with your Solana private keys (Base64 arrays) for each agent
note
Note: Each agent script runs on a different port—EscrowAgent uses :8000
, PlayerAgent uses :8001
, and ChallengerAgent uses :8002
by default.
High-Level Architecture

- PlayerAgent & ChallengerAgent each place a bet by transferring SOL to the Escrow wallet (managed by the EscrowAgent).
- EscrowAgent collects two bets, checks the BTC price via an external API, and decides a winner. 90% of the total stake is transferred to the winner’s Solana wallet; the loser forfeits.
Escrow Agent
Overview
The EscrowAgent:
- Registers on Almanac so other agents (Player/Challenger) can discover it
- Waits for two escrowRequest messages
- Fetches BTC price from Binance
- Transfers the correct portion of SOL to the winner
Script Breakdown
Required Libraries
import os
import base58
import ast
from uagents import Agent, Context, Model
from solders.keypair import Keypair
from functions import get_latest_btc_price, transfer_sol
import time
- os & ast for environment handling
- uagents for agent creation
- solders.keypair for Solana KeyPair
- functions for helper utilities (price fetch & SOL transfer)
Key Classes & Models
class escrowRequest(Model):
amount: float
price: float
public_key: str
class escrowResponse(Model):
result: str
- escrowRequest holds the user’s desired bet:
amount
,price
, and the user’s Solana public key. - escrowResponse returns the result to the user: either
"You Won"
or"You Lost"
.
Initialization & Identity
# Retrieve ESCROW_SECRET_LIST from the .env
escrow_secret_key_str = os.getenv('ESCROW_SECRET_LIST')
escrow_secret_key_list = ast.literal_eval(escrow_secret_key_str)
escrow_secret_key_bytes = bytes(escrow_secret_key_list)
escrow_keypair = Keypair.from_bytes(escrow_secret_key_bytes)
escrow_pubkey_base58 = base58.b58encode(bytes(escrow_keypair.pubkey())).decode('utf-8')
agent = Agent(
name="EscrowAgent",
port=8000,
seed="Escrow Wallet",
endpoint=["http://127.0.0.1:8000/submit"],
)
- We decode the Solana private key from
.env
. - Create a
Keypair
for the Escrow’s wallet. - Instantiate a
uagents.Agent
with the name “EscrowAgent” listening on port8000
.
On Startup
@agent.on_event('startup')
async def saf(ctx: Context):
ctx.logger.info("Escrow agent initialized, ready for bids.")
ctx.logger.info(f"Escrow agent address: {agent.address}")
ctx.storage.set("bids_count", 0)
- Logs that the Escrow is online.
- Initializes a storage key bids_count=0 to track how many requests have come in.
Message Handling
Receiving Bets
@agent.on_message(model=escrowRequest, replies={escrowResponse})
async def escrow_request_handler(ctx: Context, sender: str, msg: escrowRequest):
current_count = ctx.storage.get("bids_count") or 0
...
if current_count == 0:
# Store first bet
elif current_count == 1:
# Store second bet
# Compare
# Transfer to winner
# Respond with escrowResponse
# Reset storage
- First Bet: If
bids_count=0
, store the details (amount, price, user’s pubkey). - Second Bet: If
bids_count=1
, store the second user’s bet, then callget_latest_btc_price()
. - Calculate each user’s distance from the real BTC price.
- Transfer 90% of the total stake to the winner’s public key with
transfer_sol()
. - Send escrowResponse messages to both the winner
(You Won)
and loser(You Lost)
. - Reset internal storage.
Running the EscrowAgent
if __name__ == "__main__":
agent.run()
- Save the script as
escrow_agent.py
- Simply run
poetry run python escrow_agent.py
.
Player Agent
Overview
The PlayerAgent simulates a user placing a bet on BTC’s future price.