Solana Agent Integration with Fetch.ai uAgents
This Solana Devnet demo wires three local uAgents to Solana wallets: EscrowAgent, PlayerAgent, and ChallengerAgent. Players transfer SOL to escrow first, then send a typed message that includes the deposit transaction signature. Escrow verifies both deposits on Devnet, compares each spot BTC/USDT guess to Binance, and pays the full matched pot to the closer guess.
This is a local demo with a configured Escrow address. Agents use endpoint= on loopback. They do not discover each other through Almanac. Copy the Escrow uAgent address and Solana pubkey from Escrow startup logs into .env before starting the players.
See also AI Agents Reshaping the On-Chain Ecosystem and BNB Chain Agents. Solana secret lists are wallet keypairs (64-byte JSON integer arrays). The uAgent seed= string is a separate Fetch.ai identity; it does not derive your Solana pubkey.
This tutorial is a Solana Devnet programming sample. Do not use mainnet, real funds, or production keys. It is not financial advice, not a licensed gambling product, and not a price-prediction market. Any keys that ever appeared in git (including the linked community repo) are burned — generate new keypairs.
The original walkthrough lived in a personal repo, abhifetch/solana-fetch-uagents-integration (last updated 2024). Treat that tree as community / stale: it pins uagents ^0.1.0 and Python 3.8, and its example.env / README published full secret arrays. Do not copy those keys. Use the code on this page with uagents==0.25.5.
Prerequisites
Ordered setup:
- Clone or create a project folder and
cdinto it. - Install Python 3.10+ (current uAgents adapters expect ≥3.10; do not use 3.8).
- Install the Solana CLI and point it at Devnet.
- Create a venv, then install the pins below (Poetry is optional).
- Generate three new Solana keypairs (
solana-keygen new). Convert each JSON file to an env var without pasting real keys into chat, docs, or git. - Airdrop Devnet SOL to player, challenger, and escrow (escrow must cover payout plus network fees).
- Run Escrow first, copy its logged addresses into
.env, then start Player and Challenger. Leave both clients running until they receiveEscrowResponse.
Default local ports: Escrow :8000, Player :8001, Challenger :8002.
High-level architecture

- Player and Challenger each send equal SOL amounts to the Escrow Solana wallet and wait for confirmation.
- They then message Escrow with amount, spot BTC/USDT guess, their Solana pubkey, and the deposit tx signature.
- Escrow verifies both deposits on Devnet, requires equal stakes, fetches Binance spot
BTCUSDT, and transfers the entire pot to the closer guess. Solana fees are paid by the escrow wallet, so fund extra SOL there.
This is not a futures bet. Escrow compares guesses to the spot ticker at match time.
Fetch wallet vs Solana wallet
| Wallet | What it is | How you fund it |
|---|---|---|
| Solana Devnet keypair | ESCROW_SECRET_LIST / PLAYER_SECRET_LIST / CHALLENGER_SECRET_LIST | solana airdrop … --url devnet |
| uAgent identity | seed= string → agent.address (agent1…) | Separate from SOL. fund_agent_if_low (if you import it) tops up the Fetch/Almanac wallet, not Devnet SOL. This demo uses local endpoints, so skip it unless you add mailbox/testnet registration. |
Do not set AGENTVERSE_API_KEY unless you switch these agents to Agentverse mailbox. The scripts below do not read that variable.
Dependencies
python -m venv venv
source venv/bin/activate
Windows:
python -m venv venv
venv\Scripts\activate
uagents==0.25.5
python-dotenv==1.0.1
requests==2.32.3
solana==0.36.6
solders==0.26.0
base58==2.1.1
pip install -r requirements.txt
Optional Poetry pins (replace any uagents = "^0.1.0" / python = "^3.8" from the old community repo):
[tool.poetry.dependencies]
python = "^3.10"
uagents = "0.25.5"
python-dotenv = "1.0.1"
requests = "2.32.3"
solana = "0.36.6"
solders = "0.26.0"
base58 = "2.1.1"
Keys and .env (placeholders only)
Format is a JSON integer array of 64 bytes, not Base64. solana-keygen new --outfile wallet.json already writes that array.
solana config set --url https://api.devnet.solana.com
solana-keygen new --outfile player-wallet.json --no-bip39-passphrase
solana-keygen new --outfile challenger-wallet.json --no-bip39-passphrase
solana-keygen new --outfile escrow-wallet.json --no-bip39-passphrase
Put each file’s single JSON line into .env yourself. Never commit .env or wallet JSON. Rotate any key that was ever committed (including prefixes shown in older versions of this page).
# Placeholders — replace with YOUR 64-integer arrays. Do not reuse published keys.
PLAYER_SECRET_LIST=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
CHALLENGER_SECRET_LIST=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
ESCROW_SECRET_LIST=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
# Filled from EscrowAgent startup logs — do not hardcode a third-party address.
ESCROW_AGENT_ADDRESS=agent1q...your_local_escrow_address
ESCROW_SOLANA_PUBKEY=YourEscrowSolanaPubkeyBase58
PLAYER_BET_AMOUNT=0.1
PLAYER_BTC_GUESS=65000
CHALLENGER_BET_AMOUNT=0.1
CHALLENGER_BTC_GUESS=64000
[0,0,…] is invalid as a real keypair; it only shows the shape. After Escrow prints Escrow agent address and Escrow Solana pubkey, copy those values into ESCROW_AGENT_ADDRESS and ESCROW_SOLANA_PUBKEY.
Shared models
from uagents import Model
class EscrowRequest(Model):
amount: float
price: float
public_key: str
deposit_tx_sig: str
class EscrowResponse(Model):
result: str