fix(mining-admin): 池账户钱包配置移到后端 .env,前端从 API 读取

做市商的 kavaWalletAddress 是后端 API 返回的,池账户应该一样。

- 后端 mining-blockchain-service/.env.example: 新增
  BURN_POOL_WALLET_USERNAME/ADDRESS 和
  MINING_POOL_WALLET_USERNAME/ADDRESS(同做市商钱包配置模式)
- 前端 .env.production: 移除 NEXT_PUBLIC_BURN/MINING_POOL 变量
- 前端 configs/page.tsx: 钱包地址改从 API 响应
  (poolAccountBalance.walletAddress) 读取,未配置时显示提示

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
hailin 2026-02-03 00:14:38 -08:00
parent 6dbb620e82
commit 4d2bcc7568
3 changed files with 75 additions and 54 deletions

View File

@ -96,6 +96,22 @@ FUSDT_MARKET_MAKER_USERNAME=
# 钱包地址EVM 地址)
FUSDT_MARKET_MAKER_ADDRESS=
# =============================================================================
# 100亿销毁池 MPC 钱包 (2-of-3 门限)
# =============================================================================
# MPC 用户名(用于签名转账交易)
BURN_POOL_WALLET_USERNAME=wallet-22fd661f
# 钱包地址EVM 地址)
BURN_POOL_WALLET_ADDRESS=0xdE2932D2A25e1698c1354A41e2e46B414C46F5a1
# =============================================================================
# 200万挖矿池 MPC 钱包 (2-of-3 门限)
# =============================================================================
# MPC 用户名(用于签名转账交易)
MINING_POOL_WALLET_USERNAME=wallet-974e78f5
# 钱包地址EVM 地址)
MINING_POOL_WALLET_ADDRESS=0x8BC9091375ae8ef43ae011F0f9bAf10e51bC9D59
# =============================================================================
# 区块扫描配置
# =============================================================================

View File

@ -1,11 +1,3 @@
NEXT_PUBLIC_API_URL=https://mapi.szaiai.com/api/v2/mining-admin
TRADING_SERVICE_URL=https://mapi.szaiai.com/api/v2/trading
NEXT_PUBLIC_APP_NAME=挖矿管理后台
# 100亿销毁池钱包配置
NEXT_PUBLIC_BURN_POOL_WALLET_NAME=wallet-22fd661f
NEXT_PUBLIC_BURN_POOL_WALLET_ADDRESS=0xdE2932D2A25e1698c1354A41e2e46B414C46F5a1
# 200万挖矿池钱包配置
NEXT_PUBLIC_MINING_POOL_WALLET_NAME=wallet-974e78f5
NEXT_PUBLIC_MINING_POOL_WALLET_ADDRESS=0x8BC9091375ae8ef43ae011F0f9bAf10e51bC9D59

View File

