Files
WrBug 89fb980da7 refactor: 移除 polygon.rpc.url 配置,使用 RpcNodeService 统一管理 RPC 节点
- 删除 application.properties 中的 polygon.rpc.url 配置
- 更新 ApiHealthCheckService 直接使用 RpcNodeService.getHttpUrl()
- 删除所有 Docker Compose 配置中的 POLYGON_RPC_URL 环境变量
- 删除所有部署脚本中的 POLYGON_RPC_URL 环境变量
- 更新所有文档,移除 POLYGON_RPC_URL 相关说明
- 删除 application.properties 中无用的 position.push 配置项
- 修正日志配置中的包名(polyhermes -> polymarketbot)

现在系统通过 RpcNodeService 从数据库读取 RPC 节点配置,用户可以通过系统设置页面管理 RPC 节点,不再需要环境变量配置。
2025-12-28 04:51:07 +08:00

15 KiB

PolyHermes Development Guide

📖 中文版本: 开发文档(中文)

This document describes the development guide for the PolyHermes project, including project structure, development environment setup, code standards, API interfaces, etc.

📋 Table of Contents

📦 Project Structure

polyhermes/
├── backend/                    # Backend service
│   ├── src/main/kotlin/
│   │   └── com/wrbug/polymarketbot/
│   │       ├── api/            # API interface definitions (Retrofit)
│   │       ├── config/         # Configuration classes
│   │       ├── controller/     # REST controllers
│   │       ├── dto/            # Data Transfer Objects
│   │       ├── entity/         # Database entities
│   │       ├── repository/     # Data access layer
│   │       ├── service/        # Business logic services
│   │       ├── util/           # Utility classes
│   │       └── websocket/       # WebSocket handling
│   └── src/main/resources/
│       ├── application.properties
│       └── db/migration/       # Flyway database migration scripts
├── frontend/                   # Frontend application
│   ├── src/
│   │   ├── components/        # Common components
│   │   ├── pages/              # Page components
│   │   ├── services/           # API services
│   │   ├── store/              # State management (Zustand)
│   │   ├── types/              # TypeScript type definitions
│   │   ├── utils/              # Utility functions
│   │   ├── hooks/              # React Hooks
│   │   ├── locales/            # Internationalization resources
│   │   └── styles/             # Style files
│   └── public/                 # Static resources
├── docs/                       # Documentation
│   ├── zh/                     # Chinese documentation
│   │   ├── DEPLOYMENT.md       # Deployment documentation
│   │   ├── VERSION_MANAGEMENT.md  # Version management documentation
│   │   └── ...
│   ├── en/                     # English documentation
│   │   ├── DEPLOYMENT.md       # Deployment documentation
│   │   ├── VERSION_MANAGEMENT.md  # Version management documentation
│   │   └── ...
│   └── copy-trading-requirements.md  # Copy trading system requirements
├── .github/workflows/          # GitHub Actions workflows
└── README.md                   # Project description

🛠️ Development Environment Setup

Prerequisites

  • JDK: 17+
  • Node.js: 18+
  • MySQL: 8.0+
  • Gradle: 7.5+ (or use Gradle Wrapper)
  • Docker: 20.10+ (optional, for containerized deployment)

Backend Development Environment

  1. Clone Repository
git clone https://github.com/WrBug/PolyHermes.git
cd PolyHermes
  1. Configure Database

Create MySQL database:

CREATE DATABASE polyhermes CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
  1. Configure Environment Variables

Edit backend/src/main/resources/application.properties or use environment variables:

# Database configuration
spring.datasource.url=jdbc:mysql://localhost:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8mb4
spring.datasource.username=${DB_USERNAME:root}
spring.datasource.password=${DB_PASSWORD:password}

# Server port
server.port=${SERVER_PORT:8000}

# JWT secret
jwt.secret=${JWT_SECRET:change-me-in-production}

# Encryption key (for encrypting stored private keys and API Keys)
crypto.secret.key=${CRYPTO_SECRET_KEY:change-me-in-production}
  1. Start Backend Service
cd backend
./gradlew bootRun

Backend service will start at http://localhost:8000.

Frontend Development Environment

  1. Install Dependencies
cd frontend
npm install
  1. Configure Environment Variables (Optional)

Create .env file:

VITE_API_URL=http://localhost:8000
VITE_WS_URL=ws://localhost:8000
  1. Start Development Server
npm run dev

Frontend application will start at http://localhost:3000.

📝 Code Standards

Backend Development Standards

For detailed standards, please refer to: Backend Development Standards

