GDEX MCP Server (gdex-skill)
Servidor MCP para GDEX Pro: trading al contado en 11 redes, perpetuos de Hyperliquid hasta 50x, y copy trading. El apalancamiento y el copy trading conllevan riesgo de pérdida.
Documentación
██████╗ ██████╗ ███████╗██╗ ██╗ ██████╗ ██████╗ ██████╗
██╔════╝ ██╔══██╗██╔════╝╚██╗██╔╝ ██╔══██╗██╔══██╗██╔═══██╗
██║ ███╗██║ ██║█████╗ ╚███╔╝ ██████╔╝██████╔╝██║ ██║
██║ ██║██║ ██║██╔══╝ ██╔██╗ ██╔═══╝ ██╔══██╗██║ ██║
╚██████╔╝██████╔╝███████╗██╔╝ ██╗ ██║ ██║ ██║╚██████╔╝
╚═════╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝
· p r o · powered by GEMACH
Habilidad de Agente IA para GDEX Pro — el terminal de trading con autocustodia de Gemach
Spot entre cadenas · Perpetuos HyperLiquid · Copy trading · Portafolio · Descubrimiento de tokens · Custodia gestionada
Por qué los agentes usan GDEX
GDEX es la superficie de trading. Esta habilidad es cómo los agentes de IA (Claude, Cursor, Codex y más de 40 otros) lo instalan y operan en él — spot, perpetuos, copy-trade y puentes — sin construir su propia infraestructura de exchange.
La ruta más rápida para un agente:
npx skills add GemachDAO/gdex-skill --all --agent '*' -g
Luego abre gdex.pro para el terminal humano, o ejecuta el servidor MCP para que el agente pueda ejecutar operaciones por sí mismo.
Tabla de Contenidos
- Instalar como Habilidad de Agente
- Servidor MCP
- Instalación del SDK
- Inicio Rápido
- Verificar (sin conexión)
- Autenticación
- Referencia de API
- Cadenas Soportadas
- Manejo de Errores
- Funciones de Utilidad
- Pruebas
- Arquitectura
🤖 Instalar como Habilidad de Agente
Instala directamente en Claude Code, Cursor, Codex, Windsurf y más de 40 otros agentes usando la CLI de habilidades:
# Install all skills (recommended)
npx skills add GemachDAO/gdex-skill --all --agent '*' -g
# Pick skills interactively
npx skills add GemachDAO/gdex-skill
# Install a specific skill
npx skills add GemachDAO/gdex-skill --skill gdex-spot-trading
GDEX usa una arquitectura de múltiples habilidades — los agentes cargan solo las habilidades que necesitan, manteniendo el contexto ligero y enfocado.
Habilidades Disponibles
| Habilidad | Descripción |
|---|---|
gdex-onboarding | Descripción general de la plataforma, arquitectura, cadenas soportadas, inicio rápido |
gdex-retailer-onboarding | Integraciones de socios minoristas — socios de incorporación con marca en la pila de GDEX |
gdex-authentication | Autenticación de custodia gestionada, cifrado, claves de sesión, inicio de sesión con clave API |
gdex-spot-trading | Comprar/vender tokens en cualquier cadena con enrutamiento DEX |
gdex-perp-trading | Futuros perpetuos HyperLiquid — posiciones, órdenes, apalancamiento |
gdex-perp-funding | Depositar/retirar USDC hacia/desde HyperLiquid |
gdex-limit-orders | Crear, cancelar y listar órdenes limitadas |
gdex-portfolio | Portafolio entre cadenas, saldos, historial de operaciones |
gdex-token-discovery | Detalles de tokens, tokens en tendencia, gráficos OHLCV (sin autenticación) |
gdex-token-import | Importar tokens personalizados en detalles, saldos y portafolio |
gdex-livestream-discovery | Tokens de transmisión en vivo de Solana, estado en vivo, alertas de grandes compras |
gdex-watchlist-social | Listas de seguimiento, comentarios de tokens, votación de sentimiento |
gdex-trending-promotion | Reservar espacios de tendencia pagados y verificar el estado de la reserva |
gdex-xstocks | Listado de acciones tokenizadas (xStocks) |
gdex-content-coins | Monedas de contenido Zora y monedas de creadores en Base |
gdex-copy-trading | Crear/eliminar copy trade, tablas de clasificación, historial de transacciones, lista DEX (solo Solana para escrituras) |
gdex-perp-copy-trading | Copy trading de perpetuos HL — traders principales, crear/gestionar configuraciones, datos de mercado |
gdex-hl-outcomes | Mercados de resultados (eventos) HyperLiquid — listar, ordenar, gestionar posiciones |
gdex-hl-referral | Información de referidos HyperLiquid y reclamos de recompensas |
gdex-bridge | Puente entre cadenas con cotizaciones |
gdex-transfers | Transferencias nativas y ERC20/SPL mediante custodia gestionada |
gdex-wallet-setup | Generar billeteras EVM, claves de sesión, información de billetera (sin autenticación) |
gdex-ui-install-setup | Configuración de proyectos React/Next.js, proveedores de contexto SDK, variables de entorno |
gdex-ui-trading-components | Patrones de componentes React para formularios de órdenes, tablas de posiciones, paneles de copy trade |
gdex-ui-portfolio-dashboard | Componentes de panel de portafolio — saldos, historial de operaciones, selectores de cadena |
gdex-ui-wallet-connection | UI de conexión de billetera — botones de conexión, estado de autenticación, cambio de cadena |
gdex-ui-theming | Temas CSS — modo oscuro/claro, colores de trading, puntos de interrupción responsivos, Tailwind |
gdex-ui-page-layouts | Composiciones de página completa — trading, portafolio, copy trading, páginas de puente |
gdex-sdk-debugging | Solucionar errores — códigos de error, depuración de cifrado, peculiaridades de cadenas, trampas de HL |
La description de cada habilidad le dice al agente cuándo cargarla. No se requiere configuración de clave API para las habilidades de trading (las claves compartidas están integradas).
Habilidades de Riesgo y Datos de Mercado
Fuentes de datos deterministas y eventos para riesgo e investigación. Cada una incluye un script Python de biblioteca estándar que imprime NDJSON: sin clave API, sin instalación, y cada número proviene del script, no de un modelo.
| Habilidad | Salida |
|---|---|
gdex-hl-market-risk | ~234 perpetuos principales de HyperLiquid: funding, interés abierto, prima de oráculo, límites de apalancamiento, exclusión de listado |
gdex-hl-anomaly | Eventos de anomalía HyperLiquid puntuados y con marca de tiempo (divergencia de oráculo, extremo de funding, shock de liquidez) contra líneas base aprendidas por mercado, más un registro de cobertura por ejecución. Backtest |
gdex-token-risk | Pantalla de tokens GDEX en 12 cadenas: precio, liquidez, volumen, honeypot, impuestos, bloqueo de LP, concentración de tenedores (los datos de seguridad faltantes nunca son "seguros") |
gvault | GVault (GMACL, Enzyme en Ethereum): NAV, precio de acción, tenencias, retorno acumulado y anualizado |
python3 skills/gdex-hl-market-risk/scripts/hl_market_risk.py > hl.ndjson
Arnés de Habilidades (trae tu propia clave)
harness/ ejecuta estas habilidades con Claude en tu propia clave API de Anthropic.
export produce cada fuente sin modelo; ask responde preguntas con un agente que solo puede
citar cifras que los scripts de habilidades imprimieron. Cada ejecución de script se registra con un sha256 de su salida.
🔌 Servidor MCP
El servidor MCP de GDEX expone 117 herramientas — ejecución completa de trading + documentación del SDK — como herramientas del Protocolo de Contexto de Modelo. Cualquier agente de IA compatible con MCP puede operar de forma autónoma.
Código fuente: el servidor está implementado en este repositorio, en mcp-server/. El punto de entrada es mcp-server/src/index.ts y los manejadores de herramientas están en mcp-server/src/tools/. El paquete npm @gemachdao/gdex-mcp-server se construye desde ese directorio mediante el flujo de trabajo de lanzamiento. Consulta mcp-server/README.md para ejecutarlo desde el código fuente o con el Dockerfile del repositorio.
Configuración Rápida
# Auto-generate config for your AI client
npx @gemachdao/gdex-mcp-server init --client claude # → .mcp.json
npx @gemachdao/gdex-mcp-server init --client cursor # → .cursor/mcp.json
npx @gemachdao/gdex-mcp-server init --client vscode # → .vscode/mcp.json
npx @gemachdao/gdex-mcp-server init --client codex # → .codex/config.toml
npx @gemachdao/gdex-mcp-server init --client opencode # → .opencode/mcp.json
Plugin de Claude Code
/plugin marketplace add GemachDAO/gdex-skill
/plugin install gdex@gemachdao
Instala cada habilidad de GDEX más el servidor MCP (npx -y @gemachdao/gdex-mcp-server). La clave API opcional de GDEX se guarda en tu almacén de credenciales del sistema.
Codex (OpenAI)
codex plugin marketplace add GemachDAO/gdex-skill
codex plugin add gdex@gemachdao
Instala cada habilidad de GDEX más el servidor MCP. Solo para el servidor MCP: codex mcp add gdex -- npx -y @gemachdao/gdex-mcp-server.
Extensión CLI de Gemini
gemini extensions install https://github.com/GemachDAO/gdex-skill
Configuración Manual
Agrega a la configuración MCP de tu cliente:
{
"mcpServers": {
"gdex-mcp-server": {
"command": "npx",
"args": ["@gemachdao/gdex-mcp-server"],
"env": {
"GDEX_API_KEY": "your-api-key"
}
}
}
}
Variables de Entorno
| Variable | Descripción | Requerida |
|---|---|---|
GDEX_API_KEY | Clave API de GDEX — autentica automáticamente al inicio | Opcional |
GDEX_API_URL | Sobrescribir URL base de API (predeterminado: https://trade-api.gemach.io/v1) | Opcional |
Herramientas de Ejecución MCP (109 herramientas)
| Categoría | Herramientas | Descripción |
|---|---|---|
| Autenticación | auth_login, generate_session_keypair, managed_sign_in, build_sign_in_payload | Inicio de sesión con clave API, claves de sesión, inicio de sesión de custodia gestionada |
| Trading Spot | buy_token, sell_token | Comprar/vender en Solana, Sui y 10 cadenas EVM (Ethereum, Base, Arbitrum, BSC y más) |
| Trading de Perpetuos | open_perp_position, place_perp_order, close_perp_position, close_all_positions, cancel_perp_order, cancel_all_perp_orders, set_leverage, perp_deposit, perp_withdraw | Futuros perpetuos completos de HyperLiquid — largo/corto, TP/SL; apalancamiento hasta el límite de cada mercado (40x en BTC principal) |
| Datos de Perpetuos | get_account_state, get_perp_positions, get_mark_price, get_all_mid_prices, get_usdc_balance, get_hl_open_orders, get_hl_trade_history, get_hl_spot_state, get_trader_leverage | Cuenta, posiciones y precios de HyperLiquid en tiempo real |
| Ejecución Directa | execute_cross_perp, execute_isolated_perp, execute_spot, direct_cancel_order | Ejecución con clave privada — margen cruzado/aislado, spot, cancelar |
| Órdenes Limitadas | limit_buy, limit_sell, update_order, get_limit_orders | Compra/venta limitada con TP/SL, gestión de órdenes |
| Copy Trading (Solana) | get_copy_trade_wallets, get_copy_trade_custom_wallets, get_copy_trade_gems, get_copy_trade_dexes, get_copy_trade_list, get_copy_trade_tx_list, create_copy_trade, update_copy_trade | Auto-espejo de los mejores traders de Solana |
| Copy Trading (Perpetuos HL) | get_hl_top_traders, get_hl_top_traders_by_pnl, get_hl_user_stats, get_hl_perp_dexes, get_hl_all_assets, get_hl_clearinghouse_state, get_hl_meta_and_asset_ctxs, get_hl_deposit_tokens, get_hl_copy_trade_list, get_hl_copy_trade_tx_list, create_hl_copy_trade, update_hl_copy_trade | Copiar traders de perpetuos de HyperLiquid |
| Portafolio y Datos | get_portfolio, get_balances, get_trade_history, get_token_details, get_trending_tokens, get_ohlcv, get_top_traders, get_wallet_info, generate_evm_wallet | Portafolio entre cadenas, datos de mercado, velas OHLCV |
| Puente | estimate_bridge, execute_bridge, get_bridge_orders | Puente de tokens nativos entre cadenas |
| Custodia Gestionada | managed_purchase, managed_sell, managed_trade_status, build_trade_payload | Envío de operaciones cifradas de bajo nivel |
| Transferencias | transfer_native, transfer_token | Enviar tokens nativos y ERC20/SPL mediante custodia gestionada |
| Social y Listas de Seguimiento | add_comment, get_comments, vote_sentiment, get_watchlist, change_watchlist | Comentarios de tokens, votos de sentimiento, listas de seguimiento |
| Importación de Tokens | import_token | Agregar un token personalizado para que aparezca en detalles, saldos y portafolio |
| Descubrimiento y Análisis de Mercado | get_newest_tokens, get_top_tokens, get_token_trades, get_token_image, get_native_prices, get_xstocks, get_zora_tokens, get_wallet_performance, get_nof1_analytics, generate_pnl | Tokens nuevos y principales, operaciones, precios, xStocks, monedas Zora, rendimiento de billeteras, análisis NoF1, generación de PnL |
| Transmisión en Vivo | get_currently_live, get_live_status, get_bigbuys | Tokens de transmisión en vivo de Solana y alertas de grandes compras |
| Mercados de Resultados HL | hl_outcomes, get_hl_outcome_volumes, hl_outcome_account, hl_create_outcome_order, hl_cancel_outcome_order, hl_close_outcome_order | Mercados de resultados (eventos) HyperLiquid |
| Cuenta y Referidos HL | hl_enable_trading, hl_swap_collateral, hl_tx_list, hl_list_user_copy_pnl, hl_ref_info, hl_ref_claim, hl_builder_referral | Habilitación única de HL, swaps de garantía HIP-3, fills/órdenes, PnL de copy-trade, recompensas de referidos |
| Promoción y Socios | trending_list, trending_options, trending_register, trending_booking_status, get_retailers | Espacios de tendencia pagados y socios minoristas |
| Cuenta | oauth_login, associate_email | Inicio de sesión con Google y vinculación de un correo electrónico a una billetera |
Herramientas de Documentación MCP (8 herramientas)
| Herramienta | Descripción |
|---|---|
search_gdex_docs | Buscar documentación por palabra clave |
get_sdk_pattern | Patrones de código TypeScript por operación |
get_api_info | Detalles de endpoints de API (URL, método, parámetros) |
explain_workflow | Flujos de trabajo de trading paso a paso |
get_chain_info | Cadenas soportadas y capacidades |
get_trading_guide | Guías de trading spot, perpetuo o limitado |
get_copy_trade_guide | Guías de copy trading (Solana / HL) |
get_component_guide | Patrones de componentes de UI React |
📦 Instalación del SDK
npm install github:GemachDAO/gdex-skill
Instala el SDK directamente desde GitHub (se compila durante la instalación). Las importaciones permanecen
from '@gemachdao/gdex-skill'. Fija una versión connpm install github:GemachDAO/gdex-skill#v4.1.1. El script de instalación muestra un banner de inicio rápido en tu terminal. Dependencias opcionales entre pares para la firma de wallets (solo necesarias para la autenticación de wallet específica del usuario):npm install ethers # Autenticación de wallet EVM npm install bs58 tweetnacl # Autenticación de wallet Solana
🚀 Inicio Rápido
import { GdexSkill, GDEX_API_KEY_PRIMARY } from '@gemachdao/gdex-skill';
// 1. Create skill instance
const skill = new GdexSkill();
// 2. Authenticate with pre-configured shared key — no wallet needed
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY);
// 3. Spot buy on Solana
const trade = await skill.buyToken({
chain: 'solana',
tokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
amount: '0.1', // 0.1 SOL
slippage: 1, // 1% max slippage
});
console.log('Trade submitted:', trade.jobId, '— status:', trade.status);
// 4. Open a BTC 10× long on HyperLiquid
const pos = await skill.openPerpPosition({
coin: 'BTC',
side: 'long',
sizeUsd: '1000',
leverage: 10,
takeProfitPrice: '110000',
stopLossPrice: '95000',
});
// 5. Read-only endpoints need no auth
const trending = await skill.getTrendingTokens({ chain: 'solana', period: '24h', limit: 5 });
console.log('Trending:', trending.map(t => t.symbol).join(', '));
✅ Verificación (sin conexión)
Confirma que el SDK está instalado y configurado correctamente — no se requiere conexión de red ni clave API:
npm run verify
Ejemplo de salida:
1. SDK import
✓ SDK imported from ../dist/index.js
2. API keys
✓ GDEX_API_KEY_PRIMARY = 9b4e1c73...
✓ GDEX_API_KEY_SECONDARY = 2c8f0a91...
✓ GDEX_API_KEYS array = 2 keys
3. GdexSkill instantiation
✓ new GdexSkill() — default config
✓ new GdexSkill({ apiUrl, timeout, maxRetries }) — custom config
4. Authentication state (offline)
✓ isAuthenticated() = false before login
✓ loginWithApiKey(GDEX_API_KEY_PRIMARY) → isAuthenticated() = true
✓ logout() → isAuthenticated() = false
...
All 20 checks passed ✓
SDK is ready — no network token required.
🔑 Autenticación
Claves API compartidas (recomendado para agentes)
Dos claves compartidas están preconfiguradas en el paquete — los agentes no necesitan firmar transacciones de wallet:
import {
GdexSkill,
GDEX_API_KEY_PRIMARY,
GDEX_API_KEY_SECONDARY,
GDEX_API_KEYS,
} from '@gemachdao/gdex-skill';
const skill = new GdexSkill();
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY); // use primary
// or:
skill.loginWithApiKey(GDEX_API_KEY_SECONDARY); // use secondary
// or cycle through them:
skill.loginWithApiKey(GDEX_API_KEYS[0]);
skill.isAuthenticated(); // → true
skill.logout(); // clear session
Nota: Los endpoints de solo lectura (
getTrendingTokens,getTokenDetails,getOHLCV,getTopTraders) no requieren autenticación.
Autenticación basada en Wallet (avanzado)
Para wallets propiedad del usuario o firmantes personalizados (wallets de hardware, extensiones de navegador):
// EVM wallet (secp256k1)
await skill.authenticate({
type: 'evm',
address: '0xYourAddress',
privateKey: '0xPrivateKey',
});
// Solana wallet (ed25519)
await skill.authenticate({
type: 'solana',
address: 'YourSolanaAddress',
privateKey: 'base58EncodedPrivateKey',
});
// Custom signer (MetaMask / Phantom)
await skill.authenticate({
type: 'evm',
address: accounts[0],
signer: async (message) =>
window.ethereum.request({ method: 'personal_sign', params: [message, accounts[0]] }),
});
Configuración
const skill = new GdexSkill({
apiUrl: 'https://trade-api.gemach.io/v1', // Backend (default)
timeout: 30000, // Request timeout ms
maxRetries: 3, // Retry attempts on 429/503
debug: false, // Log every request
});
El SDK no lee variables de entorno directamente. Si eliges usar variables de entorno,
léelas en tu aplicación (por ejemplo, mediante process.env) y pasa sus valores al
constructor de GdexSkill como se muestra arriba.
Variables de entorno recomendadas para tu propia aplicación:
| Variable de Entorno | Descripción | Valor Predeterminado |
|---|---|---|
GDEX_API_URL | URL base del backend para pasar como apiUrl | https://trade-api.gemach.io/v1 |
GDEX_API_KEY | Clave API para cifrado AES en el flujo de custodia gestionada | — |
GDEX_TIMEOUT | Tiempo de espera de solicitud (ms) para pasar como timeout | 30000 |
GDEX_MAX_RETRIES | Intentos de reintento para pasar como maxRetries | 3 |
GDEX_DEBUG | Habilitar registro de depuración para pasar como debug | false |
GDEX_CONTROL_WALLET | Dirección de wallet de control (userId) para custodia gestionada | — |
GDEX_SESSION_PRIVATE | Clave privada de sesión (hex, prefijo 0x) para custodia gestionada | — |
GDEX_MANAGED_CHAIN_ID | ID de cadena para operaciones gestionadas (622112261=Solana, 42161=Arbitrum para perps) | 622112261 |
CONFIRM_LIVE_TRADE | Establecer en YES para enviar operaciones reales | — |
🔒 Operaciones con Custodia Gestionada
Todas las operaciones en GDEX pasan por wallets gestionadas del lado del servidor. Tu wallet de control (EVM o Solana) solo se usa para autenticar (iniciar sesión) — la ejecución real en cadena la manejan los trabajadores de operaciones del backend de GDEX.
Cómo Funciona
- Generar un par de claves de sesión — clave secp256k1 usada para firmar operaciones después de la autenticación
- Iniciar sesión — la wallet de control firma un mensaje, cifrado como
computedData→ POST/v1/sign_in - Resolver usuario — GET
/v1/usercon la clave de sesión cifrada para ver las wallets gestionadas - Operar — codificar datos de operación en ABI, firmar con la clave de sesión, cifrar como
computedData→ POST/v1/purchase_v2o/v1/sell_v2 - Consultar estado — GET
/v1/trade-status/:requestIdhasta que se complete/falla
Cifrado
Todos los payloads autenticados usan AES-256-CBC con una clave/IV determinista derivada de la clave API (sin IV aleatorio):
- Clave = primeros 32 bytes del hex de
SHA256(apiKey) - IV = primeros 16 bytes del hex de
SHA256(SHA256(apiKey)) - Payloads de operación/inicio de sesión:
JSON.stringify({ userId, data, signature, apiKey })→ UTF-8 → cifrar → hex - Clave de sesión (
/v1/user): bytes crudos decodificados en hex → cifrar (no cadena UTF-8) - La clave API se incluye dentro del payload JSON cifrado (no solo se usa para cifrar)
ADVERTENCIA: NO uses IV aleatorios ni el formato
iv:ciphertext. El backend usa AES determinista derivado de la cadena hash de la clave API.
Firmas
Firmas de operaciones spot (compra/venta) usan keccak256 crudo + secp256k1 (sin prefijo EIP-191):
- Mensaje:
"<action>-<lowercaseUserId>-<dataHexWithout0x>" - Resumen:
keccak256(utf8Bytes(message)) - Salida:
r(64 hex) + s(64 hex) + v(2 hex)= 130 caracteres, sin prefijo0x - v = parámetro de recuperación crudo (
00o01), NO EIP-155 (1b/1c)
Firmas de perps HL usan el mismo algoritmo pero con prefijos de acción específicos de HL (hl_deposit, hl_withdraw, hl_create_order, etc.) y esquemas ABI diferentes. Consulta la sección Referencia de Custodia Gestionada HL.
Firmas de inicio de sesión usan EIP-191 personal_sign con la wallet de control — esta es la ÚNICA operación que usa EIP-191. Todas las operaciones posteriores al inicio de sesión usan keccak256 crudo.
Generación de Nonce
Los nonces son generados por el cliente (no se obtienen del servidor):
const nonce = String(Math.floor(Date.now() / 1000) + Math.floor(Math.random() * 1000));
Ejemplo Rápido
import {
GdexSkill,
GDEX_API_KEY_PRIMARY,
generateGdexSessionKeyPair,
buildGdexSignInMessage,
buildGdexSignInComputedData,
buildGdexManagedTradeComputedData,
buildGdexUserSessionData,
} from '@gemachdao/gdex-skill';
const skill = new GdexSkill();
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY);
const apiKey = GDEX_API_KEY_PRIMARY;
// 1. Session keypair
const { sessionPrivateKey, sessionKey } = generateGdexSessionKeyPair();
// 2. Sign-in (control wallet signs this message)
const userId = '0xYourControlWallet';
const nonce = String(Math.floor(Date.now() / 1000) + Math.floor(Math.random() * 1000));
const message = buildGdexSignInMessage(userId, nonce, sessionKey);
const signature = /* wallet.signMessage(message) */;
const signInPayload = buildGdexSignInComputedData({ apiKey, userId, sessionKey, nonce, signature });
await skill.signInWithComputedData({ computedData: signInPayload.computedData, chainId: 900 });
// 3. Trade
const trade = buildGdexManagedTradeComputedData({
apiKey, action: 'purchase', userId,
tokenAddress: 'DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263',
amount: '100000',
nonce: String(Math.floor(Date.now() / 1000) + Math.floor(Math.random() * 1000)),
sessionPrivateKey,
});
const result = await skill.submitManagedPurchase({
computedData: trade.computedData, chainId: 900, slippage: 1,
});
// 4. Poll
if (result.requestId) {
const status = await skill.getManagedTradeStatus(result.requestId);
console.log(status.status, status.hash);
}
Ayudantes de Custodia Gestionada
| Función | Propósito |
|---|---|
generateGdexSessionKeyPair() | Generar par de claves de sesión secp256k1 |
buildGdexSignInMessage(userId, nonce, sessionKey) | Construir el mensaje de inicio de sesión para firma de wallet |
encodeGdexSignInData(sessionKey, nonce, refCode?) | Codificar datos de inicio de sesión en ABI (['bytes','string','string']) |
buildGdexSignInComputedData({...}) | Construir payload de inicio de sesión cifrado |
buildGdexUserSessionData(sessionKey, apiKey) | Cifrar clave de sesión (bytes hex crudos) para /v1/user |
encodeGdexTradeData(tokenAddr, amount, nonce?) | Codificar datos de operación en ABI (['string','uint256','string']) |
signGdexTradeMessageWithSessionKey(action, userId, data, privKey) | Firmar operación con clave de sesión (v = recoveryParam crudo 00/01) |
buildGdexManagedTradeComputedData({...}) | Construir payload de operación cifrado |
encodeLimitOrderData(action, params) | Codificar datos de orden límite en ABI (esquemas de compra/venta/actualización) |
signLimitOrderMessage(action, userId, data, privKey) | Firmar orden límite con clave de sesión |
buildLimitOrderComputedData({...}) | Construir payload de orden límite cifrado |
encodeCopyTradeData(action, params) | Codificar datos de copy trade en ABI (crear: 12 campos, actualizar: 16 campos, chainId es uint256) |
signCopyTradeMessage(action, userId, data, privKey) | Firmar copy trade con clave de sesión |
buildCopyTradeComputedData({...}) | Construir payload de copy trade cifrado |
buildEncryptedGdexPayload({...}) | Cifrar JSON {userId, data, signature} para computedData |
encryptGdexComputedData(plaintext, apiKey) | Cifrar texto plano UTF-8 con AES-256-CBC |
encryptGdexHexData(hexData, apiKey) | Cifrar bytes crudos decodificados en hex con AES-256-CBC |
decryptGdexComputedData(cipherHex, apiKey) | Descifrar a texto plano UTF-8 con AES-256-CBC |
deriveGdexAesMaterial(apiKey) | Obtener clave/IV AES crudos de la clave API |
Verificar Flujo Gestionado (sin conexión)
npm run verify:managed
Esto genera todos los payloads (par de claves de sesión, inicio de sesión, consulta de usuario, operación), valida los ciclos de cifrado/descifrado e imprime el plan de ejecución completo — sin realizar ninguna llamada API en vivo.
📚 Referencia de API
Operaciones Spot
buyToken(params)
Comprar un token en cualquier cadena compatible.
| Parámetro | Tipo | Obligatorio | Descripción |
|---|---|---|---|
chain | string | ChainId | ✅ | Nombre de cadena o ID numérico |
tokenAddress | string | ✅ | Dirección del contrato del token |
amount | string | ✅ | Cantidad de entrada de token nativo |
slippage | number | % máximo de deslizamiento (predeterminado: 1) | |
dex | string | Forzar DEX específico | |
walletAddress | string | Sobrescribir dirección de wallet | |
priorityFee | number | Tarifa de prioridad de Solana (lamports) |
const result = await skill.buyToken({
chain: 'solana',
tokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: '0.1',
slippage: 1,
});
// result.jobId, result.status, result.txHash, result.outputAmount
sellToken(params)
// Sell absolute amount
await skill.sellToken({ chain: 8453, tokenAddress: '0x...', amount: '100', slippage: 0.5 });
// Sell 50% of holdings
await skill.sellToken({ chain: 'solana', tokenAddress: '...', amount: '50%' });
Futuros Perpetuos (HyperLiquid)
Crítico: Los depósitos/retiros/órdenes de HyperLiquid usan un flujo criptográfico diferente al de las operaciones spot. Consulta la sección Referencia de Custodia Gestionada HL a continuación para especificaciones exactas.
openPerpPosition(params)
| Parámetro | Tipo | Predeterminado | Descripción |
|---|---|---|---|
coin | string | Símbolo del activo (p. ej., 'BTC', 'ETH') | |
side | 'long' | 'short' | Dirección | |
sizeUsd | string | Colateral en USD | |
leverage | number | 5 | 1–50× |
takeProfitPrice | string | Precio de TP opcional | |
stopLossPrice | string | Precio de SL opcional | |
marginMode | 'cross' | 'isolated' | 'cross' | Modo de margen |
const pos = await skill.openPerpPosition({
coin: 'BTC', side: 'long', sizeUsd: '1000', leverage: 10,
takeProfitPrice: '110000', stopLossPrice: '95000',
});
closePerpPosition(params)
await skill.closePerpPosition({ coin: 'BTC' }); // close 100%
await skill.closePerpPosition({ coin: 'ETH', closePercent: 50 }); // close 50%
Otros métodos de perps
await skill.setPerpLeverage({ coin: 'BTC', leverage: 20 });
// Update leverage via HL managed-custody (explicit session-key signing)
await skill.hlUpdateLeverage({
coin: 'BTC',
leverage: 40,
isCross: true, // true = cross margin, false = isolated (default: true)
apiKey,
walletAddress,
sessionPrivateKey,
});
// Deposit USDC to HyperLiquid (human-readable amount, converted internally)
await skill.perpDeposit({ amount: '10' }); // deposit 10 USDC (minimum)
await skill.perpWithdraw({ amount: '5' }); // withdraw 5 USDC
const positions = await skill.getPerpPositions({ walletAddress: '0x...' });
// Each: { coin, side, size, entryPrice, markPrice, leverage, unrealizedPnl, liquidationPrice }
Notas sobre depósitos HL: El monto está en USDC legible para humanos (p. ej.,
'10'para 10 USDC). El SDK convierte automáticamente a la unidad más pequeña (6 decimales). El depósito mínimo es de 10 USDC. Tu wallet gestionada debe tener el monto del depósito + el margen de tarifa del 1% en USDC en Arbitrum. Después de que la transacción en cadena se confirme, HyperLiquid tarda ~10 minutos en acreditar el depósito.
Ejecución Directa en HyperLiquid (mediante @gdexsdk/hyper-liquid-trader)
Para operar directamente en HyperLiquid L1 sin custodia gestionada — usa tu propia clave privada:
// Cross-margin perpetual trade
const result = await skill.hlExecuteCrossPerp(
process.env.PRIVATE_KEY!,
{ coin: 'BTC', isLong: true, price: '100000', positionSize: '0.001', leverage: 10 },
);
// Isolated-margin perpetual trade
const result2 = await skill.hlExecuteIsolatedPerp(
process.env.PRIVATE_KEY!,
{ coin: 'ETH', isLong: false, price: '3000', positionSize: '1', leverage: 5 },
);
// Spot trade on HyperLiquid
const result3 = await skill.hlExecuteSpot(
process.env.PRIVATE_KEY!,
{ coin: 'PURR', isBuy: true, price: '0.50', size: '100' },
);
// Cancel an order directly
await skill.hlDirectCancelOrder(process.env.PRIVATE_KEY!, 'BTC', orderId);
// Get all mid prices
const mids = await skill.getHlAllMids();
// Get trade history
const trades = await skill.getHlTradeHistory('0xYourWallet');
// Get a trader's leverage context (for copy trading)
const leverage = await skill.getHlTraderLeverageContext('0xTraderWallet', 'BTC');
// Create a standalone HyperLiquidTrading instance with custom WS URLs
const trader = await skill.createHlTrader(['wss://custom-ws.example.com']);
Órdenes Límite
Endpoints:
limit_buy/limit_sell/update_order/orders— NOorders/createniorders/cancel.
// Limit buy — buy WIF when price drops to $0.50 on Solana
const buyResult = await skill.limitBuy({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD', // control wallet
sessionPrivateKey: '<session-key-hex>',
chainId: 622112261, // Solana
tokenAddress: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm',
amount: '10000000', // lamports
triggerPrice: '0.50',
profitPercent: '50', // optional: TP at 50% gain
lossPercent: '25', // optional: SL at 25% loss
});
// Limit sell — sell WIF when price reaches $999.99 (take-profit)
const sellResult = await skill.limitSell({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
sessionPrivateKey: '<session-key-hex>',
chainId: 622112261,
tokenAddress: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm',
amount: '100000',
triggerPrice: '999.99',
});
// Delete/cancel an order
await skill.updateOrder({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
sessionPrivateKey: '<session-key-hex>',
chainId: 622112261,
orderId: '<64-char-hex-order-id>',
isDelete: true,
});
// List active orders (uses session-key auth, not full computedData)
const { count, orders } = await skill.getLimitOrders({
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
data: encryptedSessionKey, // from buildGdexUserSessionData()
chainId: 622112261,
});
Copy Trading
Solo Solana para operaciones de escritura. El inicio de sesión debe usar
chainId: 622112261. El ABI codificachainIdcomouint256.
Descubrimiento (sin autenticación)
// Top 300 wallets by total PnL (cached 2 min)
const topWallets = await skill.getCopyTradeWallets();
// [{ address, totalPnl, receivedMinusSpent, spent, unrealizedValue, chainId }]
// Top 300 by net received
const customWallets = await skill.getCopyTradeCustomWallets();
// Hot new tokens from top wallets (cached 20s)
const gems = await skill.getCopyTradeGems();
// Supported DEXes for Solana
const dexes = await skill.getCopyTradeDexes(622112261);
// [{ dexName: 'pumpfun', dexNumber: 0, programId: '...' }, ...]
Lectura (autenticación con clave de sesión)
import { buildGdexUserSessionData } from '@gemachdao/gdex-skill';
const data = buildGdexUserSessionData(sessionKey, apiKey);
// List copy trade configs (cached 20s per user)
const { allCopyTrades, dexes } = await skill.getCopyTradeList({ userId, data });
// allCopyTrades: [{ copyTradeId, copyTradeName, traderWallet, isActive, lossPercent, profitPercent, ... }]
// Transaction history with PnL
const { txes } = await skill.getCopyTradeTxList({ userId, data });
Crear (autenticación computedData)
import {
GDEX_API_KEY_PRIMARY,
buildCopyTradeComputedData,
generateGdexSessionKeyPair,
buildGdexSignInMessage,
buildGdexSignInComputedData,
} from '@gemachdao/gdex-skill';
// Sign-in MUST use chainId: 622112261 for copy trade operations
const result = await skill.createCopyTrade({
apiKey: GDEX_API_KEY_PRIMARY,
userId: controlWalletAddress,
sessionPrivateKey,
chainId: 622112261, // Solana only
traderWallet: 'SolanaTraderAddress',
copyTradeName: 'Alpha Trader',
buyMode: 1, // 1 = fixed SOL, 2 = percentage
copyBuyAmount: '0.001', // SOL amount (mode 1) or percentage (mode 2)
lossPercent: '50', // stop-loss at 50%
profitPercent: '100', // take-profit at 100%
copySell: true, // also copy sell trades
isBuyExistingToken: false, // skip tokens already held
excludedDexNumbers: [], // no DEX exclusions
});
// { isSuccess: true, message: 'created new copy trade successfully', allCopyTrades: [...] }
Eliminar (autenticación computedData)
// Delete a copy trade (isDelete: true)
const deleteResult = await skill.updateCopyTrade({
apiKey: GDEX_API_KEY_PRIMARY,
userId: controlWalletAddress,
sessionPrivateKey,
chainId: 622112261,
copyTradeId: '<64-char-hex-id>',
traderWallet: 'SolanaTraderAddress',
copyTradeName: 'Alpha Trader',
buyMode: 1,
copyBuyAmount: '0.001',
lossPercent: '50',
profitPercent: '100',
isDelete: true, // permanently deletes the copy trade
});
// { isSuccess: true, message: 'Updated' }
ADVERTENCIA: Tanto
isDelete: truecomoisChangeStatus: trueeliminan permanentemente el copy trade. No hay función de activar/pausar en el backend actual. Los campos booleanos usan''para falso y'1'para verdadero internamente; la cadena'0'es verdadera en JS y activará la eliminación.
Referencia ABI de Copy Trade
| Acción | Campos | Tipos ABI |
|---|---|---|
create_copy_trade | 12 | ['string','string','uint256','string'×9] |
update_copy_trade | 16 | ['string','string','uint256','string'×13] |
Orden de campos al crear: [traderWallet, copyTradeName, chainId, gasPrice, buyMode, copyBuyAmount, isBuyExistingToken, lossPercent, profitPercent, nonce, copySell, excludedDexNumbers]
Orden de campos al actualizar: [traderWallet, copyTradeName, chainId, gasPrice, buyMode, copyBuyAmount, isBuyExistingToken, lossPercent, profitPercent, nonce, copySell, excludedDexNumbers, copyTradeId, isDelete, isChangeStatus, excludedProgramIds]
chainIden la posición 2 esuint256, todos los demás campos sonstring. El nonce se genera automáticamente por el SDK.
Copy Trading de Perps HL
Completamente separado del copy trading de Solana anterior. Esto copia posiciones de futuros perpetuos (largo/corto) en HyperLiquid. El inicio de sesión usa
chainId: 1. Todos los campos ABI son cadenas.
Descubrimiento (sin autenticación)
// Top traders by volume/tradeCount/deposit (cached 15 min)
const topByVolume = await skill.getHlTopTraders('volume');
const topByPnl = await skill.getHlTopTradersByPnl();
// Detailed trader stats (cached 1 hr)
// NOTE: Requires MANAGED wallet address, not control wallet
const stats = await skill.getHlUserStats('0xManagedWalletAddress');
// { userStats: { '24h', '7d', '30d', dailyPnls, volumes, tradesCount, allTime } }
// Market data
const dexes = await skill.getHlPerpDexes();
const assets = await skill.getHlAllAssets();
const tokens = await skill.getHlDepositTokens();
// Account state
const state = await skill.getHlClearinghouseState('0xAddress');
const orders = await skill.getHlOpenOrdersForCopy('0xAddress');
const balance = await skill.getHlUsdcBalanceForCopy('0xAddress');
Lectura (autenticación con clave de sesión)
import { buildGdexUserSessionData } from '@gemachdao/gdex-skill';
const data = buildGdexUserSessionData(sessionKey, apiKey);
// List HL copy trade configs
const { allCopyTrades } = await skill.getHlCopyTradeList({ userId, data });
// [{ copyTradeId, copyTradeName, copyMode, traderWallet, isActive, oppositeCopy, totalPnl, ... }]
// Fill history (cached 15s, max 100 per page)
const { txes, totalCount } = await skill.getHlCopyTradeTxList({ userId, data, page: '1', limit: '20' });
// [{ coin, px, sz, side, dir, closedPnl, copyTradeName, traderWallet, ... }]
Crear (autenticación computedData)
await skill.createHlCopyTrade({
apiKey,
userId: controlWalletAddress,
sessionPrivateKey,
traderWallet: '0xTraderEvmAddress',
copyTradeName: 'BTC Whale',
copyMode: 1, // 1 = fixed USD, 2 = proportion
fixedAmountCostPerOrder: '50', // $50 per copied trade
lossPercent: '25', // mandatory, > 0 and < 100
profitPercent: '100', // mandatory, > 0
oppositeCopy: false, // true = copy opposite direction
});
Actualizar / Eliminar (autenticación computedData)
// Update parameters
await skill.updateHlCopyTrade({
apiKey, userId: controlWalletAddress, sessionPrivateKey,
copyTradeId: 'abc123...',
traderWallet: '0xTraderEvmAddress',
copyTradeName: 'Updated Name',
copyMode: 2, fixedAmountCostPerOrder: '0.5',
lossPercent: '30', profitPercent: '150',
oppositeCopy: true,
});
// Delete permanently (use isDelete)
await skill.updateHlCopyTrade({ ...existingParams, isDelete: true });
// WARNING: isChangeStatus also PERMANENTLY DELETES (does NOT toggle)
await skill.updateHlCopyTrade({ ...existingParams, isChangeStatus: true });
Referencia ABI de Copy Trade de Perps HL
| Acción | Campos | Tipos ABI |
|---|---|---|
hl_create | 8 | ['string' × 8] |
hl_update | 11 | ['string' × 11] |
Orden de campos al crear: [traderWallet, copyTradeName, copyMode, fixedAmountCostPerOrder, lossPercent, profitPercent, nonce, oppositeCopy]
Orden de campos al actualizar: [traderWallet, copyTradeName, copyMode, fixedAmountCostPerOrder, lossPercent, profitPercent, nonce, isDelete, isChangeStatus, copyTradeId, oppositeCopy]
Todos los campos son
string. Campos booleanos:'1'= verdadero,''= falso. Nonce generado automáticamente por el SDK. Nota:copyModeyoppositeCopyen las respuestas contienen desplazamientos de bytes ABI (p. ej., 416), no valores reales. TantoisDeletecomoisChangeStatuseliminan permanentemente la operación.
Portafolio
// Full cross-chain portfolio
const portfolio = await skill.getPortfolio({ walletAddress: '0x...' });
// { totalValueUsd, balances, perpPositions?, realizedPnl, unrealizedPnl }
// Chain-specific balances
const balances = await skill.getBalances({ walletAddress: '0x...', chain: ChainId.ETHEREUM });
// Paginated trade history
const history = await skill.getTradeHistory({
walletAddress: '0x...', page: 1, limit: 20,
startTime: 1700000000, endTime: 1700086400,
});
Información de Tokens
🔓 No se requiere autenticación para estos endpoints.
// Token details
const token = await skill.getTokenDetails({
tokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
chain: 'solana',
});
// { symbol, name, priceUsd, priceChange24h, marketCap, fdv, volume24h, liquidity }
// Trending tokens
const trending = await skill.getTrendingTokens({
chain: 'solana',
period: '24h', // '1h' | '6h' | '24h' | '7d'
limit: 20,
minLiquidity: 50000,
});
// OHLCV candles
const ohlcv = await skill.getOHLCV({
tokenAddress: 'So11111111111111111111111111111111111111112',
chain: 'solana',
resolution: '60', // '1'|'5'|'15'|'30'|'60'|'240'|'D'|'W'
from: Math.floor(Date.now() / 1000) - 86400,
to: Math.floor(Date.now() / 1000),
});
Mejores Traders
🔓 No se requiere autenticación.
const traders = await skill.getTopTraders({
chain: 'solana',
period: '7d', // '1d' | '7d' | '30d' | 'all'
limit: 10,
sortBy: 'pnl', // 'pnl' | 'winRate' | 'volume' | 'tradeCount'
});
// [{ address, totalPnlUsd, winRate, tradeCount, totalVolumeUsd }]
Puente
// Get quote first
const quote = await skill.getBridgeQuote({
fromChain: 'solana',
toChain: ChainId.ETHEREUM,
tokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: '100',
});
console.log('Output:', quote.outputAmount, '— fee (USD):', quote.feeUsd);
// Execute bridge
const result = await skill.bridge({
fromChain: 'solana',
toChain: ChainId.ETHEREUM,
tokenAddress: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
amount: '100',
destinationAddress: '0xYourEthAddress',
slippage: 0.5,
});
Información de Wallet
const info = await skill.getWalletInfo({ walletAddress: '...', chain: 'solana' });
// { address, nativeBalance, nativeSymbol, totalValueUsd, tokenCount }
Generación de Wallet
🔓 No se requiere autenticación. Las claves se generan localmente y nunca se transmiten.
Cuando un usuario aún no tiene wallet, genera una wallet de control EVM para él. Luego usa el flujo de inicio de sesión de custodia gestionada para autenticar, y el backend de Gbot aprovisiona automáticamente una wallet de trading completa — incluida una dirección de Solana y otras claves específicas de cadena — del lado del servidor. No se necesita generación separada de wallet de Solana.
generateEvmWallet() — tu wallet de control
Genera una nueva wallet compatible con EVM (Ethereum, Base, Arbitrum, BSC, etc.) usando ethers.Wallet.createRandom().
import {
GdexSkill,
generateEvmWallet,
generateGdexSessionKeyPair,
buildGdexSignInMessage,
GDEX_API_KEY_PRIMARY,
} from '@gemachdao/gdex-skill';
// Step 1: generate your EVM control wallet (one-time setup)
const wallet = generateEvmWallet();
console.log(wallet.address); // '0xAbCd...' (checksummed) — safe to share
// ⚠️ Store wallet.privateKey and wallet.mnemonic securely
// Step 2: generate a session keypair for managed-custody trading
const { sessionPrivateKey, sessionKey } = generateGdexSessionKeyPair();
// Step 3: build the sign-in message and sign with your control wallet
const message = buildGdexSignInMessage(wallet.address, String(Date.now()), sessionKey);
// Sign with: new ethers.Wallet(wallet.privateKey).signMessage(message)
// Step 4: submit sign_in computedData (see Managed-Custody Trading section above)
// The backend provisions Solana + all other trading wallets server-side
🌐 Cadenas Compatibles
| Cadena | ChainId | Token nativo | DEXes |
|---|---|---|---|
| Ethereum | 1 | ETH | Uniswap V2/V3, Odos |
| Optimism | 10 | ETH | Uniswap V3, Odos |
| BNB Smart Chain | 56 | BNB | PancakeSwap, Odos |
| Sonic | 146 | S | — |
| Fraxtal | 252 | frxETH | Uniswap V3 |
| Nibiru | 6900 | NIBI | — |
| Base | 8453 | ETH | Uniswap V3, Odos, Arcadia |
| Arbitrum One | 42161 | ETH | Uniswap V3, Odos |
| Berachain | 80094 | BERA | — |
| Solana | 622112261 | SOL | Raydium, Raydium V2, Orca |
| Sui | 1313131213 | SUI | Cetus, Bluefin |
| HyperLiquid | solo perps | USDC | Motor de perps nativo |
El enum
ChainIdes más amplio que esta tabla. También define Avalanche (43114), Polygon (137), zkSync Era (324), Linea (59144), Blast (81457) y Scroll (534352). ElsupportedChainIdsdel backend no los incluye, por lo que las llamadas contra esos ids no se enrutarán. Opera solo con las cadenas listadas arriba.
import { ChainId } from '@gemachdao/gdex-skill';
ChainId.ETHEREUM // 1
ChainId.OPTIMISM // 10
ChainId.BSC // 56
ChainId.SONIC // 146
ChainId.FRAXTAL // 252
ChainId.NIBIRU // 6900
ChainId.BASE // 8453
ChainId.ARBITRUM // 42161
ChainId.BERACHAIN // 80094
ChainId.SOLANA // 622112261
ChainId.SUI // 1313131213
⚠️ Manejo de Errores
import {
GdexAuthError, // 401/403 — re-authenticate
GdexValidationError, // invalid input params
GdexApiError, // 4xx/5xx backend errors
GdexNetworkError, // connection failures, timeouts
GdexRateLimitError, // 429 — check err.retryAfter
} from '@gemachdao/gdex-skill';
try {
await skill.buyToken({ ... });
} catch (err) {
if (err instanceof GdexRateLimitError) {
console.log(`Rate limited — retry after ${err.retryAfter}s`);
await new Promise(r => setTimeout(r, err.retryAfter * 1000));
// retry…
} else if (err instanceof GdexAuthError) {
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY); // re-auth
} else if (err instanceof GdexValidationError) {
console.error(`Bad param "${err.field}": ${err.message}`);
} else if (err instanceof GdexApiError) {
console.error(`API ${err.statusCode}: ${err.message}`);
} else if (err instanceof GdexNetworkError) {
console.error(`Network (${err.code}): ${err.message}`);
}
}
| Clase | Cuándo se lanza |
|---|---|
GdexAuthError | 401/403, credenciales inválidas |
GdexValidationError | Dirección, monto, cadena o slippage inválidos |
GdexApiError | HTTP no exitoso (4xx/5xx) |
GdexNetworkError | Conexión rechazada, ECONNABORTED, timeout |
GdexRateLimitError | HTTP 429 (tiene .retryAfter en segundos) |
🛠 Funciones de Utilidad
import {
getChainName, // getChainName(8453) → "Base"
getNativeToken, // getNativeToken('solana') → "SOL"
formatTokenAmount, // formatTokenAmount('1000000', 6, 'USDC') → "1 USDC"
formatUsd, // formatUsd('1234.5') → "$1,234.50"
formatPercentChange, // formatPercentChange('5.23') → "+5.23%"
shortenAddress, // shortenAddress('0x1234...') → "0x1234...5678"
validateAddress, // throws GdexValidationError if invalid
validateAmount, // throws GdexValidationError if invalid
validateChain, // throws GdexValidationError if unsupported
} from '@gemachdao/gdex-skill';
🧪 Pruebas
Las 103 pruebas se ejecutan con HTTP simulado — no se requiere clave API real ni conexión de red:
npm test # run all 103 tests
npm run test:coverage # with coverage report
npm run verify # offline SDK smoke-test (20 checks)
npm run verify:managed # managed-custody payload validation (dry-run)
Suites de pruebas:
tests/client/auth.test.ts— autenticación con clave API, firma de wallets EVM/Solanatests/actions/spotTrade.test.ts— compra/venta, slippage, validacióntests/actions/perpTrade.test.ts— apertura/cierre de posiciones, apalancamiento, depósitostests/actions/portfolio.test.ts— saldos, historial, información de wallettests/actions/tokenInfo.test.ts— tendencias, OHLCV, detalles de tokens, mejores traderstests/utils/walletGeneration.test.ts— generación de wallet de control EVM (offline)tests/utils/gdexManagedCrypto.test.ts— helpers de cripto con custodia gestionada (AES, firma, codificación ABI)
🏗 Arquitectura
AI Agent (Claude Code / Cursor / Codex / ...)
│
│ npx skills add GemachDAO/gdex-skill
│ ──────────────────────────────────
│ SKILL.md → agent skill directory
│
▼
@gemachdao/gdex-skill (this package)
│ TypeScript methods with full type safety
│ @gdexsdk/hyper-liquid-trader for HyperLiquid L1 queries & direct execution
│ Managed-custody: AES-256-CBC encryption + secp256k1 session signing
│ computedData payloads for all trade operations
│ Auto-retry with exponential backoff
│
│ Control Wallet (EVM / Solana)
│ └─ signs once for /v1/sign_in → session keypair
│
▼
Gbot Backend API (https://trade-api.gemach.io/v1)
│ Decrypt computedData → verify signature → resolve nonce (gRPC)
│ NATS JetStream trade queue
│ Server-side managed wallets (custody)
│ DEX aggregation engine
▼
Blockchains (Solana · Sui · Ethereum · Base · Arbitrum · …)
Referencia de Custodia Gestionada HL
Las operaciones de perps en HyperLiquid usan un pipeline criptográfico distinto al de los trades al contado. Cualquier detalle incorrecto produce un error 400 Unauthorized (code 103). Esta sección documenta la especificación exacta.
Flujo de Depósito HL
El backend ejecuta custodialmente el depósito on-chain: carga la clave privada del usuario en el servidor, construye una transacción de Arbitrum y envía USDC al receptor del puente de HyperLiquid. El agente solo proporciona una firma de autorización.
Agent SDK Backend
──────── ───────
1. ABI-encode deposit params ──► 2. AES-decrypt computedData
(uint64 chainId, address, 3. ABI-decode data
uint256 amount, string nonce) 4. Verify chainId == 42161
2. Sign with session key ──► 5. Verify signature vs stored sessionKey
3. AES-encrypt as computedData ──► 6. Validate token, balance, min deposit
4. POST /v1/hl/deposit 7. Execute ERC-20 transfer on Arbitrum
Esquemas ABI HL (CRÍTICO)
| Acción | Tipos ABI | Campos |
|---|---|---|
hl_deposit | ['uint64', 'address', 'uint256', 'string'] | [chainId, tokenAddress, amount, nonce] |
hl_withdraw | ['string', 'string'] | [amount, nonce] |
hl_create_order | ['string', 'bool', 'string', 'string', 'bool', 'string', 'string', 'string', 'bool'] | [coin, isLong, price, size, reduceOnly, nonce, tpPrice, slPrice, isMarket] |
hl_place_order | ['string', 'bool', 'string', 'string', 'bool', 'string'] | [coin, isLong, price, size, reduceOnly, nonce] |
hl_close_all | ['string'] | [nonce] |
hl_cancel_order | ['string', 'string', 'string'] | [nonce, coin, orderId] |
hl_cancel_all_orders | ['string'] | [nonce] |
hl_update_leverage | ['string', 'uint32', 'bool', 'string'] | [coin, leverage, isCross, nonce] |
ADVERTENCIA: El chainId
hl_depositusauint64, NOuint256. Esta es la causa más común de errores "Unauthorized". El backend re-codifica conuint64para la verificación de firma — si codificas conuint256, el hex difiere, la recuperación de firma falla y obtienes el código 103.
Formato de Firma HL
Todas las operaciones de escritura HL firman con la clave privada de sesión (del sign-in), NO con la clave de la wallet de control:
// Message format (no EIP-191 prefix):
const msg = `${action}-${userId.toLowerCase()}-${dataHex}`;
// e.g.: "hl_deposit-0x53d029a6...-00000000000000000000000000000000000000000000000000000000..."
const digest = keccak256(toUtf8Bytes(msg));
const sig = new SigningKey(sessionPrivateKey).sign(digest);
// Output: r(64hex) + s(64hex) + v(2hex) = 130 chars, no 0x prefix
// v = raw recovery parameter (00 or 01), NOT EIP-155 (1b/1c)
Restricciones de Depósito HL
| Restricción | Valor |
|---|---|
| Cadena | Solo Arbitrum (chainId 42161) |
| Token | Solo USDC (0xaf88d065e77c8cC2239327C5EDb3A432268e5831) |
| Monto | En la unidad más pequeña (6 decimales): 10 USDC = 10000000 |
| Depósito mínimo | 10 USDC |
| Buffer de comisión | El saldo debe cubrir amount × 1.01 |
| Tiempo de entrega | ~10 minutos después de que la tx de Arbitrum confirme |
| Receptor del puente | 0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7 |
| userId | Dirección de la wallet de control (del sign-in), NO la wallet gestionada |
Códigos de Error HL
| Código | Error | Causa |
|---|---|---|
| 101 | Parámetros faltantes | computedData no está en el cuerpo de la solicitud |
| 102 | chainId inválido | chainId no es 42161 |
| 102 | Parámetros inválidos | Nonce ya usado, o token no soportado |
| 103 | No autorizado | Falló la verificación de firma — revisa los tipos ABI (uint64!), userId, y que estés firmando con la clave de sesión registrada durante el sign-in |
| — | Saldo insuficiente | La wallet gestionada no tiene suficiente USDC + comisión en Arbitrum |
| — | Monto demasiado bajo | Monto < 10 USDC |
Encabezados HTTP (Requeridos)
El backend está detrás de Cloudflare. Las solicitudes DEBEN incluir encabezados similares a los de un navegador:
{
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
'Accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.9',
'Accept-Encoding': 'gzip, deflate, br',
'Connection': 'keep-alive',
'Authorization': 'Bearer <apiKey>', // NOT X-API-Key
}
ADVERTENCIA: Usar un User-Agent que no sea de navegador (p. ej.,
axios/1.xo cualquier cadena que contenga identificadores de bot) resultará en un 403 de Cloudflare "Access denied". El SDK maneja esto automáticamente.
Ejemplo Completo de Depósito HL
import {
GdexSkill,
GDEX_API_KEY_PRIMARY,
generateGdexSessionKeyPair,
buildGdexSignInMessage,
buildGdexSignInComputedData,
buildHlComputedData,
} from '@gemachdao/gdex-skill';
import { ethers } from 'ethers';
const apiKey = GDEX_API_KEY_PRIMARY;
const skill = new GdexSkill();
skill.loginWithApiKey(apiKey);
// 1. Generate session keypair
const { sessionPrivateKey, sessionKey } = generateGdexSessionKeyPair();
// 2. Sign in (control wallet signs the Terms message)
const controlWallet = new ethers.Wallet('0xYourPrivateKey');
const nonce = String(Date.now());
const message = buildGdexSignInMessage(controlWallet.address, nonce, sessionKey);
const signature = await controlWallet.signMessage(message);
const signInPayload = buildGdexSignInComputedData({
apiKey, userId: controlWallet.address, sessionKey, nonce,
signature: signature.replace(/^0x/, ''),
});
await skill.signInWithComputedData({
computedData: signInPayload.computedData, chainId: 42161,
});
// 3. Deposit USDC (amount in smallest unit, uint64 chainId is handled by SDK)
const computedData = buildHlComputedData({
action: 'hl_deposit',
apiKey,
walletAddress: controlWallet.address, // userId = control wallet
sessionPrivateKey,
actionParams: {
chainId: 42161,
tokenAddress: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
amount: '10000000', // 10 USDC in smallest unit (6 decimals)
},
});
const result = await skill.client.post('/v1/hl/deposit', { computedData });
// { hash: '0x...', isSuccess: true, amount: '10000000', message: 'Deposit successfully...' }
// Wait ~10 minutes for HyperLiquid to credit the deposit
Contribuciones
- Haz un fork del repositorio
- Crea una rama de funcionalidad
- Añade pruebas para la nueva funcionalidad
- Ejecuta
npm test && npm run build && npm run verify - Envía un pull request
Licencia
MIT © GemachDAO