@ -24,10 +24,9 @@ import { Badge } from '@/components/ui/badge';
import { Pencil, Save, X, Play, Pause, AlertCircle, CheckCircle2, Loader2, Wallet, PlusCircle, MinusCircle, Copy, Check, Flame, HardHat } from 'lucide-react';
import type { SystemConfig } from '@/types/config';
const BURN_POOL_WALLET_NAME = process.env.NEXT_PUBLIC_BURN_POOL_WALLET_NAME || 'wallet-22fd661f';
const BURN_POOL_WALLET_ADDRESS = process.env.NEXT_PUBLIC_BURN_POOL_WALLET_ADDRESS || '0xdE2932D2A25e1698c1354A41e2e46B414C46F5a1';
const MINING_POOL_WALLET_NAME = process.env.NEXT_PUBLIC_MINING_POOL_WALLET_NAME || 'wallet-974e78f5';
const MINING_POOL_WALLET_ADDRESS = process.env.NEXT_PUBLIC_MINING_POOL_WALLET_ADDRESS || '0x8BC9091375ae8ef43ae011F0f9bAf10e51bC9D59';
// 池账户钱包名(与后端 .env 中的 BURN_POOL_WALLET_USERNAME / MINING_POOL_WALLET_USERNAME 对应)
const BURN_POOL_WALLET_NAME = 'wallet-22fd661f';
const MINING_POOL_WALLET_NAME = 'wallet-974e78f5';
const categoryLabels: Record<string, string> = {
mining: '挖矿配置',
@ -285,30 +284,37 @@ export default function ConfigsPage() {
<DialogTitle> 100亿</DialogTitle>
<DialogDescription> fUSDT</DialogDescription>
</DialogHeader>
<div className="flex flex-col items-center space-y-4">
<div className="p-4 bg-white rounded-lg">
<QRCodeSVG value={BURN_POOL_WALLET_ADDRESS} size={180} />
</div>
<div className="w-full">
<Label className="text-xs text-muted-foreground"> (Kava EVM)</Label>
<div className="flex items-center gap-2 mt-1">
<code className="flex-1 text-xs bg-muted p-2 rounded break-all">
{BURN_POOL_WALLET_ADDRESS}
</code>
<Button
size="sm"
variant="outline"
onClick={() => handleCopyAddress(BURN_POOL_WALLET_ADDRESS)}
>
{copiedAddress === BURN_POOL_WALLET_ADDRESS ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
{burnPoolBalance?.walletAddress ? (
<div className="flex flex-col items-center space-y-4">
<div className="p-4 bg-white rounded-lg">
<QRCodeSVG value={burnPoolBalance.walletAddress} size={180} />
</div>
<div className="w-full">
<Label className="text-xs text-muted-foreground"> (Kava EVM)</Label>
<div className="flex items-center gap-2 mt-1">
<code className="flex-1 text-xs bg-muted p-2 rounded break-all">
{burnPoolBalance.walletAddress}
</code>
<Button
size="sm"
variant="outline"
onClick={() => handleCopyAddress(burnPoolBalance.walletAddress)}
>
{copiedAddress === burnPoolBalance.walletAddress ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
</div>
</div>
<div className="text-xs text-yellow-600 bg-yellow-50 p-2 rounded w-full">
<AlertCircle className="h-3 w-3 inline mr-1" />
12
</div>
</div>
<div className="text-xs text-yellow-600 bg-yellow-50 p-2 rounded w-full">
<AlertCircle className="h-3 w-3 inline mr-1" />
12
) : (
<div className="text-center text-muted-foreground py-4">
<AlertCircle className="h-6 w-6 mx-auto mb-2 text-yellow-500" />
<p className="text-sm"> .env BURN_POOL_WALLET_ADDRESS</p>
</div>
</div>
)}
</DialogContent>
</Dialog>
@ -426,30 +432,37 @@ export default function ConfigsPage() {
<DialogTitle> 200</DialogTitle>
<DialogDescription> fUSDT</DialogDescription>
</DialogHeader>
<div className="flex flex-col items-center space-y-4">
<div className="p-4 bg-white rounded-lg">
<QRCodeSVG value={MINING_POOL_WALLET_ADDRESS} size={180} />
</div>
<div className="w-full">
<Label className="text-xs text-muted-foreground"> (Kava EVM)</Label>
<div className="flex items-center gap-2 mt-1">
<code className="flex-1 text-xs bg-muted p-2 rounded break-all">
{MINING_POOL_WALLET_ADDRESS}
</code>
<Button
size="sm"
variant="outline"
onClick={() => handleCopyAddress(MINING_POOL_WALLET_ADDRESS)}
>
{copiedAddress === MINING_POOL_WALLET_ADDRESS ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
{miningPoolBalance?.walletAddress ? (
<div className="flex flex-col items-center space-y-4">
<div className="p-4 bg-white rounded-lg">
<QRCodeSVG value={miningPoolBalance.walletAddress} size={180} />
</div>
<div className="w-full">
<Label className="text-xs text-muted-foreground"> (Kava EVM)</Label>
<div className="flex items-center gap-2 mt-1">
<code className="flex-1 text-xs bg-muted p-2 rounded break-all">
{miningPoolBalance.walletAddress}
</code>
<Button
size="sm"
variant="outline"
onClick={() => handleCopyAddress(miningPoolBalance.walletAddress)}
>
{copiedAddress === miningPoolBalance.walletAddress ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}
</Button>
</div>
</div>
<div className="text-xs text-yellow-600 bg-yellow-50 p-2 rounded w-full">
<AlertCircle className="h-3 w-3 inline mr-1" />
12
</div>
</div>
<div className="text-xs text-yellow-600 bg-yellow-50 p-2 rounded w-full">
<AlertCircle className="h-3 w-3 inline mr-1" />
12
) : (
<div className="text-center text-muted-foreground py-4">
<AlertCircle className="h-6 w-6 mx-auto mb-2 text-yellow-500" />
<p className="text-sm"> .env MINING_POOL_WALLET_ADDRESS</p>
</div>
</div>
)}
</DialogContent>
</Dialog>