Core Standards:

  • Follow Kotlin coding standards
  • Controller methods must not use suspend
  • Entity ID fields use Long? = null
  • All time fields use Long timestamps (milliseconds)
  • Use BigDecimal for numerical calculations
  • Use ErrorCode enum to define error codes and messages
  • Do not add TODO comments in code
  • Do not directly return mock data

Frontend Development Standards

For detailed standards, please refer to: Frontend Development Standards

Core Standards:

  • Use TypeScript type definitions
  • Use functional components and Hooks
  • Do not use any type
  • Must use internationalization (i18n) for all text display
  • Must use formatUSDC function to format USDC amounts
  • Must support mobile and desktop
  • Do not add TODO comments in code

Commit Standards

Follow Conventional Commits standards:

  • feat: New feature
  • fix: Bug fix
  • docs: Documentation update
  • style: Code style adjustment
  • refactor: Code refactoring
  • test: Test related
  • chore: Build/tool related

Examples:

git commit -m "feat: Add version number display feature"
git commit -m "fix: Fix order status update issue"

📡 API Documentation

Unified Response Format

All API interfaces use POST method uniformly, response format as follows:

{
  "code": 0,
  "data": {},
  "msg": ""
}
  • code: Response code, 0 means success, non-0 means failure
  • data: Response data, can be any type
  • msg: Response message, usually empty on success, contains error message on failure

Error Code Standards

  • 0: Success
  • 1001-1999: Parameter error
  • 2001-2999: Authentication/permission error
  • 3001-3999: Resource not found
  • 4001-4999: Business logic error
  • 5001-5999: Server internal error

Main API Interfaces

Account Management

  • POST /api/accounts/list - Get account list
  • POST /api/accounts/import - Import account (via private key)
  • POST /api/accounts/detail - Get account details
  • POST /api/accounts/edit - Edit account
  • POST /api/accounts/delete - Delete account
  • POST /api/accounts/balance - Get account balance

Leader Management

  • POST /api/leaders/list - Get Leader list
  • POST /api/leaders/add - Add Leader
  • POST /api/leaders/edit - Edit Leader
  • POST /api/leaders/delete - Delete Leader

Copy Trading Templates

  • POST /api/templates/list - Get template list
  • POST /api/templates/add - Add template
  • POST /api/templates/edit - Edit template
  • POST /api/templates/delete - Delete template

Copy Trading Configuration

  • POST /api/copy-trading/list - Get copy trading configuration list
  • POST /api/copy-trading/add - Add copy trading configuration
  • POST /api/copy-trading/edit - Edit copy trading configuration
  • POST /api/copy-trading/delete - Delete copy trading configuration
  • POST /api/copy-trading/enable - Enable copy trading
  • POST /api/copy-trading/disable - Disable copy trading

Order Management

  • POST /api/copy-trading/orders/buy - Get buy order list
  • POST /api/copy-trading/orders/sell - Get sell order list
  • POST /api/copy-trading/orders/matched - Get matched order list

Statistical Analysis

  • POST /api/statistics/global - Get global statistics
  • POST /api/statistics/leader - Get Leader statistics
  • POST /api/statistics/category - Get category statistics
  • POST /api/copy-trading/statistics - Get copy trading relationship statistics

Position Management

  • POST /api/positions/list - Get position list
  • POST /api/positions/sell - Sell position
  • POST /api/positions/redeem - Redeem position

System Management

  • POST /api/system-settings/proxy - Configure proxy
  • POST /api/system-settings/api-health - Get API health status
  • POST /api/users/list - Get user list
  • POST /api/users/add - Add user
  • POST /api/users/edit - Edit user
  • POST /api/users/delete - Delete user

For detailed API interface documentation, please refer to: Copy Trading System Requirements

🗄️ Database Design

Main Data Tables

  • accounts - Account table
  • leaders - Leader table
  • templates - Copy trading template table
  • copy_trading - Copy trading configuration table
  • copy_orders - Copy trading order table
  • positions - Position table
  • users - User table
  • system_settings - System settings table

Database migration scripts are located at backend/src/main/resources/db/migration/, managed using Flyway.

🎨 Frontend Development Guide

Project Structure

frontend/src/
├── components/          # Common components
│   ├── Layout.tsx      # Layout component (supports mobile)
│   └── Logo.tsx        # Logo component
├── pages/              # Page components
│   ├── AccountList.tsx
│   ├── LeaderList.tsx
│   ├── CopyTradingList.tsx
│   └── ...
├── services/           # API services
│   ├── api.ts         # API service definitions
│   └── websocket.ts   # WebSocket service
├── store/             # State management (Zustand)
├── types/             # TypeScript type definitions
├── utils/             # Utility functions
│   ├── index.ts       # Unified export
│   ├── ethers.ts      # Ethereum related utilities
│   ├── auth.ts        # Authentication related utilities
│   └── version.ts     # Version number utilities
├── hooks/             # React Hooks
├── locales/           # Internationalization resources
│   ├── zh-CN/
│   ├── zh-TW/
│   └── en/
└── styles/            # Style files

