lushdog@outlook.com hace 1 mes
padre
commit
582478451b
Se han modificado 3 ficheros con 183 adiciones y 88 borrados
  1. 19 55
      src/app/api/my-lp/route.ts
  2. 72 0
      src/app/api/my-lp/route2.ts
  3. 92 33
      src/app/my-lp/page.tsx

+ 19 - 55
src/app/api/my-lp/route.ts

@@ -1,71 +1,35 @@
 import { NextRequest, NextResponse } from 'next/server'
-import { Connection, PublicKey } from '@solana/web3.js'
-import { getSolanaRpcUrl } from '@/lib/solana-config'
-import { chain } from '@/lib/config'
-interface LPInfo {
-	nftMint: string
-	PriceRange: string
-	Token: string
-	TokenA: number
-	TokenB: number
-}
 
 export async function GET(request: NextRequest) {
 	try {
 		const searchParams = request.nextUrl.searchParams
-		const address = searchParams.get('address')
+		const page = searchParams.get('page') || '1'
+		const pageSize = searchParams.get('pageSize') || '500'
+		const address = searchParams.get('userAddress')
 
-		if (!address) {
-			return NextResponse.json(
-				{ code: 400, message: '缺少地址参数' },
-				{ status: 400 }
-			)
-		}
+		const response = await fetch(
+			`https://api2.byreal.io/byreal/api/dex/v2/position/list?userAddress=${address}&page=${page}&pageSize=${pageSize}&status=0`,
+			{
+				method: 'GET',
+				headers: {
+					accept: 'application/json',
+				},
+			}
+		)
 
-		// 验证地址格式
-		let publicKey: PublicKey
-		try {
-			publicKey = new PublicKey(address)
-		} catch (error) {
+		if (!response.ok) {
 			return NextResponse.json(
-				{ code: 400, message: '无效的 Solana 地址格式' },
-				{ status: 400 }
+				{ retCode: response.status, retMsg: '外部 API 请求失败' },
+				{ status: response.status }
 			)
 		}
 
-		const lpList = await chain.getRawPositionInfoListByUserAddress(publicKey)
-		const list = lpList.slice(0, 10)
-		console.log(list, 'list')
-		const lpListData = []
-		for (const item of list) {
-			const positionInfo = await chain.getPositionInfoByNftMint(item.nftMint)
-			if (!positionInfo) continue
-			const { uiPriceLower, uiPriceUpper, tokenA, tokenB } = positionInfo
-			console.log(positionInfo, 'positionInfo')
-			lpListData.push({
-				nftMint: item.nftMint.toBase58(),
-				PriceRange: `${uiPriceLower} - ${uiPriceUpper}`,
-				Token: `${tokenA.address.toBase58().slice(0, 4)}/${tokenB.address.toBase58().slice(0, 4)}`,
-				TokenA: tokenA.uiAmount,
-				TokenB: tokenB.uiAmount,
-			})
-		}
-		return NextResponse.json({
-			code: 200,
-			message: '查询成功',
-			data: {
-				address: address,
-				lpList: lpListData,
-				total: lpListData.length,
-			},
-		})
+		const data = await response.json()
+		return NextResponse.json(data)
 	} catch (error) {
-		console.error('查询 LP 失败:', error)
+		console.error('API Route Error:', error)
 		return NextResponse.json(
-			{
-				code: 500,
-				message: error instanceof Error ? error.message : '服务器内部错误',
-			},
+			{ retCode: 500, retMsg: '服务器内部错误' },
 			{ status: 500 }
 		)
 	}

+ 72 - 0
src/app/api/my-lp/route2.ts

@@ -0,0 +1,72 @@
+import { NextRequest, NextResponse } from 'next/server'
+import { Connection, PublicKey } from '@solana/web3.js'
+import { getSolanaRpcUrl } from '@/lib/solana-config'
+import { chain } from '@/lib/config'
+interface LPInfo {
+	nftMint: string
+	PriceRange: string
+	Token: string
+	TokenA: number
+	TokenB: number
+}
+
+export async function GET(request: NextRequest) {
+	try {
+		const searchParams = request.nextUrl.searchParams
+		const address = searchParams.get('address')
+
+		if (!address) {
+			return NextResponse.json(
+				{ code: 400, message: '缺少地址参数' },
+				{ status: 400 }
+			)
+		}
+
+		// 验证地址格式
+		let publicKey: PublicKey
+		try {
+			publicKey = new PublicKey(address)
+		} catch (error) {
+			return NextResponse.json(
+				{ code: 400, message: '无效的 Solana 地址格式' },
+				{ status: 400 }
+			)
+		}
+
+		const lpList = await chain.getRawPositionInfoListByUserAddress(publicKey)
+		const list = lpList.slice(0, 10)
+		console.log(list, 'list')
+		const lpListData = []
+		for (const item of list) {
+			const positionInfo = await chain.getPositionInfoByNftMint(item.nftMint)
+			if (!positionInfo) continue
+			const { uiPriceLower, uiPriceUpper, tokenA, tokenB } = positionInfo
+			console.log(positionInfo, 'positionInfo')
+			lpListData.push({
+				nftMint: item.nftMint.toBase58(),
+				PriceRange: `${uiPriceLower} - ${uiPriceUpper}`,
+				Token: `${tokenA.address.toBase58().slice(0, 4)}/${tokenB.address.toBase58().slice(0, 4)}`,
+				TokenA: tokenA.uiAmount,
+				TokenB: tokenB.uiAmount,
+			})
+		}
+		return NextResponse.json({
+			code: 200,
+			message: '查询成功',
+			data: {
+				address: address,
+				lpList: lpListData,
+				total: lpListData.length,
+			},
+		})
+	} catch (error) {
+		console.error('查询 LP 失败:', error)
+		return NextResponse.json(
+			{
+				code: 500,
+				message: error instanceof Error ? error.message : '服务器内部错误',
+			},
+			{ status: 500 }
+		)
+	}
+}

+ 92 - 33
src/app/my-lp/page.tsx

@@ -1,32 +1,40 @@
 'use client'
 
 import { useEffect, useState } from 'react'
-import { Button, Modal, Input, Table, message, Spin } from 'antd'
+import { Button, Modal, Input, Table, message, Spin, Image } from 'antd'
 import type { ColumnsType } from 'antd/es/table'
 
-interface LPInfo {
-	mint: string
-	amount: string
-	uiAmount: number
+interface MintInfo {
+	symbol: string
 	decimals: number
+	logoURI: string
+	price: string
+	address: string
+}
+interface LPInfo {
+	mintA: MintInfo
+	mintB: MintInfo
 }
 
-interface LPResponse {
-	code: number
-	message: string
-	data?: {
-		address: string
-		lpList: LPInfo[]
-		total: number
-	}
+interface RecordInfo {
+	poolAddress: string
+	nftMintAddress: string
+	PriceRange: string
+	Token: string
+	TokenA: number
+	TokenB: number
 }
 
 export default function MyLPPage() {
 	const [userAddress, setUserAddress] = useState<string>('')
 	const [isModalOpen, setIsModalOpen] = useState(false)
 	const [inputValue, setInputValue] = useState<string>('')
-	const [lpList, setLpList] = useState<LPInfo[]>([])
+	const [lpList, setLpList] = useState<RecordInfo[]>([])
 	const [loading, setLoading] = useState(false)
+	const [total, setTotal] = useState(0)
+	const [page, setPage] = useState(1)
+	const [pageSize, setPageSize] = useState(10)
+	const [poolMap, setPoolMap] = useState<Record<string, LPInfo>>({})
 
 	useEffect(() => {
 		const userAddress = localStorage.getItem('userAddress')
@@ -35,27 +43,24 @@ export default function MyLPPage() {
 		}
 	}, [])
 
-	useEffect(() => {
-		if (userAddress) {
-			fetchLPList()
-		}
-	}, [userAddress])
-
 	const fetchLPList = async () => {
 		if (!userAddress) return
 
 		setLoading(true)
 		try {
 			const response = await fetch(
-				`/api/my-lp?address=${encodeURIComponent(userAddress)}`
+				`/api/my-lp?userAddress=${encodeURIComponent(userAddress)}&page=${page}&pageSize=${pageSize}`
 			)
-			const data: LPResponse = await response.json()
-
-			if (data.code === 200 && data.data) {
-				setLpList(data.data.lpList)
-				message.success(`查询成功,找到 ${data.data.total} 个 LP token`)
+			const data = await response.json()
+			console.log(data, 'data')
+			const { positions, total, poolMap } = data.result?.data
+			if (data.retCode === 0 && data.result) {
+				setLpList(positions as RecordInfo[])
+				setTotal(total)
+				setPoolMap(poolMap)
+				message.success(`查询成功,找到 ${data.result.data.total} 个 LP token`)
 			} else {
-				message.error(data.message || '查询失败')
+				message.error(data.retMsg || '查询失败')
 				setLpList([])
 			}
 		} catch (error) {
@@ -88,13 +93,61 @@ export default function MyLPPage() {
 		setInputValue('')
 	}
 
-	const columns: ColumnsType<LPInfo> = [
+	function getPoolInfo(poolAddress: string) {
+		const poolInfo = poolMap[poolAddress]
+		if (!poolInfo) {
+			return {
+				lpToken: '',
+				logoURI: [],
+				price: [],
+			}
+		}
+		const tokenA = poolInfo.mintA.symbol
+		const tokenB = poolInfo.mintB.symbol
+		return {
+			lpToken: `${tokenA}/${tokenB}`,
+			logoURI: [poolInfo.mintA.logoURI, poolInfo.mintB.logoURI],
+			price: [poolInfo.mintA.price, poolInfo.mintB.price],
+		}
+	}
+
+	const columns: ColumnsType<RecordInfo> = [
+		{
+			title: 'LP Token',
+			dataIndex: 'lpToken',
+			key: 'lpToken',
+			render: (text: string, record: RecordInfo) => (
+				<div className="flex items-center gap-2">
+					<span className="inline-flex items-center">
+						<Image
+							src={getPoolInfo(record.poolAddress).logoURI[0]}
+							alt="logo"
+							width={20}
+							height={20}
+							style={{ borderRadius: '50%', marginLeft: 8 }}
+						/>
+						<Image
+							src={getPoolInfo(record.poolAddress).logoURI[1]}
+							alt="logo"
+							width={20}
+							height={20}
+							style={{ borderRadius: '50%' }}
+						/>
+					</span>
+					<span className="font-mono text-sm">
+						{getPoolInfo(record.poolAddress).lpToken}
+					</span>
+				</div>
+			),
+		},
 		{
 			title: 'NFT Token Address',
-			dataIndex: 'nftMint',
-			key: 'nftMint',
+			dataIndex: 'nftMintAddress',
+			key: 'nftMintAddress',
 			render: (text: string) => (
-				<span className="font-mono text-sm">{text}</span>
+				<span className="font-mono text-sm">
+					{text.slice(0, 6)}...{text.slice(-4)}
+				</span>
 			),
 		},
 		{
@@ -144,11 +197,17 @@ export default function MyLPPage() {
 					<Table
 						columns={columns}
 						dataSource={lpList}
-						rowKey="nftMint"
+						rowKey="nftMintAddress"
 						pagination={{
-							pageSize: 10,
+							pageSize: pageSize,
 							showSizeChanger: true,
 							showTotal: (total) => `共 ${total} 条记录`,
+							total: total,
+						}}
+						onChange={(pagination) => {
+							setPage(pagination.current || 1)
+							setPageSize(pagination.pageSize || 10)
+							fetchLPList()
 						}}
 					/>
 				</Spin>