mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-14 00:07:01 +08:00
fix(web): remove undefined setHyperliquidWalletAddr call in ExchangeConfigModal (#525)
This commit is contained in:
@@ -660,50 +660,52 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 信号源配置警告 */}
|
{/* 信号源配置警告 */}
|
||||||
{traders && traders.some(t => (t.use_coin_pool || t.use_oi_top)) &&
|
{traders &&
|
||||||
(!userSignalSource.coinPoolUrl && !userSignalSource.oiTopUrl) && (
|
traders.some((t) => t.use_coin_pool || t.use_oi_top) &&
|
||||||
<div
|
!userSignalSource.coinPoolUrl &&
|
||||||
className="rounded-lg px-4 py-3 flex items-start gap-3 animate-slide-in"
|
!userSignalSource.oiTopUrl && (
|
||||||
style={{
|
<div
|
||||||
background: 'rgba(246, 70, 93, 0.1)',
|
className="rounded-lg px-4 py-3 flex items-start gap-3 animate-slide-in"
|
||||||
border: '1px solid rgba(246, 70, 93, 0.3)',
|
style={{
|
||||||
}}
|
background: 'rgba(246, 70, 93, 0.1)',
|
||||||
>
|
border: '1px solid rgba(246, 70, 93, 0.3)',
|
||||||
<AlertTriangle
|
}}
|
||||||
size={20}
|
>
|
||||||
className="flex-shrink-0 mt-0.5"
|
<AlertTriangle
|
||||||
style={{ color: '#F6465D' }}
|
size={20}
|
||||||
/>
|
className="flex-shrink-0 mt-0.5"
|
||||||
<div className="flex-1">
|
style={{ color: '#F6465D' }}
|
||||||
<div className="font-semibold mb-1" style={{ color: '#F6465D' }}>
|
/>
|
||||||
⚠️ {t('signalSourceNotConfigured', language)}
|
<div className="flex-1">
|
||||||
|
<div className="font-semibold mb-1" style={{ color: '#F6465D' }}>
|
||||||
|
⚠️ {t('signalSourceNotConfigured', language)}
|
||||||
|
</div>
|
||||||
|
<div className="text-sm" style={{ color: '#848E9C' }}>
|
||||||
|
<p className="mb-2">
|
||||||
|
{t('signalSourceWarningMessage', language)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<strong>{t('solutions', language)}</strong>
|
||||||
|
</p>
|
||||||
|
<ul className="list-disc list-inside space-y-1 ml-2 mt-1">
|
||||||
|
<li>点击"📡 {t('signalSource', language)}"按钮配置API地址</li>
|
||||||
|
<li>或在交易员配置中禁用"使用币种池"和"使用OI Top"</li>
|
||||||
|
<li>或在交易员配置中设置自定义币种列表</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => setShowSignalSourceModal(true)}
|
||||||
|
className="mt-3 px-3 py-1.5 rounded text-sm font-semibold transition-all hover:scale-105"
|
||||||
|
style={{
|
||||||
|
background: '#F0B90B',
|
||||||
|
color: '#000',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{t('configureSignalSourceNow', language)}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm" style={{ color: '#848E9C' }}>
|
|
||||||
<p className="mb-2">
|
|
||||||
{t('signalSourceWarningMessage', language)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>{t('solutions', language)}</strong>
|
|
||||||
</p>
|
|
||||||
<ul className="list-disc list-inside space-y-1 ml-2 mt-1">
|
|
||||||
<li>点击"📡 {t('signalSource', language)}"按钮配置API地址</li>
|
|
||||||
<li>或在交易员配置中禁用"使用币种池"和"使用OI Top"</li>
|
|
||||||
<li>或在交易员配置中设置自定义币种列表</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
onClick={() => setShowSignalSourceModal(true)}
|
|
||||||
className="mt-3 px-3 py-1.5 rounded text-sm font-semibold transition-all hover:scale-105"
|
|
||||||
style={{
|
|
||||||
background: '#F0B90B',
|
|
||||||
color: '#000',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{t('configureSignalSourceNow', language)}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Configuration Status */}
|
{/* Configuration Status */}
|
||||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 md:gap-6">
|
<div className="grid grid-cols-1 lg:grid-cols-2 gap-4 md:gap-6">
|
||||||
@@ -1576,22 +1578,23 @@ function ExchangeConfigModal({
|
|||||||
onClose: () => void
|
onClose: () => void
|
||||||
language: Language
|
language: Language
|
||||||
}) {
|
}) {
|
||||||
const [selectedExchangeId, setSelectedExchangeId] = useState(editingExchangeId || '');
|
const [selectedExchangeId, setSelectedExchangeId] = useState(
|
||||||
const [apiKey, setApiKey] = useState('');
|
editingExchangeId || ''
|
||||||
const [secretKey, setSecretKey] = useState('');
|
)
|
||||||
const [passphrase, setPassphrase] = useState('');
|
const [apiKey, setApiKey] = useState('')
|
||||||
const [testnet, setTestnet] = useState(false);
|
const [secretKey, setSecretKey] = useState('')
|
||||||
const [showGuide, setShowGuide] = useState(false);
|
const [passphrase, setPassphrase] = useState('')
|
||||||
|
const [testnet, setTestnet] = useState(false)
|
||||||
|
const [showGuide, setShowGuide] = useState(false)
|
||||||
const [serverIP, setServerIP] = useState<{
|
const [serverIP, setServerIP] = useState<{
|
||||||
public_ip: string;
|
public_ip: string
|
||||||
message: string;
|
message: string
|
||||||
} | null>(null);
|
} | null>(null)
|
||||||
const [loadingIP, setLoadingIP] = useState(false);
|
const [loadingIP, setLoadingIP] = useState(false)
|
||||||
const [copiedIP, setCopiedIP] = useState(false);
|
const [copiedIP, setCopiedIP] = useState(false)
|
||||||
|
|
||||||
// 币安配置指南展开状态
|
// 币安配置指南展开状态
|
||||||
const [showBinanceGuide, setShowBinanceGuide] = useState(false);
|
const [showBinanceGuide, setShowBinanceGuide] = useState(false)
|
||||||
|
|
||||||
|
|
||||||
// Aster 特定字段
|
// Aster 特定字段
|
||||||
const [asterUser, setAsterUser] = useState('')
|
const [asterUser, setAsterUser] = useState('')
|
||||||
@@ -1611,9 +1614,6 @@ function ExchangeConfigModal({
|
|||||||
setPassphrase('') // Don't load existing passphrase for security
|
setPassphrase('') // Don't load existing passphrase for security
|
||||||
setTestnet(selectedExchange.testnet || false)
|
setTestnet(selectedExchange.testnet || false)
|
||||||
|
|
||||||
// Hyperliquid 字段
|
|
||||||
setHyperliquidWalletAddr(selectedExchange.hyperliquidWalletAddr || '')
|
|
||||||
|
|
||||||
// Aster 字段
|
// Aster 字段
|
||||||
setAsterUser(selectedExchange.asterUser || '')
|
setAsterUser(selectedExchange.asterUser || '')
|
||||||
setAsterSigner(selectedExchange.asterSigner || '')
|
setAsterSigner(selectedExchange.asterSigner || '')
|
||||||
@@ -1624,26 +1624,27 @@ function ExchangeConfigModal({
|
|||||||
// 加载服务器IP(当选择binance时)
|
// 加载服务器IP(当选择binance时)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (selectedExchangeId === 'binance' && !serverIP) {
|
if (selectedExchangeId === 'binance' && !serverIP) {
|
||||||
setLoadingIP(true);
|
setLoadingIP(true)
|
||||||
api.getServerIP()
|
api
|
||||||
.then(data => {
|
.getServerIP()
|
||||||
setServerIP(data);
|
.then((data) => {
|
||||||
|
setServerIP(data)
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch((err) => {
|
||||||
console.error('Failed to load server IP:', err);
|
console.error('Failed to load server IP:', err)
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setLoadingIP(false);
|
setLoadingIP(false)
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}, [selectedExchangeId]);
|
}, [selectedExchangeId])
|
||||||
|
|
||||||
const handleCopyIP = (ip: string) => {
|
const handleCopyIP = (ip: string) => {
|
||||||
navigator.clipboard.writeText(ip).then(() => {
|
navigator.clipboard.writeText(ip).then(() => {
|
||||||
setCopiedIP(true);
|
setCopiedIP(true)
|
||||||
setTimeout(() => setCopiedIP(false), 2000);
|
setTimeout(() => setCopiedIP(false), 2000)
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
@@ -1789,104 +1790,151 @@ function ExchangeConfigModal({
|
|||||||
{selectedExchange && (
|
{selectedExchange && (
|
||||||
<>
|
<>
|
||||||
{/* Binance 和其他 CEX 交易所的字段 */}
|
{/* Binance 和其他 CEX 交易所的字段 */}
|
||||||
{(selectedExchange.id === 'binance' || selectedExchange.type === 'cex') && selectedExchange.id !== 'hyperliquid' && selectedExchange.id !== 'aster' && (
|
{(selectedExchange.id === 'binance' ||
|
||||||
<>
|
selectedExchange.type === 'cex') &&
|
||||||
{/* 币安用户配置提示 (D1 方案) */}
|
selectedExchange.id !== 'hyperliquid' &&
|
||||||
{selectedExchange.id === 'binance' && (
|
selectedExchange.id !== 'aster' && (
|
||||||
<div
|
<>
|
||||||
className="mb-4 p-3 rounded cursor-pointer transition-colors"
|
{/* 币安用户配置提示 (D1 方案) */}
|
||||||
style={{
|
{selectedExchange.id === 'binance' && (
|
||||||
background: '#1a3a52',
|
<div
|
||||||
border: '1px solid #2b5278',
|
className="mb-4 p-3 rounded cursor-pointer transition-colors"
|
||||||
}}
|
style={{
|
||||||
onClick={() => setShowBinanceGuide(!showBinanceGuide)}
|
background: '#1a3a52',
|
||||||
>
|
border: '1px solid #2b5278',
|
||||||
<div className="flex items-center justify-between">
|
}}
|
||||||
<div className="flex items-center gap-2">
|
onClick={() => setShowBinanceGuide(!showBinanceGuide)}
|
||||||
<span style={{ color: '#58a6ff' }}>ℹ️</span>
|
>
|
||||||
<span className="text-sm font-medium" style={{ color: '#EAECEF' }}>
|
<div className="flex items-center justify-between">
|
||||||
<strong>币安用户必读:</strong>
|
<div className="flex items-center gap-2">
|
||||||
使用「现货与合约交易」API,不要用「统一账户 API」
|
<span style={{ color: '#58a6ff' }}>ℹ️</span>
|
||||||
|
<span
|
||||||
|
className="text-sm font-medium"
|
||||||
|
style={{ color: '#EAECEF' }}
|
||||||
|
>
|
||||||
|
<strong>币安用户必读:</strong>
|
||||||
|
使用「现货与合约交易」API,不要用「统一账户 API」
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span style={{ color: '#8b949e' }}>
|
||||||
|
{showBinanceGuide ? '▲' : '▼'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span style={{ color: '#8b949e' }}>
|
|
||||||
{showBinanceGuide ? '▲' : '▼'}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* 展开的详细说明 */}
|
{/* 展开的详细说明 */}
|
||||||
{showBinanceGuide && (
|
{showBinanceGuide && (
|
||||||
<div
|
<div
|
||||||
className="mt-3 pt-3"
|
className="mt-3 pt-3"
|
||||||
style={{
|
style={{
|
||||||
borderTop: '1px solid #2b5278',
|
borderTop: '1px solid #2b5278',
|
||||||
fontSize: '0.875rem',
|
fontSize: '0.875rem',
|
||||||
color: '#c9d1d9'
|
color: '#c9d1d9',
|
||||||
}}
|
}}
|
||||||
onClick={(e) => e.stopPropagation()}
|
onClick={(e) => e.stopPropagation()}
|
||||||
>
|
|
||||||
<p className="mb-2" style={{ color: '#8b949e' }}>
|
|
||||||
<strong>原因:</strong>统一账户 API 权限结构不同,会导致订单提交失败
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p className="font-semibold mb-1" style={{ color: '#EAECEF' }}>
|
|
||||||
正确配置步骤:
|
|
||||||
</p>
|
|
||||||
<ol className="list-decimal list-inside space-y-1 mb-3" style={{ paddingLeft: '0.5rem' }}>
|
|
||||||
<li>登录币安 → 个人中心 → <strong>API 管理</strong></li>
|
|
||||||
<li>创建 API → 选择「<strong>系统生成的 API 密钥</strong>」</li>
|
|
||||||
<li>勾选「<strong>现货与合约交易</strong>」(<span style={{ color: '#f85149' }}>不选统一账户</span>)</li>
|
|
||||||
<li>IP 限制选「<strong>无限制</strong>」或添加服务器 IP</li>
|
|
||||||
</ol>
|
|
||||||
|
|
||||||
<p className="mb-2 p-2 rounded" style={{ background: '#3d2a00', border: '1px solid #9e6a03' }}>
|
|
||||||
💡 <strong>多资产模式用户注意:</strong>
|
|
||||||
如果您开启了多资产模式,将强制使用全仓模式。建议关闭多资产模式以支持逐仓交易。
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<a
|
|
||||||
href="https://www.binance.com/zh-CN/support/faq/how-to-create-api-keys-on-binance-360002502072"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
className="inline-block text-sm hover:underline"
|
|
||||||
style={{ color: '#58a6ff' }}
|
|
||||||
>
|
>
|
||||||
📖 查看币安官方教程 ↗
|
<p className="mb-2" style={{ color: '#8b949e' }}>
|
||||||
</a>
|
<strong>原因:</strong>统一账户 API
|
||||||
</div>
|
权限结构不同,会导致订单提交失败
|
||||||
)}
|
</p>
|
||||||
|
|
||||||
|
<p
|
||||||
|
className="font-semibold mb-1"
|
||||||
|
style={{ color: '#EAECEF' }}
|
||||||
|
>
|
||||||
|
正确配置步骤:
|
||||||
|
</p>
|
||||||
|
<ol
|
||||||
|
className="list-decimal list-inside space-y-1 mb-3"
|
||||||
|
style={{ paddingLeft: '0.5rem' }}
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
登录币安 → 个人中心 → <strong>API 管理</strong>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
创建 API → 选择「
|
||||||
|
<strong>系统生成的 API 密钥</strong>」
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
勾选「<strong>现货与合约交易</strong>」(
|
||||||
|
<span style={{ color: '#f85149' }}>
|
||||||
|
不选统一账户
|
||||||
|
</span>
|
||||||
|
)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
IP 限制选「<strong>无限制</strong>」或添加服务器
|
||||||
|
IP
|
||||||
|
</li>
|
||||||
|
</ol>
|
||||||
|
|
||||||
|
<p
|
||||||
|
className="mb-2 p-2 rounded"
|
||||||
|
style={{
|
||||||
|
background: '#3d2a00',
|
||||||
|
border: '1px solid #9e6a03',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
💡 <strong>多资产模式用户注意:</strong>
|
||||||
|
如果您开启了多资产模式,将强制使用全仓模式。建议关闭多资产模式以支持逐仓交易。
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href="https://www.binance.com/zh-CN/support/faq/how-to-create-api-keys-on-binance-360002502072"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="inline-block text-sm hover:underline"
|
||||||
|
style={{ color: '#58a6ff' }}
|
||||||
|
>
|
||||||
|
📖 查看币安官方教程 ↗
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label
|
||||||
|
className="block text-sm font-semibold mb-2"
|
||||||
|
style={{ color: '#EAECEF' }}
|
||||||
|
>
|
||||||
|
{t('apiKey', language)}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
value={apiKey}
|
||||||
|
onChange={(e) => setApiKey(e.target.value)}
|
||||||
|
placeholder={t('enterAPIKey', language)}
|
||||||
|
className="w-full px-3 py-2 rounded"
|
||||||
|
style={{
|
||||||
|
background: '#0B0E11',
|
||||||
|
border: '1px solid #2B3139',
|
||||||
|
color: '#EAECEF',
|
||||||
|
}}
|
||||||
|
required
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-semibold mb-2" style={{ color: '#EAECEF' }}>
|
<label
|
||||||
{t('apiKey', language)}
|
className="block text-sm font-semibold mb-2"
|
||||||
</label>
|
style={{ color: '#EAECEF' }}
|
||||||
<input
|
>
|
||||||
type="password"
|
{t('secretKey', language)}
|
||||||
value={apiKey}
|
</label>
|
||||||
onChange={(e) => setApiKey(e.target.value)}
|
<input
|
||||||
placeholder={t('enterAPIKey', language)}
|
type="password"
|
||||||
className="w-full px-3 py-2 rounded"
|
value={secretKey}
|
||||||
style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }}
|
onChange={(e) => setSecretKey(e.target.value)}
|
||||||
required
|
placeholder={t('enterSecretKey', language)}
|
||||||
/>
|
className="w-full px-3 py-2 rounded"
|
||||||
</div>
|
style={{
|
||||||
|
background: '#0B0E11',
|
||||||
<div>
|
border: '1px solid #2B3139',
|
||||||
<label className="block text-sm font-semibold mb-2" style={{ color: '#EAECEF' }}>
|
color: '#EAECEF',
|
||||||
{t('secretKey', language)}
|
}}
|
||||||
</label>
|
required
|
||||||
<input
|
/>
|
||||||
type="password"
|
</div>
|
||||||
value={secretKey}
|
|
||||||
onChange={(e) => setSecretKey(e.target.value)}
|
|
||||||
placeholder={t('enterSecretKey', language)}
|
|
||||||
className="w-full px-3 py-2 rounded"
|
|
||||||
style={{ background: '#0B0E11', border: '1px solid #2B3139', color: '#EAECEF' }}
|
|
||||||
required
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label
|
<label
|
||||||
@@ -1934,37 +1982,62 @@ function ExchangeConfigModal({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Binance 白名单IP提示 */}
|
{/* Binance 白名单IP提示 */}
|
||||||
{selectedExchange.id === 'binance' && (
|
{selectedExchange.id === 'binance' && (
|
||||||
<div className="p-4 rounded" style={{ background: 'rgba(240, 185, 11, 0.1)', border: '1px solid rgba(240, 185, 11, 0.2)' }}>
|
<div
|
||||||
<div className="text-sm font-semibold mb-2" style={{ color: '#F0B90B' }}>
|
className="p-4 rounded"
|
||||||
{t('whitelistIP', language)}
|
style={{
|
||||||
</div>
|
background: 'rgba(240, 185, 11, 0.1)',
|
||||||
<div className="text-xs mb-3" style={{ color: '#848E9C' }}>
|
border: '1px solid rgba(240, 185, 11, 0.2)',
|
||||||
{t('whitelistIPDesc', language)}
|
}}
|
||||||
</div>
|
>
|
||||||
|
<div
|
||||||
|
className="text-sm font-semibold mb-2"
|
||||||
|
style={{ color: '#F0B90B' }}
|
||||||
|
>
|
||||||
|
{t('whitelistIP', language)}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="text-xs mb-3"
|
||||||
|
style={{ color: '#848E9C' }}
|
||||||
|
>
|
||||||
|
{t('whitelistIPDesc', language)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{loadingIP ? (
|
{loadingIP ? (
|
||||||
<div className="text-xs" style={{ color: '#848E9C' }}>
|
<div className="text-xs" style={{ color: '#848E9C' }}>
|
||||||
{t('loadingServerIP', language)}
|
{t('loadingServerIP', language)}
|
||||||
</div>
|
</div>
|
||||||
) : serverIP && serverIP.public_ip ? (
|
) : serverIP && serverIP.public_ip ? (
|
||||||
<div className="flex items-center gap-2 p-2 rounded" style={{ background: '#0B0E11' }}>
|
<div
|
||||||
<code className="flex-1 text-sm font-mono" style={{ color: '#F0B90B' }}>{serverIP.public_ip}</code>
|
className="flex items-center gap-2 p-2 rounded"
|
||||||
<button
|
style={{ background: '#0B0E11' }}
|
||||||
type="button"
|
|
||||||
onClick={() => handleCopyIP(serverIP.public_ip)}
|
|
||||||
className="px-3 py-1 rounded text-xs font-semibold transition-all hover:scale-105"
|
|
||||||
style={{ background: 'rgba(240, 185, 11, 0.2)', color: '#F0B90B' }}
|
|
||||||
>
|
>
|
||||||
{copiedIP ? t('ipCopied', language) : t('copyIP', language)}
|
<code
|
||||||
</button>
|
className="flex-1 text-sm font-mono"
|
||||||
</div>
|
style={{ color: '#F0B90B' }}
|
||||||
) : null}
|
>
|
||||||
</div>
|
{serverIP.public_ip}
|
||||||
)}
|
</code>
|
||||||
</>
|
<button
|
||||||
)}
|
type="button"
|
||||||
|
onClick={() => handleCopyIP(serverIP.public_ip)}
|
||||||
|
className="px-3 py-1 rounded text-xs font-semibold transition-all hover:scale-105"
|
||||||
|
style={{
|
||||||
|
background: 'rgba(240, 185, 11, 0.2)',
|
||||||
|
color: '#F0B90B',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{copiedIP
|
||||||
|
? t('ipCopied', language)
|
||||||
|
: t('copyIP', language)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* Hyperliquid 交易所的字段 */}
|
{/* Hyperliquid 交易所的字段 */}
|
||||||
{selectedExchange.id === 'hyperliquid' && (
|
{selectedExchange.id === 'hyperliquid' && (
|
||||||
|
|||||||
Reference in New Issue
Block a user