Internationalization Support

The project supports multiple languages (Simplified Chinese, Traditional Chinese, English), using react-i18next.

Adding New Translations:

  1. Add translations in src/locales/{locale}/common.json
  2. Use useTranslation Hook in components:
import { useTranslation } from 'react-i18next'

const MyComponent: React.FC = () => {
  const { t } = useTranslation()
  return <div>{t('key')}</div>
}

Mobile Adaptation

  • Use react-responsive to detect device type
  • Breakpoint settings: Mobile < 768px, Desktop >= 768px
  • Use responsive layouts and components

Utility Functions

USDC Amount Formatting:

import { formatUSDC } from '../utils'

const balance = formatUSDC('1.23456')  // "1.2345"

Ethereum Address Validation:

import { isValidWalletAddress } from '../utils'

if (isValidWalletAddress(address)) {
  // Address is valid
}

⚙️ Backend Development Guide

Project Structure

backend/src/main/kotlin/com/wrbug/polymarketbot/
├── api/                # API interface definitions (Retrofit)
│   ├── PolymarketClobApi.kt
│   ├── PolymarketGammaApi.kt
│   └── GitHubApi.kt
├── controller/         # REST controllers
├── service/            # Business logic services
├── entity/             # Database entities
├── repository/         # Data access layer
├── dto/                # Data Transfer Objects
├── util/               # Utility classes
│   ├── CryptoUtils.kt  # Encryption utilities
│   ├── RetrofitFactory.kt  # Retrofit factory
│   └── ...
└── websocket/          # WebSocket handling

Creating New API Interface

  1. Define Retrofit Interface (in api/ directory):
interface MyApi {
    @POST("/endpoint")
    suspend fun myMethod(@Body request: MyRequest): Response<MyResponse>
}
  1. Create Service (in service/ directory):
@Service
class MyService(
    private val myApi: MyApi
) {
    suspend fun doSomething(): Result<MyResponse> {
        // Business logic
    }
}
  1. Create Controller (in controller/ directory):
@RestController
@RequestMapping("/api/my")
class MyController(
    private val myService: MyService,
    private val messageSource: MessageSource
) {
    @PostMapping("/list")
    fun list(@RequestBody request: MyListRequest): ResponseEntity<ApiResponse<MyListResponse>> {
        return try {
            val data = runBlocking { myService.getList(request) }
            ResponseEntity.ok(ApiResponse.success(data))
        } catch (e: Exception) {
            logger.error("Failed to get list", e)
            ResponseEntity.ok(ApiResponse.error(ErrorCode.SERVER_ERROR, messageSource = messageSource))
        }
    }
}

Database Operations

Using Spring Data JPA:

@Repository
interface MyRepository : JpaRepository<MyEntity, Long> {
    fun findByCode(code: String): MyEntity?
    fun findByCategory(category: String): List<MyEntity>
}

Encrypted Storage

Use CryptoUtils to encrypt sensitive data:

@Autowired
private lateinit var cryptoUtils: CryptoUtils

// Encrypt
val encrypted = cryptoUtils.encrypt("sensitive-data")

// Decrypt
val decrypted = cryptoUtils.decrypt(encrypted)

🔧 FAQ

Q1: How to add a new page?

  1. Create page component in frontend/src/pages/
  2. Add route in frontend/src/App.tsx
  3. Add menu item in frontend/src/components/Layout.tsx (if needed)

Q2: How to add a new API interface?

  1. Create Controller in backend/src/main/kotlin/.../controller/
  2. Create Service in backend/src/main/kotlin/.../service/
  3. Add API call method in frontend/src/services/api.ts

Q3: How to add a database table?

  1. Create Entity class (in entity/ directory)
  2. Create Repository interface (in repository/ directory)
  3. Create Flyway migration script (in resources/db/migration/)

Q4: How to test WebSocket?

Use browser console or WebSocket client tool to connect to ws://localhost:8000/ws

Q5: How to debug backend code?

  1. Use IDE's debugging feature (IntelliJ IDEA, VS Code, etc.)
  2. Add logs in code: logger.debug("Debug info")
  3. View log output: ./gradlew bootRun or view log files

🤝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork this repository
  2. Create a feature branch (git checkout -b feature/AmazingFeature)
  3. Follow code standards
  4. Commit your changes (git commit -m 'feat: Add some AmazingFeature')
  5. Push to the branch (git push origin feature/AmazingFeature)
  6. Open a Pull Request

Happy Coding! 🚀