feat: CLOB V1 → V2 完整迁移
- 更新 EIP-712 签名结构: domain version "1"→"2", 移除 taker/expiration/nonce/feeRateBps, 新增 timestamp/metadata/builder - 更新合约地址为 V2 (CTF_EXCHANGE, NEG_RISK_EXCHANGE) - CLOB URL 切换到 clob-v2.polymarket.com - 抵押品代币 USDC.e → pUSD (0xC011a7E12a19f7B1f670d46F03B03f3342E82DFB) - 新增 USDC.e → pUSD wrap 功能 (CollateralOnramp 合约) - SignedOrderObject 补充 API payload 必需的 taker/expiration 字段 - NewOrderRequest 补充 deferExec/postOnly 字段 - 前端账户管理新增 pUSD 迁移按钮 - 移除所有 feeRateBps 相关逻辑 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Card, Table, Button, Space, Tag, Popconfirm, message, Typography, Spin, Modal, Descriptions, Divider, Form, Input, Alert, Tooltip, List, Empty } from 'antd'
|
||||
import { PlusOutlined, ReloadOutlined, EditOutlined, CopyOutlined, EyeOutlined, DeleteOutlined, WalletOutlined } from '@ant-design/icons'
|
||||
import { PlusOutlined, ReloadOutlined, EditOutlined, CopyOutlined, EyeOutlined, DeleteOutlined, WalletOutlined, SwapOutlined } from '@ant-design/icons'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useAccountStore } from '../store/accountStore'
|
||||
import type { Account } from '../types'
|
||||
@@ -8,6 +8,7 @@ import { useMediaQuery } from 'react-responsive'
|
||||
import { formatUSDC } from '../utils'
|
||||
import AccountImportForm from '../components/AccountImportForm'
|
||||
import AccountSetupStatusBlock from '../components/AccountSetupStatusBlock'
|
||||
import apiService from '../services/api'
|
||||
|
||||
const { Title } = Typography
|
||||
|
||||
@@ -27,6 +28,43 @@ const AccountList: React.FC = () => {
|
||||
const [editLoading, setEditLoading] = useState(false)
|
||||
const [accountImportModalVisible, setAccountImportModalVisible] = useState(false)
|
||||
const [accountImportForm] = Form.useForm()
|
||||
const [wrapLoading, setWrapLoading] = useState<Record<number, boolean>>({})
|
||||
|
||||
const handleWrapToPusd = async (account: Account) => {
|
||||
try {
|
||||
setWrapLoading(prev => ({ ...prev, [account.id]: true }))
|
||||
const res = await apiService.accounts.getUsdceBalance(account.id)
|
||||
if (res.data.code !== 0 || !res.data.data) {
|
||||
message.error(res.data.msg || '查询 USDC.e 余额失败')
|
||||
return
|
||||
}
|
||||
const balance = parseFloat(res.data.data.balance)
|
||||
if (balance <= 0) {
|
||||
message.info('USDC.e 余额为 0,无需迁移')
|
||||
return
|
||||
}
|
||||
Modal.confirm({
|
||||
title: 'USDC.e → pUSD 迁移',
|
||||
content: `检测到 ${balance.toFixed(2)} USDC.e,将全部 wrap 为 pUSD。确认继续?`,
|
||||
okText: '确认迁移',
|
||||
cancelText: '取消',
|
||||
onOk: async () => {
|
||||
const wrapRes = await apiService.accounts.wrapToPusd(account.id)
|
||||
if (wrapRes.data.code === 0) {
|
||||
const txHash = wrapRes.data.data?.transactionHash
|
||||
message.success(txHash ? `迁移成功,交易: ${txHash.slice(0, 10)}...` : '迁移成功(无需操作)')
|
||||
fetchAccountBalance(account.id)
|
||||
} else {
|
||||
message.error(wrapRes.data.msg || '迁移失败')
|
||||
}
|
||||
}
|
||||
})
|
||||
} catch (e: any) {
|
||||
message.error(e.message || '迁移失败')
|
||||
} finally {
|
||||
setWrapLoading(prev => ({ ...prev, [account.id]: false }))
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetchAccounts()
|
||||
@@ -374,6 +412,26 @@ const AccountList: React.FC = () => {
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip title="USDC.e → pUSD">
|
||||
<div
|
||||
onClick={() => handleWrapToPusd(record)}
|
||||
style={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
width: '32px',
|
||||
height: '32px',
|
||||
cursor: wrapLoading[record.id] ? 'wait' : 'pointer',
|
||||
borderRadius: '6px',
|
||||
transition: 'background-color 0.2s'
|
||||
}}
|
||||
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = '#fff7e6'}
|
||||
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = 'transparent'}
|
||||
>
|
||||
<SwapOutlined style={{ fontSize: '16px', color: '#fa8c16' }} spin={wrapLoading[record.id]} />
|
||||
</div>
|
||||
</Tooltip>
|
||||
|
||||
<Popconfirm
|
||||
title={t('accountList.deleteConfirm')}
|
||||
description={
|
||||
|
||||
@@ -284,9 +284,21 @@ export const apiService = {
|
||||
/**
|
||||
* 赎回仓位
|
||||
*/
|
||||
redeemPositions: (data: any) =>
|
||||
redeemPositions: (data: any) =>
|
||||
apiClient.post<ApiResponse<any>>('/accounts/positions/redeem', data),
|
||||
|
||||
|
||||
/**
|
||||
* 将 USDC.e wrap 为 pUSD(V2 迁移)
|
||||
*/
|
||||
wrapToPusd: (accountId: number) =>
|
||||
apiClient.post<ApiResponse<{ transactionHash: string | null }>>('/accounts/wrap-to-pusd', { accountId }),
|
||||
|
||||
/**
|
||||
* 查询 USDC.e 余额(V2 迁移用)
|
||||
*/
|
||||
getUsdceBalance: (accountId: number) =>
|
||||
apiClient.post<ApiResponse<{ balance: string }>>('/accounts/usdce-balance', { accountId }),
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user