### Clone and Install Dependencies Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/02-register-agent.md Initial setup commands to prepare the local development environment. ```bash git clone https://github.com/Stephen-Kimoi/ai-trading-agent-template cd ai-trading-agent-template npm install ``` -------------------------------- ### Setup Project Environment Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/README.md Commands to clone the repository, install dependencies, and initialize the environment configuration. ```bash git clone cd ai-trading-agent-tutorial npm install cp .env.example .env # Fill in SEPOLIA_RPC_URL, PRIVATE_KEY, KRAKEN_API_KEY, KRAKEN_API_SECRET ``` -------------------------------- ### Install Kraken CLI Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Use this script to install the Kraken CLI on Linux/macOS. Verify the installation by checking the version. ```bash # install script (Linux/macOS) curl --proto '=https' --tlsv1.2 -LsSf https://github.com/krakenfx/kraken-cli/releases/latest/download/kraken-cli-installer.sh | sh # check out the version kraken --version ``` -------------------------------- ### Launch Dashboard Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/07-reusable-template.md Starts the live web dashboard that monitors agent activity and checkpoints. ```bash npm run dashboard # → http://localhost:3000 ``` -------------------------------- ### Example Reasoning Strings Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/05-explanation-layer.md Illustrates good and bad examples of reasoning strings for trade decisions. Good examples are specific and auditable, while bad examples are too vague. ```text // Good: specific, auditable "Price fell 1.2% over last 5 ticks while volume dropped 40% below average. Bearish divergence — selling to reduce exposure. Risk: potential support at $94,200 may reverse the move." // Bad: too vague "The market looks bad." ``` -------------------------------- ### Start Kraken MCP Server Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Command to start the Kraken CLI's built-in MCP (Model Context Protocol) server on a specified port. This is the preferred integration method for agents using MCP. ```bash # Start the MCP server kraken mcp serve --port 8080 ``` -------------------------------- ### Run Agent and Dashboard Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/README.md Commands to start the agent loop and the live dashboard in separate terminals. ```bash # Terminal 1 — agent loop npm run run-agent # Terminal 2 — live dashboard at http://localhost:3000 npm run dashboard ``` -------------------------------- ### Fetch Market Data with Kraken MCP Client Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Example of fetching market data using the `KrakenMCPClient`, demonstrating its identical interface to the `KrakenClient` when interacting with the MCP server. ```typescript // Same interface as KrakenClient const market = await kraken.getTicker("XBTUSD"); ``` -------------------------------- ### formatExplanation() Output for BUY Decision Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/05-explanation-layer.md Example output from the `formatExplanation` function for a BUY decision, showing timestamp, action, asset, amount, price, confidence, reason, and market context. ```text [2024-01-15T10:30:00.000Z] BUY XBTUSD — $100.00 @ $95,420.50 Confidence: 78% Reason: Upward momentum: price rose 0.62% over last 5 ticks. Spread is tight at 0.003%. Buying. Market context: 24h high=96200, low=93800, VWAP=94980.20 Spread: 0.0052% | Volume: 1204.50 ``` -------------------------------- ### Check Kraken Ticker via CLI Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Verify CLI setup by checking the ticker price for a given pair. This command does not require authentication. ```bash # Check ticker (no auth needed) kraken --json ticker --pair XBTUSD ``` -------------------------------- ### Fetch Market Data with Kraken Client Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Example of using the Kraken client's `getTicker` method to fetch market data for a given trading pair. This method internally uses the CLI. ```typescript // Fetch market data const market = await kraken.getTicker("XBTUSD"); // → { price: 95420.5, bid: 95418, ask: 95423, volume: 1204, ... } ``` -------------------------------- ### Format Checkpoint Log Output Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/05-explanation-layer.md This is an example of the structured summary produced by `formatCheckpointLog()` when a checkpoint is generated. It provides a human-readable overview of the trade decision. ```text ──────────────────────────────────────────────────────────────────────── CHECKPOINT — BUY XBTUSD Agent: 0xabc...def Timestamp: 2024-01-15T10:30:00.000Z Amount: $100 Price: $95420.5 Confidence: 78% Reasoning: Upward momentum: price rose 0.62% over last 5 ticks... Sig: 0x1a2b3c4d5e6f7890...1234567890 Signer: 0xYourWalletAddress ──────────────────────────────────────────────────────────────────────── ``` -------------------------------- ### Place Order with Kraken Client Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Example of using the Kraken client's `placeOrder` method to execute a trade. This is typically used for paper trading in sandbox mode and internally uses the CLI. ```typescript // Place order (paper trade in sandbox) const result = await kraken.placeOrder({ pair: "XBTUSD", type: "buy", ordertype: "market", volume: "0.001" }); // → { txid: ["OTXID-..."], descr: { order: "buy 0.001 XBTUSD @ market" } } ``` -------------------------------- ### formatExplanation() Output for HOLD Decision Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/05-explanation-layer.md Example output from the `formatExplanation` function for a HOLD decision, detailing the timestamp, action, asset, price, confidence, reason, and market information. ```text [2026-03-27T11:02:50.000Z] HOLD XBTUSD @ $66,422.60 Confidence: 50% Reason: No clear momentum (0.09% change). Holding current position. Market: bid=66421, ask=66421.1, spread=0.0002%, vol=2764.35 ``` -------------------------------- ### Submit Trade Intent with ethers.js Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Construct and sign a trade intent using EIP-712, then submit it to the RiskRouter. This example demonstrates setting parameters like pair, action, amount, slippage, nonce, and deadline. ```typescript const tradeIntent = { agentId: agentId, agentWallet: agentWalletAddress, pair: "XBTUSD", action: "BUY", amountUsdScaled: 50000, // $500 * 100 maxSlippageBps: 100, nonce: currentNonce, deadline: Math.floor(Date.now() / 1000) + 300 }; const signature = await agentWallet.signTypedData(domain, types, tradeIntent); await router.submitTradeIntent(tradeIntent, signature); ``` -------------------------------- ### Start Countdown Timer Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/leaderboard.html Initializes and manages a countdown timer that updates a UI element with the remaining time until the next refresh. Also updates the 'last updated' timestamp. ```javascript function startCountdown() { clearInterval(cdTimer); cdSecs = REFRESH_MS / 1000; cdTimer = setInterval(() => { cdSecs = Math.max(0, cdSecs - 1); el.countdown.textContent = cdSecs + 's'; if (lastFetchAt) el.lastUpdated.textContent = ago(lastFetchAt); }, 1000); } ``` -------------------------------- ### Initialize and Use KrakenClient Source: https://context7.com/stephen-kimoi/ai-trading-agent-template/llms.txt Demonstrates initializing the Kraken client from environment variables, fetching market data, placing orders, and checking account status. ```typescript import { KrakenClient } from "./src/exchange/kraken"; // Initialize client (reads KRAKEN_API_KEY, KRAKEN_API_SECRET, KRAKEN_SANDBOX from env) const kraken = new KrakenClient(); // Fetch live market data (public endpoint - no auth required) const ticker = await kraken.getTicker("XBTUSD"); console.log(ticker); // { // pair: "XBTUSD", // price: 66422.6, // bid: 66421.0, // ask: 66421.1, // volume: 2764.35, // vwap: 66180.42, // high: 67200.0, // low: 65800.0, // timestamp: 1711536000000 // } // Place a market order (requires API credentials) const order = await kraken.placeOrder({ pair: "XBTUSD", type: "buy", ordertype: "market", volume: "0.001" // Base asset volume (BTC) }); console.log(order); // { txid: ["OQCLML-BW3P3-BUCMWZ"], descr: { order: "buy 0.001 XBTUSD @ market" } } // Check account balance const balance = await kraken.getBalance(); // { "ZUSD": "10000.00", "XXBT": "0.5" } // Get open orders const openOrders = await kraken.getOpenOrders(); ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/02-register-agent.md Commands and template for setting up the .env file with required wallet and RPC configurations. ```bash cp .env.example .env ``` ```env SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY PRIVATE_KEY=0xYOUR_OPERATOR_WALLET_PRIVATE_KEY # Optional: separate hot wallet for signing. Defaults to PRIVATE_KEY. AGENT_WALLET_PRIVATE_KEY=0xYOUR_HOT_WALLET_KEY ``` -------------------------------- ### Deploy Smart Contracts Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/02-register-agent.md Command to deploy the agent infrastructure and the resulting environment variable updates. ```bash npx hardhat run scripts/deploy.ts --network sepolia ``` ```text 1/5 Deploying AgentRegistry (ERC-721)... AgentRegistry: 0xABC... 2/5 Deploying HackathonVault... HackathonVault: 0xDEF... 3/5 Deploying RiskRouter... RiskRouter: 0xGHI... 4/5 Deploying ReputationRegistry... ReputationRegistry: 0xJKL... 5/5 Deploying ValidationRegistry... ValidationRegistry: 0xMNO... ── Add these to your .env ────────────────────────────────────────── AGENT_REGISTRY_ADDRESS=0xABC... HACKATHON_VAULT_ADDRESS=0xDEF... RISK_ROUTER_ADDRESS=0xGHI... REPUTATION_REGISTRY_ADDRESS=0xJKL... VALIDATION_REGISTRY_ADDRESS=0xMNO... ──────────────────────────────────────────────────────────────────── ``` -------------------------------- ### Deploy Contracts Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/README.md Deploy the required smart contracts to the Sepolia network. ```bash npx hardhat run scripts/deploy.ts --network sepolia ``` -------------------------------- ### Get Reputation Score with ethers.js Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Retrieve the average reputation score for a given agentId from the ReputationRegistry. This score is used to evaluate agent performance. ```typescript const score = await repRegistry.getAverageScore(agentId); console.log("Reputation:", score.toString(), "/ 100"); ``` -------------------------------- ### Place a Market Order via CLI (Sandbox) Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Execute a paper trade by placing a market order for a specific pair and volume in sandbox mode. Requires API key and secret. ```bash # Paper trade (sandbox mode) kraken --sandbox --json --api-key $KRAKEN_API_KEY --api-secret $KRAKEN_API_SECRET \ order add --pair XBTUSD --type buy --ordertype market --volume 0.001 ``` -------------------------------- ### Configure and Run Trading Agent Source: https://context7.com/stephen-kimoi/ai-trading-agent-template/llms.txt Environment variable configuration and CLI commands for deploying, registering, and running the trading agent. ```bash # Environment setup (.env file) SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_KEY PRIVATE_KEY=0x... # Operator wallet (owns agent NFT) AGENT_WALLET_PRIVATE_KEY=0x... # Agent hot wallet (optional, defaults to PRIVATE_KEY) AGENT_REGISTRY_ADDRESS=0x97b07dDc405B0c28B17559aFFE63BdB3632d0ca3 HACKATHON_VAULT_ADDRESS=0x0E7CD8ef9743FEcf94f9103033a044caBD45fC90 RISK_ROUTER_ADDRESS=0xd6A6952545FF6E6E6681c2d15C59f9EB8F40FdBC VALIDATION_REGISTRY_ADDRESS=0x92bF63E5C7Ac6980f237a7164Ab413BE226187F1 KRAKEN_API_KEY=your_key KRAKEN_API_SECRET=your_secret KRAKEN_SANDBOX=true # Paper trading mode TRADING_PAIR=XBTUSD POLL_INTERVAL_MS=30000 # 30 second tick interval AGENT_ID=14 # Set after first registration # Deploy contracts (if running your own) npx hardhat run scripts/deploy.ts --network sepolia # Register agent (first run) npm run register # Run the trading agent npm run run-agent # Run live dashboard (http://localhost:3000) npm run dashboard # Run tests npx hardhat test ``` -------------------------------- ### Using formatExplanation() Function Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/05-explanation-layer.md Demonstrates how to use the `formatExplanation` function to generate a structured log line from a decision and market context. Ensure the `decision` and `market` objects are correctly populated. ```typescript import { formatExplanation } from "./src/explainability/reasoner.js"; const explanation = formatExplanation(decision, market); console.log(explanation); ``` -------------------------------- ### Registration Implementation Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/02-register-agent.md TypeScript and Solidity code showing the registration logic and contract minting process. ```typescript const agentId = await getAgentId(operatorSigner, registryAddress, { name: "AITradingAgent", agentWallet: agentWallet.address, capabilities: ["trading", "analysis", "eip712-signing"], agentURI: "ipfs://...", // or data URI ... }); ``` ```solidity function register( address agentWallet, string calldata name, string calldata description, string[] calldata capabilities, string calldata agentURI ) external returns (uint256 agentId) { agentId = _nextAgentId++; _mint(msg.sender, agentId); // <-- ERC-721 mint _setTokenURI(agentId, agentURI); // ... stores metadata emit AgentRegistered(agentId, msg.sender, agentWallet, name); } ``` -------------------------------- ### Register Agent Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/02-register-agent.md Command to execute the registration script and the expected output. ```bash npm run register ``` ```text Operator wallet: 0xYourOperatorAddress Agent wallet: 0xYourAgentWalletAddress AgentRegistry: 0xABC... [identity] Registering new agent on-chain (ERC-721 mint)... [identity] Registration tx: 0xTXHASH... [identity] Agent registered! Token ID (agentId): 0 [identity] Add to .env: AGENT_ID=0 [identity] Saved to agent-id.json Agent registered! agentId (ERC-721 token ID): 0 Add to .env: AGENT_ID=0 Setting default risk params on RiskRouter... Risk params set: maxPosition=$500, maxDrawdown=5%, maxTrades/hr=10 ``` -------------------------------- ### Configure Kraken CLI Environment Variables Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Add these variables to your .env file for API key authentication and sandbox mode. KRAKEN_CLI_PATH is only needed if the binary is not on your system's PATH. ```env KRAKEN_API_KEY=your_api_key KRAKEN_API_SECRET=your_api_secret KRAKEN_SANDBOX=true # start with sandbox! KRAKEN_CLI_PATH=kraken # only needed if binary isn't on PATH ``` -------------------------------- ### Deploy Leaderboard HTML Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/CLAUDE.md Securely copies the leaderboard HTML file to the Contabo server. Ensure the password is correctly provided. ```bash sshpass -p '...' scp leaderboard.html root@154.38.174.112:/var/www/leaderboard/index.html ``` -------------------------------- ### Initialize Kraken MCP Client Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Instantiate the `KrakenMCPClient` in TypeScript, connecting to the running MCP server. This client provides the same interface as the standard `KrakenClient`. ```typescript import { KrakenMCPClient } from "./src/exchange/kraken.js"; const kraken = new KrakenMCPClient(8080); ``` -------------------------------- ### Check Kraken Balance via CLI Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md Check your account balance using the CLI. This command requires API key and secret for authentication. ```bash # Check balance (requires API key) kraken --json --api-key $KRAKEN_API_KEY --api-secret $KRAKEN_API_SECRET balance ``` -------------------------------- ### Run Agent and Dashboard Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/07-reusable-template.md Commands to execute the trading agent and launch the monitoring dashboard in separate terminal sessions. ```bash npm run run-agent # Terminal 1 npm run dashboard # Terminal 2 → http://localhost:3000 ``` -------------------------------- ### Register Agent Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/README.md Register the agent on-chain using the provided script. ```bash npm run register ``` -------------------------------- ### Claim Sandbox Capital with web3.py Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Claims allocation for a registered agent and verifies the balance. ```python vault = w3.eth.contract(address="0x0E7CD8ef9743FEcf94f9103033a044caBD45fC90", abi=HACKATHON_VAULT_ABI) tx = vault.functions.claimAllocation(agent_id).build_transaction({ "from": operator_wallet, "nonce": w3.eth.get_transaction_count(operator_wallet), "gas": 100000, }) signed = w3.eth.account.sign_transaction(tx, private_key=operator_private_key) w3.eth.send_raw_transaction(signed.rawTransaction) ``` ```python balance = vault.functions.getBalance(agent_id).call() print("Allocated:", w3.from_wei(balance, "ether"), "ETH") ``` -------------------------------- ### Run Hardhat Tests Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/CLAUDE.md Executes all unit tests for the HackathonVault contract. Use the FORK=1 flag to run with a Sepolia fork. ```bash npx hardhat test ``` ```bash FORK=1 npx hardhat test ``` -------------------------------- ### Sign and Submit TradeIntent Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Constructs, signs, and prepares a TradeIntent transaction. Requires agent's private key for signing and fetches the latest nonce from the RiskRouter. ```python from eth_account.messages import encode_typed_data nonce = router.functions.getIntentNonce(agent_id).call() intent = { "agentId": agent_id, "agentWallet": agent_wallet, "pair": "XBTUSD", "action": "BUY", "amountUsdScaled": 50000, # $500 * 100 "maxSlippageBps": 100, "nonce": nonce, "deadline": int(time.time()) + 300 } structured_data = {"domain": domain, "types": types, "message": intent, "primaryType": "TradeIntent"} signed_msg = w3.eth.account.sign_typed_data(agent_private_key, structured_data) tx = router.functions.submitTradeIntent( tuple(intent.values()), signed_msg.signature ).build_transaction({...}) ``` -------------------------------- ### Run Admin Vault Script Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/CLAUDE.md Owner-only script to adjust vault allocation and top up the HackathonVault. Requires Sepolia network. ```bash npx hardhat run scripts/admin-vault.ts --network sepolia ``` -------------------------------- ### Customize Trading Strategy Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/README.md Instructions for swapping the default momentum strategy with a custom implementation in the agent index file. ```typescript // Replace this: import { MomentumStrategy } from "./strategy.js"; const strategy = new MomentumStrategy(5, 100); // With your own: import { MyStrategy } from "./my-strategy.js"; const strategy = new MyStrategy(); ``` ```typescript interface TradingStrategy { analyze(data: MarketData): Promise; } ``` -------------------------------- ### Claim Capital Script Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Run this npm script to claim your initial sandbox capital from the HackathonVault. This is a convenient way to execute the claimAllocation function. ```bash npm run claim ``` -------------------------------- ### Run Seed Test Agents Script Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/CLAUDE.md Executes the script to create test agents using deterministic wallets. Safe to re-run. ```bash npx hardhat run scripts/seed-test-agents.ts --network sepolia ``` -------------------------------- ### Configuration Constants JavaScript Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/leaderboard.html Defines RPC endpoints, refresh interval, and contract addresses for the AI Trading Agent Template. Includes ABIs for interacting with various smart contracts. ```javascript // ── Config ─────────────────────────────────────────────────────────────────── const RPCS = [ "https://ethereum-sepolia-rpc.publicnode.com", "https://sepolia.drpc.org", "https://rpc2.sepolia.org", "https://sepolia.gateway.tenderly.co", ]; const REFRESH_MS = 30000; const ADDR = { registry: "0x97b07dDc405B0c28B17559aFFE63BdB3632d0ca3", vault: "0x0E7CD8ef9743FEcf94f9103033a044caBD45fC90", router: "0xd6A6952545FF6E6E6681c2d15C59f9EB8F40FdBC", validation: "0x92bF63E5C7Ac6980f237a7164Ab413BE226187F1", reputation: "0x423a9904e39537a9997fbaF0f220d79D7d545763", }; const ABI = { registry: [ "function totalAgents() view returns (uint256)", "function getAgent(uint256) view returns (tuple(address operatorWallet, address agentWallet, string name, string description, string[] capabilities, uint256 registeredAt, bool active) agent)", ], vault: [ "function hasClaimed(uint256) view returns (bool)", "function getBalance(uint256) view returns (uint256)", "function allocationPerTeam() view returns (uint256)", ], router: ["function getTradeRecord(uint256) view returns (uint256,uint256)"], validation: [ "function getAverageValidationScore(uint256) view returns (uint256)", "function attestationCount(uint256) view returns (uint256)", ], reputation: ["function getAverageScore(uint256) view returns (uint256)"], }; ``` -------------------------------- ### Full Tick Processing Sequence in Terminal Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/05-explanation-layer.md This illustrates a complete tick's data flow as displayed in the terminal, from live price fetching to on-chain checkpoint submission. It shows the output of various functions like `formatExplanation()` and `formatCheckpointLog()`. ```text [agent] XBTUSD @ $66,391.2 ← live price fetch from Kraken [2026-03-28T12:27:05.553Z] HOLD XBTUSD @ $66,391.20 ← formatExplanation() output Confidence: 50% ← decision.confidence Reason: No clear momentum (-0.00% change). ← decision.reasoning (from your strategy) Holding current position. Market: bid=66391.2, ask=66391.3, ← raw market data at decision time spread=0.0002%, vol=2287.42 ──────────────────────────────────────────────────────────────────────── CHECKPOINT — HOLD XBTUSD ← formatCheckpointLog() output Agent: 1 ← agentId (ERC-721 token ID) Timestamp: 2026-03-28T12:27:05.000Z Amount: $0 ← $0 for HOLD, non-zero for BUY/SELL Price: $66391.2 Confidence: 50% Reasoning: No clear momentum (-0.00% change). ← same reasoning, now inside the signed payload Holding current position. Sig: 0x009aa74a5314926499...0d7940931c ← EIP-712 signature over all of the above Signer: 0x13Ef924EB7408e90278B86b659960AFb00DDae61 ← agentWallet address ──────────────────────────────────────────────────────────────────────── [agent] Checkpoint posted to ValidationRegistry: 0xca62bb0d47f2b53a1a... ← on-chain tx hash ``` -------------------------------- ### Configure Environment Variables Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/README.md Required environment variables for contract addresses and agent identification. ```env AGENT_REGISTRY_ADDRESS=... HACKATHON_VAULT_ADDRESS=... RISK_ROUTER_ADDRESS=... REPUTATION_REGISTRY_ADDRESS=... VALIDATION_REGISTRY_ADDRESS=... ``` ```env AGENT_ID=0 ``` -------------------------------- ### Implement Groq Trading Strategy Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/07-reusable-template.md Defines a custom trading strategy using the Groq SDK to analyze market data and return trade decisions in JSON format. ```typescript import Groq from "groq-sdk"; import { MarketData, TradeDecision, TradingStrategy } from "../types/index"; export class GroqStrategy implements TradingStrategy { private client = new Groq({ apiKey: process.env.GROQ_API_KEY }); async analyze(data: MarketData): Promise { const completion = await this.client.chat.completions.create({ model: "llama-3.3-70b-versatile", messages: [ { role: "system", content: `Trading agent. Return JSON: { action, amount, confidence, reasoning }`, }, { role: "user", content: JSON.stringify({ pair: data.pair, price: data.price, high: data.high, low: data.low, vwap: data.vwap }), }, ], response_format: { type: "json_object" }, }); const parsed = JSON.parse(completion.choices[0].message.content || "{}"); return { ...parsed, asset: data.pair.replace("USD", ""), pair: data.pair }; } } ``` -------------------------------- ### Read and verify checkpoints from JSONL Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/06-eip712-checkpoints.md Reads a JSONL file of checkpoints and validates each entry against a registry address and expected signer. ```typescript import * as fs from "fs"; import { verifyCheckpoint } from "./src/explainability/checkpoint.js"; const lines = fs.readFileSync("checkpoints.jsonl", "utf8").trim().split("\n"); const checkpoints = lines.map(l => JSON.parse(l)); for (const cp of checkpoints) { const valid = verifyCheckpoint(cp, registryAddress, 11155111, expectedSigner); console.log(`${new Date(cp.timestamp * 1000).toISOString()} | ${cp.action} ${cp.pair} | valid: ${valid}`); } ``` -------------------------------- ### Register Agent with web3.py Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Registers a new agent by calling the AgentRegistry contract and parsing the resulting agentId from event logs. ```python from web3 import Web3 w3 = Web3(Web3.HTTPProvider("https://ethereum-sepolia-rpc.publicnode.com")) registry = w3.eth.contract(address="0x97b07dDc405B0c28B17559aFFE63BdB3632d0ca3", abi=AGENT_REGISTRY_ABI) tx = registry.functions.register( agent_wallet, # hot wallet address for signing trade intents "My Agent", "A trustless trading agent", ["trading", "eip712-signing"], "https://my-agent-metadata.json" ).build_transaction({ "from": operator_wallet, "nonce": w3.eth.get_transaction_count(operator_wallet), "gas": 300000, }) signed = w3.eth.account.sign_transaction(tx, private_key=operator_private_key) tx_hash = w3.eth.send_raw_transaction(signed.rawTransaction) receipt = w3.eth.wait_for_transaction_receipt(tx_hash) # Parse agentId from AgentRegistered event logs agent_id = registry.events.AgentRegistered().process_receipt(receipt)[0]["args"]["agentId"] print("agentId:", agent_id) ``` -------------------------------- ### Verify Registration Event Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/02-register-agent.md Expected event log structure on Etherscan after successful registration. ```text AgentRegistered agentId (token ID): 0 operatorWallet: 0xYourOperatorAddress agentWallet: 0xYourAgentWalletAddress name: AITradingAgent ``` -------------------------------- ### Implement an LLM-based strategy using Claude Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/07-reusable-template.md Use the Anthropic SDK to delegate trading decisions to an LLM by implementing the TradingStrategy interface. ```typescript import Anthropic from "@anthropic-ai/sdk"; import { MarketData, TradeDecision, TradingStrategy } from "../types/index"; export class ClaudeStrategy implements TradingStrategy { private client = new Anthropic(); async analyze(data: MarketData): Promise { const response = await this.client.messages.create({ model: "claude-sonnet-4-6", max_tokens: 500, system: `You are a crypto trading agent. Respond ONLY with valid JSON matching: { action: "BUY"|"SELL"|"HOLD", amount: number, confidence: number, reasoning: string } reasoning must reference specific numbers from the market data.`, messages: [{ role: "user", content: `Analyze: pair=${data.pair} price=${data.price} high=${data.high} low=${data.low} vwap=${data.vwap} volume=${data.volume}`, }], }); const parsed = JSON.parse(response.content[0].type === "text" ? response.content[0].text : "{}"); return { ...parsed, asset: data.pair.replace("USD", ""), pair: data.pair, }; } } ``` -------------------------------- ### Generate and Verify EIP-712 Checkpoints Source: https://context7.com/stephen-kimoi/ai-trading-agent-template/llms.txt Use these functions to create signed audit records for trade decisions and verify their integrity and authenticity. Requires an agent wallet and registry configuration. ```typescript import { ethers } from "ethers"; import { generateCheckpoint, verifyCheckpoint, verifyReasoningIntegrity, computeCheckpointHash } from "./src/explainability/checkpoint"; import { formatExplanation, formatCheckpointLog } from "./src/explainability/reasoner"; const agentWallet = new ethers.Wallet(process.env.AGENT_WALLET_PRIVATE_KEY!); const SEPOLIA_CHAIN_ID = 11155111; // Market data and decision from strategy const market = { pair: "XBTUSD", price: 66422.6, bid: 66421, ask: 66421.1, volume: 2764.35, vwap: 66180.42, high: 67200, low: 65800, timestamp: Date.now() }; const decision = { action: "BUY" as const, asset: "XBT", pair: "XBTUSD", amount: 100, confidence: 0.75, reasoning: "Strong upward momentum detected" }; // Generate human-readable explanation const explanation = formatExplanation(decision, market); console.log(explanation); // [2026-03-27T11:02:50.000Z] BUY XBTUSD — $100.00 @ $66,422.60 // Confidence: 75% // Reason: Strong upward momentum detected // Market context: 24h high=67200, low=65800, VWAP=66180.42 // Spread: 0.0002% | Volume: 2764.35 // Generate EIP-712 signed checkpoint const checkpoint = await generateCheckpoint( 14n, // agentId decision, // trade decision market, // market data snapshot "0x1234...intentHash", // hash from approved TradeIntent agentWallet, // signer process.env.AGENT_REGISTRY_ADDRESS!, // registry address (EIP-712 domain) SEPOLIA_CHAIN_ID ); console.log(formatCheckpointLog(checkpoint)); // ──────────────────────────────────────────────────────────────────────── // CHECKPOINT — BUY XBTUSD // Agent: 14 // Timestamp: 2026-03-27T11:02:50.000Z // Amount: $100 // Price: $66422.6 // Confidence: 75% // Sig: 0x4f93af3b...c66c3bb31c // Signer: 0xAgentWalletAddress // ──────────────────────────────────────────────────────────────────────── // Verify checkpoint signature (for auditors/validators) const isValid = verifyCheckpoint( checkpoint, process.env.AGENT_REGISTRY_ADDRESS!, SEPOLIA_CHAIN_ID, agentWallet.address // expected signer ); // true // Verify reasoning hasn't been tampered with const reasoningValid = verifyReasoningIntegrity(checkpoint); // true // Compute checkpoint hash for on-chain submission const hash = computeCheckpointHash(checkpoint, process.env.AGENT_REGISTRY_ADDRESS!, SEPOLIA_CHAIN_ID); ``` -------------------------------- ### Implement a custom algorithmic strategy Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/07-reusable-template.md Create a new class that implements the TradingStrategy interface to define custom market analysis logic. ```typescript // src/agent/my-strategy.ts import { MarketData, TradeDecision, TradingStrategy } from "../types/index"; export class MyStrategy implements TradingStrategy { async analyze(data: MarketData): Promise { // Your logic here — technical indicators, ML model, anything const action = data.price > data.vwap ? "BUY" : "SELL"; return { action, asset: "XBT", pair: data.pair, amount: 100, confidence: 0.7, reasoning: `Price ($${data.price}) is ${action === "BUY" ? "above" : "below"} VWAP ($${data.vwap.toFixed(2)}). ${action}.`, }; } } ``` -------------------------------- ### Define EIP-712 Domain for AgentRegistry Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Defines the EIP-712 domain parameters for signing checkpoints against the AgentRegistry. Used for verifying agent signatures. ```python agent_registry_domain = { "name": "AITradingAgent", "version": "1", "chainId": 11155111, "verifyingContract": "0x97b07dDc405B0c28B17559aFFE63BdB3632d0ca3" } ``` -------------------------------- ### Kraken Client CLI Execution Logic Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/03-kraken-connection.md This TypeScript code snippet shows how the Kraken client spawns the CLI as a subprocess to execute commands. It handles authentication arguments and JSON parsing. ```typescript private async run(subcommand: string[], isPrivate = false): Promise { const args: string[] = []; if (isPrivate && !this.sandbox) { args.push("--api-key", this.apiKey, "--api-secret", this.apiSecret); } args.push(...subcommand); args.push("-o", "json"); const { stdout } = await execFileAsync(KRAKEN_BIN, args, { timeout: 15000 }); return JSON.parse(stdout.trim()); } ``` -------------------------------- ### Build and Sign TradeIntent Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/04-vault-riskrouter.md TypeScript implementation for constructing, signing, and submitting a trade intent to the RiskRouter. ```typescript const riskRouter = new RiskRouterClient(routerAddress, agentWallet, SEPOLIA_CHAIN_ID); // 1. Build intent (fetches current nonce from chain) const intent = await riskRouter.buildIntent( agentId, agentWallet.address, "XBTUSD", "BUY", 100, // $100 USD { maxSlippageBps: 50, deadlineSeconds: 300 } ); // 2. Sign with EIP-712 (agentWallet is the hot signing key) const signed = await riskRouter.signIntent(intent, agentWallet); // 3. Submit to RiskRouter const result = await riskRouter.submitIntent(signed); if (result.approved) { console.log("Trade approved — intentHash:", result.intentHash); } else { console.warn("Trade rejected:", result.reason); } ``` -------------------------------- ### Register New Agent Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/01-erc8004-intro.md The core function to register an agent, mint its identity token, and store its registration details. ```solidity function register( address agentWallet, string calldata name, string calldata description, string[] calldata capabilities, string calldata agentURI ) external returns (uint256 agentId) { require(bytes(name).length > 0, "AgentRegistry: name required"); require(agentWallet != address(0), "AgentRegistry: invalid agentWallet"); agentId = _nextAgentId++; _mint(msg.sender, agentId); // ERC-721 mint _setTokenURI(agentId, agentURI); agents[agentId] = AgentRegistration({ operatorWallet: msg.sender, agentWallet: agentWallet, name: name, description: description, capabilities: capabilities, registeredAt: block.timestamp, active: true }); walletToAgentId[agentWallet] = agentId; emit AgentRegistered(agentId, msg.sender, agentWallet, name); } ``` -------------------------------- ### Implement RiskRouterClient Trade Validation Source: https://context7.com/stephen-kimoi/ai-trading-agent-template/llms.txt Shows how to build, sign, and submit EIP-712 trade intents, as well as managing risk parameters on-chain. ```typescript import { ethers } from "ethers"; import { RiskRouterClient } from "./src/onchain/riskRouter"; const provider = new ethers.JsonRpcProvider(process.env.SEPOLIA_RPC_URL); const agentWallet = new ethers.Wallet(process.env.AGENT_WALLET_PRIVATE_KEY!, provider); const SEPOLIA_CHAIN_ID = 11155111; const riskRouter = new RiskRouterClient( process.env.RISK_ROUTER_ADDRESS!, agentWallet, SEPOLIA_CHAIN_ID ); // Build a TradeIntent for a proposed trade const intent = await riskRouter.buildIntent( 14n, // agentId (ERC-721 token ID) agentWallet.address, // agentWallet "XBTUSD", // trading pair "BUY", // action 100, // amount in USD { maxSlippageBps: 50, deadlineSeconds: 300 } // 0.5% slippage, 5 min deadline ); // Sign the intent with EIP-712 const signed = await riskRouter.signIntent(intent, agentWallet); console.log(`Intent hash: ${signed.intentHash}`); // Submit to RiskRouter for on-chain validation const result = await riskRouter.submitIntent(signed); if (result.approved) { console.log("Trade approved! Proceeding with execution..."); } else { console.log(`Trade rejected: ${result.reason}`); // e.g., "exceeds max position size" or "rate limit exceeded" } // Simulate without state change (dry run) const simulation = await riskRouter.simulateIntent(intent); // { approved: true, reason: "OK" } // Configure risk parameters for an agent (owner only) await riskRouter.setRiskParams( 14n, // agentId 10000, // maxPositionUsd ($10,000) 500, // maxDrawdownBps (5%) 10 // maxTradesPerHour ); // Read current risk parameters const params = await riskRouter.getRiskParams(14n); // { maxPositionUsd: 10000, maxDrawdownBps: 500, maxTradesPerHour: 10, active: true } ``` -------------------------------- ### Fetch Data from Smart Contracts Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/leaderboard.html Fetches agent data, including total agents, allocation per team, and individual agent details like claimed status, balance, trades, validation scores, and reputation scores. Handles potential errors during data retrieval. ```javascript async function fetchData() { const provider = await getProvider(); const reg = new ethers.Contract(ADDR.registry, ABI.registry, provider); const vlt = new ethers.Contract(ADDR.vault, ABI.vault, provider); const rtr = new ethers.Contract(ADDR.router, ABI.router, provider); const val = new ethers.Contract(ADDR.validation, ABI.validation, provider); const rep = new ethers. Contract(ADDR.reputation, ABI.reputation, provider); const [total, allocPerTeam] = await Promise.all([ reg.totalAgents().then(Number), vlt.allocationPerTeam().catch(() => null), ]); if (allocPerTeam) { el.statAlloc.innerHTML = parseFloat(ethers.utils.formatEther(allocPerTeam)).toFixed(3) + ' ETH'; } if (total === 0) return []; const rows = await Promise.all( Array.from({length: total}, (_, i) => i).map(async id => { const [agent, claimed, balance, trade, valScore, repScore] = await Promise.all([ reg.getAgent(id), vlt.hasClaimed(id).catch(()=>false), vlt.getBalance(id).catch(()=>ethers.BigNumber.from(0)), rtr.getTradeRecord(id).catch(()=>[0,0]), val.getAverageValidationScore(id).catch(()=>ethers.BigNumber.from(0)), rep.getAverageScore(id).catch(()=>ethers.BigNumber.from(0)), ]); return { id, name: agent[2] || `Agent #${id}`, operator: agent[0], registeredAt:agent[5], active: agent[6], claimed, balance: parseFloat(ethers.utils.formatEther(balance)).toFixed(4), trades: Number(trade[0] || 0), valScore: Number(valScore), repScore: Number(repScore), }; }) ); return rows.sort((a,b) => b.valScore !== a.valScore ? b.valScore - a.valScore : b.repScore - a.repScore); } ``` -------------------------------- ### Set Contract Addresses in .env Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Configure your environment variables with the addresses of the shared contracts. These are essential for interacting with the deployed contracts on Sepolia Testnet. ```env AGENT_REGISTRY_ADDRESS=0x97b07dDc405B0c28B17559aFFE63BdB3632d0ca3 HACKATHON_VAULT_ADDRESS=0x0E7CD8ef9743FEcf94f9103033a044caBD45fC90 RISK_ROUTER_ADDRESS=0xd6A6952545FF6E6E6681c2d15C59f9EB8F40FdBC REPUTATION_REGISTRY_ADDRESS=0x423a9904e39537a9997fbaF0f220d79D7d545763 VALIDATION_REGISTRY_ADDRESS=0x92bF63E5C7Ac6980f237a7164Ab413BE226187F1 ``` -------------------------------- ### Set Risk Parameters Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/tutorial/04-vault-riskrouter.md Methods for configuring agent risk limits, such as maximum position size and trade frequency. ```typescript // Called automatically during npm run register await router.setRiskParams( agentId, BigInt(50000), // maxPositionUsdScaled: $500 max per trade (500 * 100) BigInt(500), // maxDrawdownBps: 5% BigInt(10) // maxTradesPerHour: 10 ); ``` ```typescript await riskRouter.setRiskParams( agentId, 500, // maxPositionUsd: $500 per trade 500, // maxDrawdownBps: 5% 10 // maxTradesPerHour ); ``` -------------------------------- ### Implement Custom Trading Strategy Source: https://context7.com/stephen-kimoi/ai-trading-agent-template/llms.txt Implement the TradingStrategy interface to define custom trading logic. The agent loop handles all other aspects like identity, risk, and execution. ```typescript import { MarketData, TradeDecision, TradingStrategy } from "./src/types/index"; // Custom strategy implementation class MyTradingStrategy implements TradingStrategy { async analyze(data: MarketData): Promise { // MarketData contains: // - pair: "XBTUSD" // - price: 66422.6 (last traded price) // - bid/ask: best bid/ask prices // - volume: 24h volume // - vwap: volume-weighted average price // - high/low: 24h high/low // - timestamp: Unix timestamp (ms) const priceChange = (data.price - data.vwap) / data.vwap; if (priceChange > 0.02) { return { action: "SELL", asset: "XBT", pair: data.pair, amount: 100, // USD confidence: 0.75, reasoning: `Price ${(priceChange * 100).toFixed(2)}% above VWAP. Taking profit.` }; } if (priceChange < -0.02) { return { action: "BUY", asset: "XBT", pair: data.pair, amount: 100, confidence: 0.70, reasoning: `Price ${(Math.abs(priceChange) * 100).toFixed(2)}% below VWAP. Buying dip.` }; } return { action: "HOLD", asset: "XBT", pair: data.pair, amount: 0, confidence: 0.5, reasoning: "Price within normal range of VWAP. Holding position." }; } } // Use in agent: swap strategy in src/agent/index.ts // const strategy = new MyTradingStrategy(); // runAgent(strategy); ``` -------------------------------- ### Claim Sandbox Capital with ethers.js Source: https://github.com/stephen-kimoi/ai-trading-agent-template/blob/main/SHARED_CONTRACTS.md Use this TypeScript snippet to claim your initial 0.05 ETH allocation from the HackathonVault. Ensure you have the vault address and your agentId configured. ```typescript const vault = new ethers.Contract( process.env.HACKATHON_VAULT_ADDRESS!, ["function claimAllocation(uint256 agentId) external"], signer ); await vault.claimAllocation(process.env.AGENT_ID!); ```