feat(trader): add Indodax exchange integration (#1400)

* feat(trader): add Indodax exchange integration

- Add IndodaxTrader implementing types.Trader interface for spot trading
- Support HMAC-SHA512 authentication with Key/Sign headers
- Map spot buy/sell to OpenLong/CloseLong, stub futures-only methods
- Wire up auto_trader.go, trader_manager.go, store/exchange.go
- Add Indodax to frontend ExchangeConfigModal and ExchangeIcons
- Add integration tests with env-var based credentials
- Add Indodax logo assets (PNG + SVG)

* fix: type validation at server.go for indodax exchange
This commit is contained in:
Muhammad Syaiful Anwar
2026-03-03 17:41:50 +07:00
committed by GitHub
parent 3358c5a53e
commit 27a7491cd1
10 changed files with 1331 additions and 60 deletions

View File

@@ -17,6 +17,7 @@ const ICON_PATHS: Record<string, string> = {
hyperliquid: '/exchange-icons/hyperliquid.png',
aster: '/exchange-icons/aster.svg',
lighter: '/exchange-icons/lighter.png',
indodax: '/exchange-icons/indodax.png',
}
// 通用图标组件
@@ -101,7 +102,9 @@ export const getExchangeIcon = (
? 'aster'
: lowerType.includes('lighter')
? 'lighter'
: lowerType
: lowerType.includes('indodax')
? 'indodax'
: lowerType
const iconProps = {
width: props.width || 24,

View File

@@ -30,6 +30,7 @@ const SUPPORTED_EXCHANGE_TEMPLATES = [
{ exchange_type: 'hyperliquid', name: 'Hyperliquid', type: 'dex' as const },
{ exchange_type: 'aster', name: 'Aster DEX', type: 'dex' as const },
{ exchange_type: 'lighter', name: 'Lighter', type: 'dex' as const },
{ exchange_type: 'indodax', name: 'Indodax', type: 'cex' as const },
]
interface ExchangeConfigModalProps {
@@ -204,6 +205,7 @@ export function ExchangeConfigModal({
hyperliquid: { url: 'https://app.hyperliquid.xyz/join/AITRADING', hasReferral: true },
aster: { url: 'https://www.asterdex.com/en/referral/fdfc0e', hasReferral: true },
lighter: { url: 'https://app.lighter.xyz/?referral=68151432', hasReferral: true },
indodax: { url: 'https://indodax.com/ref/Saep23/1', hasReferral: true },
}
// Initialize form when editing
@@ -312,7 +314,7 @@ export function ExchangeConfigModal({
setIsSaving(true)
try {
if (currentExchangeType === 'binance' || currentExchangeType === 'bybit') {
if (currentExchangeType === 'binance' || currentExchangeType === 'bybit' || currentExchangeType === 'indodax') {
if (!apiKey.trim() || !secretKey.trim()) return
await onSave(exchangeId, exchangeType, trimmedAccountName, apiKey.trim(), secretKey.trim(), '', testnet)
} else if (currentExchangeType === 'okx' || currentExchangeType === 'bitget' || currentExchangeType === 'kucoin') {
@@ -503,7 +505,7 @@ export function ExchangeConfigModal({
</div>
{/* CEX Fields */}
{(currentExchangeType === 'binance' || currentExchangeType === 'bybit' || currentExchangeType === 'okx' || currentExchangeType === 'bitget' || currentExchangeType === 'gate' || currentExchangeType === 'kucoin') && (
{(currentExchangeType === 'binance' || currentExchangeType === 'bybit' || currentExchangeType === 'okx' || currentExchangeType === 'bitget' || currentExchangeType === 'gate' || currentExchangeType === 'kucoin' || currentExchangeType === 'indodax') && (
<>
{currentExchangeType === 'binance' && (
<div