Skip to content

Commit 88b0f52

Browse files
committed
Added Frontend & Offchain Python Script
1 parent 0e03938 commit 88b0f52

20 files changed

+7481
-1
lines changed

AgentTrumpListener.py

+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
from web3 import Web3
2+
import asyncio
3+
import json
4+
import logging
5+
from datetime import datetime
6+
import os
7+
from dotenv import load_dotenv
8+
9+
# Load environment variables
10+
load_dotenv()
11+
12+
# Configure logging
13+
logging.basicConfig(
14+
level=logging.INFO,
15+
format='%(asctime)s - %(levelname)s - %(message)s'
16+
)
17+
logger = logging.getLogger(__name__)
18+
19+
# Contract configuration
20+
CONTRACT_ADDRESS = os.getenv('CONTRACT_ADDRESS')
21+
RPC_URL = os.getenv('RPC_URL') # Your Base network RPC URL
22+
PRIVATE_KEY = os.getenv('PRIVATE_KEY') # Contract owner's private key
23+
24+
# Load contract ABI
25+
with open('contract_abi.json', 'r') as f:
26+
CONTRACT_ABI = json.load(f)
27+
28+
class AgentTrumpListener:
29+
def __init__(self):
30+
# Initialize Web3
31+
self.w3 = Web3(Web3.HTTPProvider(RPC_URL))
32+
33+
# Create contract instance
34+
self.contract = self.w3.eth.contract(
35+
address=CONTRACT_ADDRESS,
36+
abi=CONTRACT_ABI
37+
)
38+
39+
# Set up account
40+
self.account = self.w3.eth.account.from_key(PRIVATE_KEY)
41+
42+
# Track the last block we processed
43+
self.last_processed_block = self.w3.eth.block_number
44+
45+
logger.info(f"Initialized listener for contract: {CONTRACT_ADDRESS}")
46+
47+
async def process_response(self, player, response, timestamp):
48+
"""
49+
Process the player's response through the AI agent
50+
"""
51+
try:
52+
logger.info(f"Processing response from {player}")
53+
logger.info(f"Response: {response}")
54+
logger.info(f"Timestamp: {datetime.fromtimestamp(timestamp)}")
55+
56+
# TODO: Add your AI agent processing logic here
57+
# is_winning = await ai_agent.evaluate_response(response)
58+
# if is_winning:
59+
# await self.submit_winner(player)
60+
61+
except Exception as e:
62+
logger.error(f"Error processing response: {e}")
63+
64+
async def submit_winner(self, winner_address):
65+
"""
66+
Submit a winner to the smart contract
67+
"""
68+
try:
69+
nonce = self.w3.eth.get_transaction_count(self.account.address)
70+
71+
tx = self.contract.functions.buttonPushed(winner_address).build_transaction({
72+
'from': self.account.address,
73+
'nonce': nonce,
74+
'gas': 200000,
75+
'gasPrice': self.w3.eth.gas_price
76+
})
77+
78+
signed_tx = self.w3.eth.account.sign_transaction(tx, PRIVATE_KEY)
79+
tx_hash = self.w3.eth.send_raw_transaction(signed_tx.rawTransaction)
80+
81+
receipt = self.w3.eth.wait_for_transaction_receipt(tx_hash)
82+
logger.info(f"Winner submitted! Transaction hash: {receipt.transactionHash.hex()}")
83+
84+
except Exception as e:
85+
logger.error(f"Error submitting winner: {e}")
86+
87+
async def process_events(self, events):
88+
"""
89+
Process a batch of events
90+
"""
91+
for event in events:
92+
player = event['args']['player']
93+
response = event['args']['response']
94+
timestamp = event['args']['timestamp']
95+
await self.process_response(player, response, timestamp)
96+
97+
async def poll_for_events(self):
98+
"""
99+
Poll for new GuessSubmitted events
100+
"""
101+
while True:
102+
try:
103+
# Get current block number
104+
current_block = self.w3.eth.block_number
105+
106+
# If new blocks exist, check for events
107+
if current_block > self.last_processed_block:
108+
events = self.contract.events.GuessSubmitted.get_logs(
109+
fromBlock=self.last_processed_block + 1,
110+
toBlock=current_block
111+
)
112+
113+
if events:
114+
logger.info(f"Found {len(events)} new events")
115+
await self.process_events(events)
116+
117+
self.last_processed_block = current_block
118+
119+
# Wait before next poll
120+
await asyncio.sleep(2)
121+
122+
except Exception as e:
123+
logger.error(f"Error polling for events: {e}")
124+
await asyncio.sleep(5)
125+
126+
def start(self):
127+
"""
128+
Start the event listener
129+
"""
130+
try:
131+
asyncio.run(self.poll_for_events())
132+
except KeyboardInterrupt:
133+
logger.info("Shutting down listener...")
134+
135+
if __name__ == "__main__":
136+
# Create and start the listener
137+
listener = AgentTrumpListener()
138+
listener.start()

agent-trump-frontend/.gitignore

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
pnpm-debug.log*
8+
lerna-debug.log*
9+
10+
node_modules
11+
dist
12+
dist-ssr
13+
*.local
14+
15+
# Editor directories and files
16+
.vscode/*
17+
!.vscode/extensions.json
18+
.idea
19+
.DS_Store
20+
*.suo
21+
*.ntvs*
22+
*.njsproj
23+
*.sln
24+
*.sw?

agent-trump-frontend/README.md

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# React + Vite
2+
3+
This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4+
5+
Currently, two official plugins are available:
6+
7+
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
8+
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh

agent-trump-frontend/eslint.config.js

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import js from '@eslint/js'
2+
import globals from 'globals'
3+
import react from 'eslint-plugin-react'
4+
import reactHooks from 'eslint-plugin-react-hooks'
5+
import reactRefresh from 'eslint-plugin-react-refresh'
6+
7+
export default [
8+
{ ignores: ['dist'] },
9+
{
10+
files: ['**/*.{js,jsx}'],
11+
languageOptions: {
12+
ecmaVersion: 2020,
13+
globals: globals.browser,
14+
parserOptions: {
15+
ecmaVersion: 'latest',
16+
ecmaFeatures: { jsx: true },
17+
sourceType: 'module',
18+
},
19+
},
20+
settings: { react: { version: '18.3' } },
21+
plugins: {
22+
react,
23+
'react-hooks': reactHooks,
24+
'react-refresh': reactRefresh,
25+
},
26+
rules: {
27+
...js.configs.recommended.rules,
28+
...react.configs.recommended.rules,
29+
...react.configs['jsx-runtime'].rules,
30+
...reactHooks.configs.recommended.rules,
31+
'react/jsx-no-target-blank': 'off',
32+
'react-refresh/only-export-components': [
33+
'warn',
34+
{ allowConstantExport: true },
35+
],
36+
},
37+
},
38+
]

agent-trump-frontend/index.html

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+
<title>Vite + React</title>
8+
</head>
9+
<body>
10+
<div id="root"></div>
11+
<script type="module" src="/src/main.jsx"></script>
12+
</body>
13+
</html>

0 commit comments

Comments
 (0)