Bladeren bron

get price range

lushdog@outlook.com 1 maand geleden
bovenliggende
commit
9a8454deea
4 gewijzigde bestanden met toevoegingen van 144 en 29 verwijderingen
  1. 0 2
      docker-compose.yml
  2. 42 1
      src/app/api/my-lp/detail/route.ts
  3. 28 0
      src/app/api/my-lp/getAddress/route.ts
  4. 74 26
      src/app/my-lp/page.tsx

+ 0 - 2
docker-compose.yml

@@ -1,5 +1,3 @@
-version: '3.8'
-
 services:
   byreal-table:
     build:

+ 42 - 1
src/app/api/my-lp/detail/route.ts

@@ -1,3 +1,4 @@
+import { TickMath } from '@/lib/byreal-clmm-sdk/src/instructions/utils/tickMath'
 import { NextRequest, NextResponse } from 'next/server'
 
 export async function GET(request: NextRequest) {
@@ -23,7 +24,47 @@ export async function GET(request: NextRequest) {
 		}
 
 		const data = await response.json()
-		return NextResponse.json(data)
+
+		const { pool, lowerTick, upperTick } = data.result?.data as {
+			lowerTick: number
+			upperTick: number
+			pool: {
+				mintA: { decimals: number; price: string }
+				mintB: { decimals: number; price: string }
+			}
+		}
+		const priceLower = TickMath.getPriceFromTick({
+			tick: lowerTick,
+			decimalsA: pool.mintA.decimals,
+			decimalsB: pool.mintB.decimals,
+		})
+
+		const priceUpper = TickMath.getPriceFromTick({
+			tick: upperTick,
+			decimalsA: pool.mintA.decimals,
+			decimalsB: pool.mintB.decimals,
+		})
+		const isInRange =
+			Number(pool.mintA.price) < priceUpper.toNumber() &&
+			Number(pool.mintA.price) > priceLower.toNumber()
+		const newData = {
+			...data,
+			result: {
+				data: {
+					...data.result.data,
+					priceLower: priceLower.toString(),
+					priceUpper: priceUpper.toString(),
+					isInRange,
+					priceOutType: isInRange
+						? 'inRange'
+						: Number(pool.mintA.price) > priceUpper.toNumber()
+							? 'priceUp'
+							: 'priceDown',
+				},
+			},
+		}
+
+		return NextResponse.json(newData)
 	} catch (error) {
 		console.error('API Route Error:', error)
 		return NextResponse.json(

+ 28 - 0
src/app/api/my-lp/getAddress/route.ts

@@ -0,0 +1,28 @@
+import { NextResponse } from 'next/server'
+import { Keypair } from '@solana/web3.js'
+import bs58 from 'bs58'
+
+export async function GET() {
+	try {
+		const secretKey = process.env.SOL_SECRET_KEY
+		if (!secretKey) {
+			return NextResponse.json(
+				{ error: 'SOL_SECRET_KEY not configured' },
+				{ status: 500 }
+			)
+		}
+		const userKeypair = Keypair.fromSecretKey(bs58.decode(secretKey))
+		const userAddress = userKeypair.publicKey
+
+		return NextResponse.json({
+			success: true,
+			address: userAddress.toBase58(),
+		})
+	} catch (error) {
+		console.error('API Route Error:', error)
+		return NextResponse.json(
+			{ retCode: 500, retMsg: '服务器内部错误' },
+			{ status: 500 }
+		)
+	}
+}

+ 74 - 26
src/app/my-lp/page.tsx

@@ -1,7 +1,17 @@
 'use client'
 
 import { useEffect, useState } from 'react'
-import { Button, Modal, Input, Table, Spin, Image, App, Typography } from 'antd'
+import {
+	Button,
+	Modal,
+	Input,
+	Table,
+	Spin,
+	Image,
+	App,
+	Typography,
+	Tag,
+} from 'antd'
 import type { ColumnsType } from 'antd/es/table'
 import dayjs from 'dayjs'
 
@@ -31,6 +41,10 @@ interface RecordInfo {
 	earnedUsdPercent: string
 	openTime: number
 	hasDetail?: boolean
+	priceOutType?: string
+	priceLower?: string
+	priceUpper?: string
+	isInRange?: boolean
 	bonusInfo?: {
 		fromCreatorPositionStatus: number
 		fromCreatorPosition: string
@@ -203,26 +217,16 @@ function MyLPPageContent() {
 				</div>
 			),
 		},
-		{
-			title: '当前价格',
-			dataIndex: 'price',
-			key: 'price',
-			render: (text: string, record: RecordInfo) => (
-				<span className="font-mono text-sm">
-					${Number(getPoolInfo(record.poolAddress).price[0]).toFixed(8)}
-				</span>
-			),
-		},
-		{
-			title: 'NFT Token Address',
-			dataIndex: 'nftMintAddress',
-			key: 'nftMintAddress',
-			render: (text: string) => (
-				<span className="font-mono text-sm">
-					{text.slice(0, 6)}...{text.slice(-4)}
-				</span>
-			),
-		},
+		// {
+		// 	title: 'NFT Token Address',
+		// 	dataIndex: 'nftMintAddress',
+		// 	key: 'nftMintAddress',
+		// 	render: (text: string) => (
+		// 		<span className="font-mono text-sm">
+		// 			{text.slice(0, 6)}...{text.slice(-4)}
+		// 		</span>
+		// 	),
+		// },
 		{
 			title: 'Total Deposit',
 			dataIndex: 'liquidityUsd',
@@ -268,12 +272,39 @@ function MyLPPageContent() {
 			),
 		},
 		{
-			title: 'Earned Percent',
-			dataIndex: 'earnedUsdPercent',
-			key: 'earnedUsdPercent',
-			render: (text: string) => (
+			title: '当前价格',
+			dataIndex: 'price',
+			key: 'price',
+			render: (text: string, record: RecordInfo) => (
 				<span className="font-mono text-sm">
-					{(Number(text) * 100).toFixed(2)}%
+					${Number(getPoolInfo(record.poolAddress).price[0]).toFixed(6)}
+				</span>
+			),
+		},
+		{
+			title: '区间',
+			dataIndex: 'priceRange',
+			key: 'priceRange',
+			render: (text: string, record: RecordInfo) => (
+				<span className="font-mono text-sm text-red-500">
+					{Number(record.priceLower).toFixed(4)} -{' '}
+					{Number(record.priceUpper).toFixed(4)}
+				</span>
+			),
+		},
+		{
+			title: '区间状态',
+			dataIndex: 'isInRange',
+			key: 'isInRange',
+			render: (text: string, record: RecordInfo) => (
+				<span className="font-mono text-sm">
+					{text ? (
+						<Tag color="green">区间内</Tag>
+					) : (
+						<Tag color="red">
+							{record.priceOutType === 'priceUp' ? '超出上限' : '低于下限'}
+						</Tag>
+					)}
 				</span>
 			),
 		},
@@ -298,6 +329,7 @@ function MyLPPageContent() {
 		{
 			title: '仓位来源',
 			dataIndex: 'bonusInfo',
+			width: 180,
 			key: 'bonusInfo',
 			render: (text: string, record: RecordInfo) => (
 				<span className="font-mono text-sm">
@@ -321,6 +353,7 @@ function MyLPPageContent() {
 		{
 			title: '操作',
 			dataIndex: 'bonusInfo',
+			width: 200,
 			key: 'bonusInfo',
 			render: (text: string, record: RecordInfo) => (
 				<div className="flex items-center gap-2">
@@ -338,11 +371,26 @@ function MyLPPageContent() {
 		},
 	]
 
+	function fetchAddress() {
+		fetch('/api/my-lp/getAddress')
+			.then((res) => res.json())
+			.then((data) => {
+				setUserAddress(data.address)
+				fetchLPList(data.address)
+			})
+			.catch((err) => {
+				console.error('Error fetching address:', err)
+				message.error('获取地址失败')
+			})
+	}
+
 	useEffect(() => {
 		const userAddress = localStorage.getItem('userAddress')
 		if (userAddress) {
 			setUserAddress(userAddress)
 			fetchLPList(userAddress)
+		} else {
+			fetchAddress()
 		}
 		// eslint-disable-next-line react-hooks/exhaustive-deps
 	}, [])