-
Notifications
You must be signed in to change notification settings - Fork 15
Add Opinion exchange support #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
0xGh-st
commented
Dec 11, 2025
- Implement Opinion exchange client with full trading API
- Add market listing and order management functionality
- Include spread strategy example and approval check script
- Add comprehensive tests for Opinion integration
PR Review: Add Opinion exchange supportSummaryThis PR adds comprehensive support for the Opinion prediction market exchange (BNB Chain), following the CCXT-style unified API pattern. The implementation is well-structured and includes market data fetching, order management, position tracking, and example strategies. Code Quality ✅Strengths:
Areas for Improvement:
Potential Bugs 🐛
Security Concerns 🔒
Performance Considerations ⚡
Test Coverage 📊Good:
Missing:
Suggestions:
Additional ObservationsPositive:
Documentation:
Architecture:
RecommendationsHigh Priority:
Medium Priority:
Low Priority:
ConclusionThis is a well-implemented PR that successfully adds Opinion exchange support following the project's patterns. The code is clean, well-documented, and thoroughly tested for basic functionality. The main concerns are:
With these issues addressed, this PR is ready to merge. Overall Rating: 8/10 - High quality implementation with minor issues to fix. |
Pull Request Review: Opinion Exchange IntegrationSummaryThis PR adds comprehensive Opinion exchange support to dr-manhattan, implementing a full CCXT-style API for the BNB Chain prediction market. The implementation is thorough with 1422 lines of production code, 309 lines of tests, and complete examples. Code Quality - Strengths
Security ConcernsCRITICAL - .env Variables Violate CLAUDE.md Rule 4 The .env.example adds 9 new environment variables, but CLAUDE.md rule 4 states: Single Source of Truth: DO NOT place many variables in .env file. Place them in the code instead. Recommendation: Only OPINION_API_KEY, OPINION_PRIVATE_KEY, and OPINION_MULTI_SIG_ADDR should be in .env (secrets). Constants like RPC_URL, HOST, CHAIN_ID, contract addresses should be hardcoded in opinion.py as class constants. Performance Considerations
Code Quality Issues
TestingCoverage: 310 lines covering basics, parsing, and mocked operations Missing tests for:
RecommendationsHigh Priority:
Medium Priority: ConclusionThis is a well-crafted implementation that adds valuable functionality. The code is clean, well-documented, and follows existing patterns. Main concerns:
With environment variable changes and improved error handling, this PR would be ready to merge. Overall Rating: 8/10 - Excellent work with minor improvements needed. |
Pull Request Review: Add Opinion Exchange SupportOverviewThis PR adds comprehensive Opinion exchange integration with 1,424 lines of new implementation code, tests, examples, and documentation. The implementation follows the existing CCXT-style architecture and integrates well with the codebase. Code Quality & Best Practices✅ Strengths
|
Pull Request Review: Add Opinion Exchange SupportOverviewThis PR adds comprehensive support for the Opinion prediction market exchange (BNB Chain) to dr-manhattan. The implementation follows the existing CCXT-style unified API pattern and includes ~1,418 lines of well-structured code with tests and examples. ✅ Strengths1. Code Quality & Architecture
2. Feature CompletenessThe implementation covers all major exchange operations:
3. Testing
4. Documentation & Examples
5. Adherence to CLAUDE.md Guidelines
|
Pull Request Review: Add Opinion Exchange SupportOverviewThis PR adds comprehensive support for the Opinion exchange (BNB Chain prediction markets) to the dr-manhattan unified API. The implementation includes a full-featured client, trading functionality, examples, and test coverage. ✅ StrengthsCode Quality
Testing
Documentation
|
PR Review: Add Opinion Exchange SupportSummaryThis PR adds comprehensive Opinion exchange support to dr-manhattan, implementing a full trading API for BNB Chain prediction markets. The implementation is well-structured and follows the existing exchange abstraction pattern. Code Quality ✅Strengths:
Minor Concerns:
Architecture & Best Practices ✅Well Implemented:
Concerns:
Security Concerns
|
Pull Request Review: Add Opinion Exchange SupportOverviewThis PR adds comprehensive support for the Opinion prediction market exchange (BNB Chain) with 3,144 additions implementing a full trading client, market listing, order management, and example strategies. The implementation follows the established CCXT-style pattern used for Polymarket and Limitless. Code Quality & Best PracticesStrengths
Areas for Improvement1. CRITICAL: .env File Violations (CLAUDE.md Rule #4)The PR adds 8 new environment variables to Per CLAUDE.md Rule #4: "Single Source of Truth: DO NOT place many variables in .env file. Place them in the code instead." Recommendation: Move constants like Reference: dr_manhattan/exchanges/opinion.py:66-69 2. Security ConcernsPrivate Key Handling:
API Key Exposure:
Recommendation:
3. Error Handling IssuesSilent Exception Swallowing (opinion.py:419-431): try:
response = self._client.get_market(...)
...
except Exception:
pass # Silently swallows ALL exceptionsThis catches ALL exceptions including Recommendation: Be specific about exceptions: except (ExchangeError, NetworkError) as e:
logger.debug(f"Binary market fetch failed: {e}")Similar issues at:
4. Code Duplication & MaintainabilityRedundant Field Parsing (opinion.py:200-211): market_id = str(
getattr(data, "market_id", "")
or getattr(data, "topic_id", "")
or getattr(data, "id", "")
)Recommendation: Extract to a helper function: def _get_first_attr(obj, *attrs, default=""):
"""Get first non-empty attribute value."""
for attr in attrs:
val = getattr(obj, attr, None)
if val:
return val
return default5. Performance ConsiderationsN+1 Query Problem (opinion.py:274-291): for i, token_id in enumerate(token_ids):
orderbook = self.get_orderbook(token_id) # Separate HTTP call per tokenFor multi-outcome markets with 10+ outcomes, this could be 10+ API calls per market. Recommendation:
Unnecessary Double Limit (opinion.py:395-396): limit = min(query_params.get("limit", 20), 20) # API enforces max 20
...
markets = markets[: query_params["limit"]] # Then slices againThis applies the limit twice - once in the API call, then again in Python. 6. Type Safety IssuesMissing Type Hints:
Recommendation: Use proper return types or create typed response models. Unsafe String to Int Conversion (opinion.py:130-135): def _parse_market_id(self, market_id: str) -> int:
try:
return int(market_id)
except (ValueError, TypeError):
raise ExchangeError(f"Invalid market_id: {market_id}")This accepts string input but returns int. Consider accepting 7. Testing GapsWhile test coverage is good, notable gaps include:
Recommendation: Add integration tests that verify:
Potential Bugs1. Incorrect Time Handling (opinion.py:302-303)if isinstance(cutoff_time, (int, float)) and cutoff_time > 0:
close_time = datetime.fromtimestamp(cutoff_time, tz=timezone.utc)If Fix: Check magnitude and divide by 1000 if needed. 2. Status Comparison Issue (opinion.py:339-342)status = getattr(data, "status", None)
if status == TopicStatus.RESOLVED.value:
metadata["closed"] = True
elif status == TopicStatus.ACTIVATED.value:
metadata["closed"] = FalseIf Fix: Add else clause with default value or log warning. 3. Division by Zero Risk (check_approval.py:66)pnl_str = f"+{pos.unrealized_pnl:.2f}" if pos.unrealized_pnl >= 0 else f"{pos.unrealized_pnl:.2f}"While not division by zero, if 4. Race Condition in Order Status (opinion.py:648-654)The order status is set to OPEN immediately after placement, but actual status should come from the API response. If the order is immediately filled or rejected, the returned status will be incorrect. Documentation & ExamplesStrengths
Issues
Security Checklist
Recommendations SummaryMust Fix (Before Merge)
Should Fix (High Priority)
Nice to Have
ConclusionThis is a solid implementation that follows the project's architectural patterns well. The main concerns are:
With the "Must Fix" items addressed, this would be ready to merge. The code quality is generally high and test coverage is reasonable for a first implementation. Overall Assessment: |
Pull Request Review: Opinion Exchange SupportThis PR adds comprehensive Opinion exchange integration to dr-manhattan. Overall, this is a solid implementation with good test coverage and examples. Below are my findings organized by category. ✅ StrengthsCode Quality
Testing
Documentation
|
Pull Request Review: Add Opinion Exchange SupportSummaryThis PR adds comprehensive Opinion exchange integration to dr-manhattan, including a full trading API client, market listing, order management, and strategy examples. The implementation follows the existing CCXT-style unified API pattern and maintains consistency with the Polymarket and Limitless implementations. Code Quality AssessmentStrengths
Issues and ConcernsCritical Issues1. Security: .env.example Violates CLAUDE.md Guidelines (CRITICAL)Location: The PR adds Opinion credentials to Issue: CLAUDE.md rule #4 states: "Single Source of Truth: DO NOT place many variables in .env file. Place them in the code instead." Recommendation: Remove these from 2. Missing Input Validation on Private Keys (HIGH SECURITY)Location: self.private_key = self.config.get("private_key", "")
# No validation that private_key is properly formatted
if self.api_key and self.private_key and self.multi_sig_addr:
self._initialize_client()Issue: No validation that the private key is properly formatted (e.g., starts with 0x, correct length). Invalid keys could cause runtime errors or security issues downstream. Recommendation: Add validation: def _validate_private_key(self, key: str) -> bool:
if not key.startswith('0x') or len(key) != 66:
raise AuthenticationError("Invalid private key format")
return True3. Broad Exception Catching Without Logging (MEDIUM)Location: Multiple locations, e.g., except Exception:
pass # Silent failureIssue: Multiple instances of bare Recommendation: At minimum, log errors when verbose mode is enabled: except Exception as e:
if self.verbose:
print(f"Warning: Failed to fetch prices: {e}")Code Quality Issues4. Inconsistent Error Response Handling (MEDIUM)Location: The Recommendation: Create a helper method that attempts both calls or check market type before fetching. 5. Magic Numbers in Code (LOW)Location: for page in range(1, 6): # Why 5 pages?Recommendation: Extract to named constant: MAX_SEARCH_PAGES = 5
for page in range(1, MAX_SEARCH_PAGES + 1):6. Incomplete Type Hints (LOW)Location: Multiple files Several methods use def _parse_market_response(self, response: Any, operation: str = "operation") -> Any:Recommendation: Use more specific types from the opinion_clob_sdk where possible. 7. Duplicate Constants (LOW)Location: BASE_URL = "https://proxy.opinion.trade:8443"
DATA_API_URL = "https://proxy.opinion.trade:8443" # Same as BASE_URLRecommendation: If they're the same, remove duplication. If they might differ in future, add a comment explaining why both exist. Performance Considerations8. Orderbook Fetching in Loop (MEDIUM)Location: When parsing markets with for i, token_id in enumerate(token_ids):
orderbook = self.get_orderbook(token_id) # N+1 query problemIssue: For categorical markets with many outcomes, this creates many sequential API calls. Recommendation:
9. No Rate Limiting in Custom Requests (MEDIUM)Location: The Recommendation: Apply rate limiting to HTTP requests: @self._rate_limit
def _request(self, method: str, endpoint: str, params: Optional[Dict] = None):
# ... existing codeTesting Concerns10. Tests Not Run in CI (MEDIUM)The PR shows test code but the command Recommendation: Ensure tests run in CI pipeline. According to CLAUDE.md rule #5: "Run and Debug yourself PROACTIVELY." 11. Mock Tests Don't Validate SDK Integration (LOW)Tests use Recommendation: Add integration tests (perhaps as optional tests that run when credentials are available) or at least import checks to ensure SDK compatibility. Best Practices12. Inconsistent Ordering Method Parameters (LOW)Location: def create_order(
self,
market_id: str,
outcome: str,
side: OrderSide,
price: float,
size: float,
params: Optional[Dict[str, Any]] = None,
)The method requires Recommendation: Consider making Security Concerns
DocumentationThe PR includes good documentation:
Minor Issue: The examples use environment variables (OPINION_API_KEY, etc.) which contradicts CLAUDE.md rule #4 about minimizing .env usage. PerformanceOverall performance looks good:
Test CoverageTest coverage appears comprehensive with 310 lines of tests covering:
Recommendation: Add integration tests or a test script that can be run manually against testnet. Overall AssessmentRecommendation: Approve with Minor Changes Required This is a solid implementation that maintains consistency with the existing codebase architecture. The code quality is good, error handling is comprehensive, and test coverage is adequate. Must Fix Before Merge:
Should Fix:
Nice to Have:
The implementation demonstrates good understanding of the existing patterns and provides a clean, functional integration with Opinion exchange. Great work! |
- Implement Opinion exchange client with full trading API - Add market listing and order management functionality - Include spread strategy example and approval check script - Add comprehensive tests for Opinion integration
- Introduced NAV dataclass for Net Asset Value calculation. - Implemented calculate_nav method to compute NAV for specific markets, including cash and positions breakdown. - Enhanced balance and position fetching logic for accurate NAV computation.
- Reformatted code in opinion.py for better structure and clarity. - Updated test cases in test_integration.py and test_opinion.py to reflect changes in market data structure. - Enhanced mock data in tests to align with actual API responses.
…ling - Removed redundant market ID assignment logic from Opinion class. - Cleaned up imports in test_opinion.py for better organization.
- Introduced a new method _parse_market_id to safely convert market_id strings to integers. - Updated all relevant calls to ensure consistent market ID parsing throughout the Opinion class. - Improved error handling for invalid market_id inputs.
- Implemented validation to ensure order prices align with the defined tick size of 0.01. - Added error handling for prices that do not meet the tick size requirement, enhancing order input integrity.
- Added missing Opinion trading configuration parameters to .env.example. - Defined CONDITIONAL_TOKEN_ADDR and MULTISEND_ADDR in the Opinion class for better clarity and usage.
- Updated tick size validation to 0.001 for better precision in order pricing. - Enhanced order ID parsing from API responses to accommodate different response structures. - Improved position and order fetching logic for multi-outcome markets. - Added order fill tracking capabilities to the SpreadStrategy for better monitoring of order executions. - Refactored price rounding and validation to align with Opinion API requirements.
19a2fcf to
590d0df
Compare
Pull Request Review: Add Opinion Exchange SupportOverall AssessmentThis is a well-structured and comprehensive implementation that successfully adds Opinion exchange support following the existing architecture patterns. The code quality is high with good test coverage and examples. However, there are several areas requiring attention. Code Quality & Best Practices✅ Strengths
|