|
|
@@ -1,72 +1,322 @@
|
|
|
-This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
|
|
|
+# Byreal Table
|
|
|
|
|
|
-## 环境变量配置
|
|
|
+Byreal Table 是一个专为 ByReal DEX 设计的流动性仓位管理工具,提供仓位监控、批量操作、跟单复制等功能。
|
|
|
+
|
|
|
+## 功能特性
|
|
|
+
|
|
|
+### 核心功能
|
|
|
+
|
|
|
+- **仓位总览**: 查看所有流动性池中的仓位排名和数据
|
|
|
+- **我的 LP**: 管理个人流动性仓位,支持批量操作
|
|
|
+- **快速跟单**: 一键复制优质仓位策略
|
|
|
+- **批量关仓**: 支持批量关闭仓位,包括出区间仓位和上级已关仓位
|
|
|
+- **自动加仓**: 支持狙击式加仓,可设置倍数
|
|
|
+- **APR 计算**: 实时计算仓位年化收益率
|
|
|
+
|
|
|
+### 主要页面
|
|
|
+
|
|
|
+#### 1. 仓位列表页 (`/position`)
|
|
|
+
|
|
|
+展示指定流动性池中的所有仓位,支持:
|
|
|
+
|
|
|
+- 按流动性、APR、创建时间等字段排序
|
|
|
+- 查看仓位价格区间和区间状态
|
|
|
+- 快速复制优质仓位
|
|
|
+- 批量复制功能
|
|
|
+- 展开查看子仓位(跟单仓位)
|
|
|
+
|
|
|
+#### 2. 我的 LP 页 (`/my-lp`)
|
|
|
+
|
|
|
+管理个人流动性仓位,支持:
|
|
|
+
|
|
|
+- 查看所有个人仓位及其收益
|
|
|
+- 一键关闭上级已关仓的仓位
|
|
|
+- 一键关闭出区间仓位
|
|
|
+- 批量快速关仓
|
|
|
+- 快速加仓和狙击加仓
|
|
|
+- 查看跟单仓位详情和收益
|
|
|
+
|
|
|
+## 技术栈
|
|
|
+
|
|
|
+- **框架**: Next.js 16 (App Router)
|
|
|
+- **语言**: TypeScript 5
|
|
|
+- **UI 组件**: Ant Design 6
|
|
|
+- **样式**: Tailwind CSS 4
|
|
|
+- **区块链**: Solana Web3.js, @solana/spl-token
|
|
|
+- **SDK**: ByReal CLMM SDK (内置)
|
|
|
+- **价格预言机**: Jupiter Price API v3
|
|
|
+- **Web 服务器**: Caddy (HTTPS + Basic Auth)
|
|
|
+- **部署**: Docker & Docker Compose
|
|
|
+
|
|
|
+## 项目结构
|
|
|
+
|
|
|
+```
|
|
|
+byreal-table/
|
|
|
+├── src/
|
|
|
+│ ├── app/ # Next.js App Router 页面
|
|
|
+│ │ ├── position/ # 仓位总览页面
|
|
|
+│ │ ├── my-lp/ # 我的 LP 管理页面
|
|
|
+│ │ ├── lp-copy/ # 跟单复制页面
|
|
|
+│ │ ├── api/ # API 路由
|
|
|
+│ │ │ ├── my-lp/ # LP 相关 API
|
|
|
+│ │ │ ├── lp-index/ # 仓位操作 API
|
|
|
+│ │ │ ├── lp-copy/ # 复制 API
|
|
|
+│ │ │ ├── top-positions/ # 排名 API
|
|
|
+│ │ │ └── pools/list/ # 流动性池列表 API
|
|
|
+│ │ └── components/ # React 组件
|
|
|
+│ ├── lib/
|
|
|
+│ │ ├── byreal-clmm-sdk/ # ByReal CLMM SDK
|
|
|
+│ │ ├── config.ts # 全局配置
|
|
|
+│ │ ├── solana-config.ts # Solana RPC 配置
|
|
|
+│ │ └── jupiter.ts # Jupiter 价格 API
|
|
|
+├── docker-compose.yml # Docker 编排配置
|
|
|
+├── Caddyfile # Caddy 服务器配置
|
|
|
+└── .env.example # 环境变量示例
|
|
|
+```
|
|
|
+
|
|
|
+## 快速开始
|
|
|
+
|
|
|
+### 环境要求
|
|
|
+
|
|
|
+- Node.js 20+
|
|
|
+- pnpm
|
|
|
+- Docker & Docker Compose (生产环境部署)
|
|
|
|
|
|
### 本地开发
|
|
|
|
|
|
-1. 创建 `.env.local` 文件(此文件已被 `.gitignore` 忽略,不会提交到 Git):
|
|
|
+1. 安装依赖
|
|
|
|
|
|
```bash
|
|
|
-# Solana RPC 地址
|
|
|
-SOL_ENDPOINT=https://lb.drpc.live/solana/
|
|
|
-
|
|
|
-# Solana 私钥(用于签名交易,敏感信息,不要提交到 Git)
|
|
|
-SOL_SECRET_KEY=your_secret_key_here
|
|
|
+pnpm install
|
|
|
```
|
|
|
|
|
|
-2. 或者参考 `.env.example` 文件创建 `.env.local`
|
|
|
+2. 配置环境变量
|
|
|
|
|
|
-### Docker 运行
|
|
|
+```bash
|
|
|
+cp .env.example .env.local
|
|
|
+```
|
|
|
|
|
|
-创建.env文件,添加以下内容
|
|
|
+编辑 `.env.local`:
|
|
|
|
|
|
```bash
|
|
|
# Solana RPC 地址
|
|
|
SOL_ENDPOINT=https://lb.drpc.live/solana/
|
|
|
|
|
|
-# Solana 私钥(用于签名交易,敏感信息,不要提交到 Git)
|
|
|
+# Solana 私钥(用于签名交易)
|
|
|
SOL_SECRET_KEY=your_secret_key_here
|
|
|
+
|
|
|
+# Jupiter API Key (可选,用于提高速率限制)
|
|
|
+JUPITER_API_KEY=your_jupiter_api_key
|
|
|
```
|
|
|
|
|
|
-直接启动(会先自动编译)
|
|
|
+3. 启动开发服务器
|
|
|
|
|
|
```bash
|
|
|
+pnpm dev
|
|
|
+```
|
|
|
+
|
|
|
+访问 [http://localhost:3000](http://localhost:3000)
|
|
|
+
|
|
|
+### Docker 部署
|
|
|
|
|
|
+1. 准备环境文件
|
|
|
+
|
|
|
+```bash
|
|
|
+cp .env.example .env
|
|
|
+```
|
|
|
+
|
|
|
+编辑 `.env` 文件,配置必要的环境变量。
|
|
|
+
|
|
|
+2. 生成 Basic Auth 密码文件
|
|
|
+
|
|
|
+```bash
|
|
|
+# 生成密码哈希
|
|
|
+HASH=$(docker run --rm caddy:2-alpine caddy hash-password --plaintext 'your_password')
|
|
|
+
|
|
|
+# 写入 htpasswd 文件
|
|
|
+echo "admin $HASH" > htpasswd
|
|
|
+```
|
|
|
+
|
|
|
+3. 启动服务
|
|
|
+
|
|
|
+```bash
|
|
|
+# 安装 httpd (用于 htpasswd 工具,可选)
|
|
|
apt install httpd
|
|
|
|
|
|
-# 按提示输入两次密码
|
|
|
-htpasswd -c ./htpasswd admin
|
|
|
+# 或使用 Docker 生成
|
|
|
+docker run --rm caddy:2-alpine caddy hash-password --plaintext 'your_password'
|
|
|
|
|
|
+# 启动所有服务
|
|
|
docker compose up -d
|
|
|
+```
|
|
|
+
|
|
|
+4. 查看日志
|
|
|
+
|
|
|
+```bash
|
|
|
+docker compose logs -f
|
|
|
+```
|
|
|
+
|
|
|
+## 环境变量说明
|
|
|
+
|
|
|
+| 变量名 | 说明 | 是否必需 |
|
|
|
+| ----------------- | --------------------------------- | -------- |
|
|
|
+| `SOL_ENDPOINT` | Solana RPC 节点地址 | 是 |
|
|
|
+| `SOL_SECRET_KEY` | Solana 钱包私钥 (Base58 格式) | 是 |
|
|
|
+| `JUPITER_API_KEY` | Jupiter API Key | 否 |
|
|
|
+| `NODE_ENV` | 运行环境 (development/production) | 否 |
|
|
|
+
|
|
|
+## API 文档
|
|
|
+
|
|
|
+### 仓位相关 API
|
|
|
|
|
|
+#### 获取仓位列表
|
|
|
+
|
|
|
+```
|
|
|
+GET /api/my-lp?userAddress={address}&page={page}&pageSize={size}&status={status}
|
|
|
+```
|
|
|
+
|
|
|
+#### 获取仓位详情
|
|
|
+
|
|
|
+```
|
|
|
+GET /api/my-lp/detail?address={positionAddress}
|
|
|
+```
|
|
|
+
|
|
|
+#### 获取复制信息
|
|
|
+
|
|
|
+```
|
|
|
+GET /api/my-lp/copyInfo?parentPositionAddress={address}&poolAddress={pool}
|
|
|
+```
|
|
|
+
|
|
|
+### 操作 API
|
|
|
+
|
|
|
+#### 添加流动性
|
|
|
+
|
|
|
+```
|
|
|
+POST /api/lp-index/lp-add
|
|
|
+Body: {
|
|
|
+ "nftMintAddress": string,
|
|
|
+ "addUsdValue": number,
|
|
|
+ "needSwap": boolean
|
|
|
+}
|
|
|
```
|
|
|
|
|
|
-### 使用 RPC 地址
|
|
|
+#### 关闭仓位
|
|
|
+
|
|
|
+```
|
|
|
+POST /api/lp-index/lp-close
|
|
|
+Body: {
|
|
|
+ "nftMintAddress": string
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+#### 复制仓位
|
|
|
+
|
|
|
+```
|
|
|
+POST /api/lp-copy
|
|
|
+Body: {
|
|
|
+ "positionAddress": string,
|
|
|
+ "nftMintAddress": string,
|
|
|
+ "maxUsdValue": number,
|
|
|
+ "needSwap": boolean
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+## 安全配置
|
|
|
+
|
|
|
+### Basic Auth
|
|
|
+
|
|
|
+项目使用 Caddy 提供 Basic Auth 认证,保护 API 接口不被未授权访问。
|
|
|
+
|
|
|
+详细配置请参考 [API_AUTH.md](./API_AUTH.md)
|
|
|
|
|
|
-在代码中使用 `src/lib/solana-config.ts` 中的工具函数:
|
|
|
+### 私钥安全
|
|
|
+
|
|
|
+- 私钥存储在环境变量中,不会提交到 Git
|
|
|
+- 生产环境建议使用密钥管理服务 (如 AWS Secrets Manager)
|
|
|
+- 定期轮换私钥
|
|
|
+
|
|
|
+## 开发指南
|
|
|
+
|
|
|
+### 添加新的 API 路由
|
|
|
+
|
|
|
+在 `src/app/api` 目录下创建新的路由文件:
|
|
|
|
|
|
```typescript
|
|
|
-import { getSolanaRpcUrl } from '@/lib/solana-config'
|
|
|
+// src/app/api/example/route.ts
|
|
|
+import { NextRequest, NextResponse } from 'next/server'
|
|
|
|
|
|
-const rpcUrl = getSolanaRpcUrl()
|
|
|
+export async function GET(request: NextRequest) {
|
|
|
+ // 处理逻辑
|
|
|
+ return NextResponse.json({ data: 'example' })
|
|
|
+}
|
|
|
```
|
|
|
|
|
|
-## Getting Started
|
|
|
+### 使用 ByReal CLMM SDK
|
|
|
|
|
|
-First, run the development server:
|
|
|
+```typescript
|
|
|
+import { chain } from '@/lib/config'
|
|
|
|
|
|
-```bash
|
|
|
-npm run dev
|
|
|
-# or
|
|
|
-yarn dev
|
|
|
-# or
|
|
|
-pnpm dev
|
|
|
-# or
|
|
|
-bun dev
|
|
|
+// 获取仓位信息
|
|
|
+const positionInfo = await chain.getPositionInfoByNftMint(nftMint)
|
|
|
+
|
|
|
+// 添加流动性
|
|
|
+const txid = await chain.addLiquidity({
|
|
|
+ userAddress,
|
|
|
+ nftMint,
|
|
|
+ base: 'MintA',
|
|
|
+ baseAmount,
|
|
|
+ otherAmountMax,
|
|
|
+ signerCallback,
|
|
|
+})
|
|
|
+
|
|
|
+// 关闭仓位
|
|
|
+const txid = await chain.decreaseFullLiquidity({
|
|
|
+ userAddress,
|
|
|
+ nftMint,
|
|
|
+ signerCallback,
|
|
|
+})
|
|
|
```
|
|
|
|
|
|
-Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
|
+### 价格计算
|
|
|
+
|
|
|
+项目使用多种价格来源:
|
|
|
+
|
|
|
+1. ByReal API (优先)
|
|
|
+2. Jupiter Price API v3
|
|
|
+3. 稳定币逻辑 (USDC/USDT = $1)
|
|
|
+4. 相对价格 (非稳定币对)
|
|
|
+
|
|
|
+## 常见问题
|
|
|
+
|
|
|
+### Q: 如何获取 Solana RPC 地址?
|
|
|
+
|
|
|
+A: 可以使用公共 RPC 如 `https://api.mainnet-beta.solana.com`,或使用第三方服务如 DRPC、QuickNode。
|
|
|
+
|
|
|
+### Q: 交易失败怎么办?
|
|
|
+
|
|
|
+A: 检查以下几点:
|
|
|
+
|
|
|
+- 钱包余额是否充足
|
|
|
+- Solana 网络是否拥堵
|
|
|
+- 滑点设置是否合理
|
|
|
+- RPC 节点是否稳定
|
|
|
+
|
|
|
+### Q: 如何批量操作仓位?
|
|
|
+
|
|
|
+A: 在"我的 LP"页面选择多个仓位,然后点击"批量快速关仓"按钮。
|
|
|
+
|
|
|
+### Q: 狙击加仓如何使用?
|
|
|
+
|
|
|
+A: 在"我的 LP"页面,展开有跟单位置的仓位,在子表格中设置金额和倍数,点击狙击图标即可。
|
|
|
+
|
|
|
+## 贡献指南
|
|
|
+
|
|
|
+欢迎提交 Issue 和 Pull Request!
|
|
|
+
|
|
|
+## 许可证
|
|
|
+
|
|
|
+MIT
|
|
|
|
|
|
-You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
|
|
|
+## 免责声明
|
|
|
|
|
|
-This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
|
|
|
+本工具仅供学习和研究使用,不构成投资建议。使用本工具进行交易所产生的风险由用户自行承担。
|