jzou19950715 commited on
Commit
180265f
·
verified ·
1 Parent(s): ec0ef76

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +157 -1
app.py CHANGED
@@ -47,6 +47,162 @@ logging.basicConfig(
47
  )
48
  logger = logging.getLogger(__name__)
49
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
  class BlockchainError(Exception):
51
  """Base exception for blockchain-related errors."""
52
  pass
@@ -136,7 +292,7 @@ class Config:
136
  MAX_IMAGE_SIZE: Tuple[int, int] = (800, 800)
137
 
138
  # OpenAI Settings
139
- OPENAI_MODEL: str = "gpt-4o-mini"
140
  MAX_TOKENS: int = 8000
141
  TEMPERATURE: float = 0.7
142
  HISTORY_LIMIT: int = 10
 
47
  )
48
  logger = logging.getLogger(__name__)
49
 
50
+ @dataclass
51
+ class ChatContext:
52
+ """Track chat context and discussed NFTs."""
53
+ wallet_data: Dict[str, Any] = field(default_factory=dict)
54
+ discussed_nfts: Set[str] = field(default_factory=set)
55
+ last_collection: str = ""
56
+
57
+ def mark_nft_discussed(self, contract: str, token_id: str) -> None:
58
+ """Track which NFTs have been discussed."""
59
+ self.discussed_nfts.add(f"{contract}_{token_id}")
60
+
61
+ def is_nft_discussed(self, contract: str, token_id: str) -> bool:
62
+ """Check if NFT has been discussed."""
63
+ return f"{contract}_{token_id}" in self.discussed_nfts
64
+
65
+ class BlockchainError(Exception):
66
+ """Base exception for blockchain-related errors."""
67
+ pass
68
+
69
+ class ConfigError(BlockchainError):
70
+ """Configuration error."""
71
+ pass
72
+
73
+ class APIError(BlockchainError):
74
+ """API call error."""
75
+ pass
76
+
77
+ class ValidationError(BlockchainError):
78
+ """Input validation error."""
79
+ pass
80
+
81
+ class NFTError(BlockchainError):
82
+ """NFT processing error."""
83
+ pass
84
+
85
+ @dataclass
86
+ class NFTMetadata:
87
+ """Structure for NFT metadata."""
88
+ contract: str
89
+ token_id: str
90
+ name: str
91
+ collection_name: str
92
+ image_url: Optional[str] = None
93
+ description: Optional[str] = None
94
+ traits: List[Dict[str, Any]] = field(default_factory=list)
95
+ last_updated: datetime = field(default_factory=datetime.now)
96
+
97
+ def to_dict(self) -> Dict[str, Any]:
98
+ """Convert to dictionary format."""
99
+ return {
100
+ "contract": self.contract,
101
+ "token_id": self.token_id,
102
+ "name": self.name,
103
+ "collection_name": self.collection_name,
104
+ "image_url": self.image_url,
105
+ "description": self.description,
106
+ "traits": self.traits,
107
+ "last_updated": self.last_updated.isoformat()
108
+ }
109
+
110
+ @dataclass
111
+ class Config:
112
+ """Enhanced application configuration."""
113
+
114
+ # Improved system prompt for more natural responses
115
+ SYSTEM_PROMPT: str = """
116
+ You are LOSS DOG 🐕 (Learning & Observing Smart Systems Digital Output Generator),
117
+ a friendly blockchain analysis assistant!
118
+
119
+ Your conversation style:
120
+ - Maintain natural dialogue flow
121
+ - Avoid repetitive responses
122
+ - Use context from previous messages
123
+ - Track which NFTs have been discussed
124
+ - Provide insights when relevant
125
+
126
+ When analyzing wallets:
127
+ - Reference specific NFTs by collection and ID
128
+ - Highlight interesting patterns
129
+ - Compare wallets if multiple available
130
+ - Monitor NFT rarity and traits
131
+ """
132
+
133
+ # API Configuration
134
+ ETHERSCAN_BASE_URL: str = "https://api.etherscan.io/api"
135
+ OPENSEA_BASE_URL: str = "https://api.opensea.io/api/v2"
136
+ ETHEREUM_ADDRESS_REGEX: str = r"^0x[a-fA-F0-9]{40}$"
137
+
138
+ # Rate Limiting & Retries
139
+ RATE_LIMIT_DELAY: float = 0.2 # 5 requests per second
140
+ MAX_RETRIES: int = 3
141
+ RETRY_BASE_DELAY: float = 1.0
142
+ RETRY_MAX_DELAY: float = 10.0
143
+
144
+ # API Timeouts
145
+ REQUEST_TIMEOUT: float = 30.0
146
+ NFT_FETCH_TIMEOUT: int = 10
147
+
148
+ # NFT Processing
149
+ MAX_NFTS_PER_COLLECTION: int = 50
150
+ NFT_BATCH_SIZE: int = 5
151
+ MAX_IMAGE_SIZE: Tuple[int, int] = (800, 800)
152
+
153
+ # OpenAI Settings
154
+ OPENAI_MODEL: str = "gpt-4-0125-preview"
155
+ MAX_TOKENS: int = 8000
156
+ TEMPERATURE: float = 0.7
157
+ HISTORY_LIMIT: int = 10"""
158
+ Blockchain Wallet Analyzer - A tool for analyzing Ethereum wallet contents and NFT holdings.
159
+
160
+ This module provides a complete implementation of a blockchain wallet analysis tool
161
+ with a Gradio web interface. It includes improved NFT tracking, natural AI communication,
162
+ and enhanced error handling.
163
+
164
+ Author: Claude
165
+ Date: January 2025
166
+ """
167
+
168
+ from __future__ import annotations
169
+ import os
170
+ import re
171
+ import json
172
+ import time
173
+ import logging
174
+ import asyncio
175
+ import base64
176
+ from typing import List, Dict, Tuple, Any, Optional, TypeVar, Set
177
+ from datetime import datetime
178
+ from decimal import Decimal
179
+ from dataclasses import dataclass, field
180
+ from pathlib import Path
181
+ from io import BytesIO
182
+
183
+ import aiohttp
184
+ import openai
185
+ import gradio as gr
186
+ from PIL import Image
187
+ from tenacity import retry, stop_after_attempt, wait_exponential
188
+
189
+ # Type variables
190
+ T = TypeVar('T')
191
+ WalletData = Dict[str, Any]
192
+ ChatHistory = List[Tuple[str, str]]
193
+ NFTIdentifier = Tuple[str, str] # (contract, token_id)
194
+
195
+ # Configure logging
196
+ logging.basicConfig(
197
+ level=logging.INFO,
198
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
199
+ handlers=[
200
+ logging.FileHandler('blockchain_analyzer.log'),
201
+ logging.StreamHandler()
202
+ ]
203
+ )
204
+ logger = logging.getLogger(__name__)
205
+
206
  class BlockchainError(Exception):
207
  """Base exception for blockchain-related errors."""
208
  pass
 
292
  MAX_IMAGE_SIZE: Tuple[int, int] = (800, 800)
293
 
294
  # OpenAI Settings
295
+ OPENAI_MODEL: str = "gpt-4-0125-preview"
296
  MAX_TOKENS: int = 8000
297
  TEMPERATURE: float = 0.7
298
  HISTORY_LIMIT: int = 10