一键导入
gdex-limit-orders
Limit buy, limit sell, update/delete, and list limit orders via managed-custody encrypted payloads
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Limit buy, limit sell, update/delete, and list limit orders via managed-custody encrypted payloads
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
HyperLiquid perpetual futures — open/close positions, set leverage, place market and limit orders with TP/SL, and manage open orders
CSS theming system for GDEX trading UIs — dark/light modes, trading colors, responsive breakpoints, and Tailwind CSS configuration
Troubleshoot GDEX SDK errors — error codes, encryption debugging, chain-specific quirks, HL gotchas, and copy trade pitfalls
Start here — GDEX overview, architecture, supported chains, available skills, and quickstart for cross-chain DeFi trading via managed-custody wallets
HyperLiquid HIP-3 outcome / event markets — list markets, place outcome orders, and manage outcome positions
Deposit and withdraw USDC to/from HyperLiquid for perpetual futures trading — constraints, amounts, and managed-custody flow
| name | gdex-limit-orders |
| description | Limit buy, limit sell, update/delete, and list limit orders via managed-custody encrypted payloads |
Create limit buy/sell orders that trigger when a token reaches your target price. Uses the same managed-custody encryption flow as spot trades (ABI-encoded → signed → AES-encrypted computedData).
Limit orders use separate endpoints for buy vs sell (NOT a single create endpoint):
| Action | Endpoint | SDK Method |
|---|---|---|
| List orders | GET /v1/orders | getLimitOrders() |
| Buy when price drops | POST /v1/limit_buy | limitBuy() |
| Sell when price rises/drops | POST /v1/limit_sell | limitSell() |
| Update or delete order | POST /v1/update_order | updateOrder() |
There is NO
/v1/orders/createor/v1/orders/cancelendpoint.
limitBuy()limitSell()updateOrder({ isDelete: true })updateOrder()getLimitOrders()@gdexsdk/gdex-skill installedloginWithApiKey() — see gdex-authenticationconfig.chains[chainId].minLimitOrder (typically 0.01 native token)import { GdexSkill, GDEX_API_KEY_PRIMARY } from '@gdexsdk/gdex-skill';
const skill = new GdexSkill();
skill.loginWithApiKey(GDEX_API_KEY_PRIMARY);
const result = await skill.limitBuy({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD', // control wallet
sessionPrivateKey: '<session-private-key-hex>',
chainId: 622112261, // Solana
tokenAddress: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', // WIF
amount: '10000000', // 0.01 SOL in lamports
triggerPrice: '0.50', // trigger when WIF price ≤ $0.50
profitPercent: '50', // take profit at 50% gain (optional)
lossPercent: '25', // stop loss at 25% loss (optional)
});
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | API key for AES encryption |
userId | string | Yes | Control wallet address (NOT managed) |
sessionPrivateKey | string | Yes | Session key from sign-in |
chainId | number | Yes | Numeric chain ID (e.g. 622112261 for Solana) |
tokenAddress | string | Yes | Token to buy |
amount | string | Yes | Native token to spend (raw units: wei/lamports) |
triggerPrice | string | Yes | USD price to trigger the buy |
profitPercent | string | No | Take-profit % above trigger ("0" to skip) |
lossPercent | string | No | Stop-loss % below trigger ("0" to skip) |
ABI schema: ['string','string','string','uint256','uint256','string'] = [tokenAddress, amount, triggerPrice, profitPercent, lossPercent, nonce]
Signature: limit_buy-{userId}-{data}
CRITICAL (Live-Tested):
profitPercentandlossPercentMUST be ABI-encoded asuint256, NOTstring. The backend decodes them as uint256 and validates0-100range. Usingstringtype produces ABI byte-offsets (e.g. 192) that fail the range check with"lossPercent must be between 0 and 100". The SDK handles this correctly — only matters if encoding manually.
// Sell WIF when price reaches $999.99 (take-profit)
const result = await skill.limitSell({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
sessionPrivateKey: '<session-private-key-hex>',
chainId: 622112261,
tokenAddress: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', // WIF
amount: '100000', // token amount in raw units
triggerPrice: '999.99', // trigger when WIF price reaches $999.99
});
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | API key for AES encryption |
userId | string | Yes | Control wallet address |
sessionPrivateKey | string | Yes | Session key from sign-in |
chainId | number | Yes | Numeric chain ID |
tokenAddress | string | Yes | Token to sell |
amount | string | Yes | Token amount to sell (raw units) |
triggerPrice | string | Yes | USD price to trigger the sell |
ABI schema: ['string','string','string','string'] = [tokenAddress, amount, triggerPrice, nonce]
Signature: limit_sell-{userId}-{data}
The backend auto-classifies as take-profit (trigger > current price) or stop-loss (trigger < current price).
// Delete an order
await skill.updateOrder({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
sessionPrivateKey: '<session-private-key-hex>',
chainId: 622112261,
orderId: '64-char-hex-order-id',
isDelete: true,
});
// Update an order's trigger price
await skill.updateOrder({
apiKey: GDEX_API_KEY_PRIMARY,
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
sessionPrivateKey: '<session-private-key-hex>',
chainId: 622112261,
orderId: '64-char-hex-order-id',
triggerPrice: '1.50',
amount: '10000000',
});
| Parameter | Type | Required | Description |
|---|---|---|---|
apiKey | string | Yes | API key for AES encryption |
userId | string | Yes | Control wallet address |
sessionPrivateKey | string | Yes | Session key from sign-in |
chainId | number | Yes | Numeric chain ID |
orderId | string | Yes | Order ID from getLimitOrders() |
amount | string | No | New amount (raw units) |
triggerPrice | string | No | New trigger price (USD) |
profitPercent | string | No | New take-profit % (buy orders) |
lossPercent | string | No | New stop-loss % (buy orders) |
isDelete | boolean | No | Set true to cancel/delete the order |
ABI schema: ['string','string','string','uint256','uint256','string','string'] = [orderId, amount, triggerPrice, profitPercent, lossPercent, nonce, isDelete]
Signature: update_order-{userId}-{data}
CRITICAL: Same as
limit_buy—profitPercentandlossPercentareuint256, notstring.
const { count, orders } = await skill.getLimitOrders({
userId: '0x53D029a671bd1CF61a2fB1F4F6e4bD830BFBb2eD',
data: encryptedSessionKey, // from buildGdexUserSessionData()
chainId: 622112261,
});
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string | Yes | Control wallet address |
data | string | Yes | Encrypted session key (from buildGdexUserSessionData) |
chainId | number | Yes | Numeric chain ID |
interface LimitOrder {
orderId: string; // unique 64-char hex ID
fromToken: string; // token being sold
toToken: string; // token being bought
isBuyLimit: boolean; // true = buy limit, false = sell limit
price: number; // trigger price in USD
takeProfitPrice: number; // TP price (0 = disabled)
stopLossPrice: number; // SL price (0 = disabled)
fromTokenAmount: string; // amount in raw units
toTokenAmount: string; // computed output amount
walletAddress: string; // managed wallet address
userId: string; // control wallet address
chainId: number; // numeric chain ID
pairAddress: string; // DEX pair address
isActive: boolean; // still pending?
isCancelled?: boolean; // was cancelled?
expiredAt: number; // expiry Unix timestamp
profitPercent?: string; // TP % (buy orders)
lossPercent?: string; // SL % (buy orders)
}
Orders are filled by background processes that monitor prices via NATS:
tokenPrice <= order.pricetokenPrice >= takeProfitPricetokenPrice <= stopLossPrice| Code | Meaning |
|---|---|
| 101 | Missing required parameters |
| 102 | Invalid nonce or params |
| 103 | Unauthorized (wrong userId or session key) |
| 1011 | Invalid/expired order |
| 1012 | Order expired |
| 1031 | Unsupported token |
| 400 | Insufficient balance (need ≥ minLimitOrder in native token) |
For backward compatibility, older method names still work:
createLimitOrder() → calls limitBuy()cancelLimitOrder() → calls updateOrder({ isDelete: true })This exact sequence was tested end-to-end and succeeded:
// 1. List existing orders
const orders = await skill.getLimitOrders({ userId, data, chainId: 622112261 });
// 2. Create a limit buy order
const result = await skill.limitBuy({
apiKey: GDEX_API_KEY_PRIMARY,
userId: controlAddress, // MUST be control address, lowercase
sessionPrivateKey,
chainId: 622112261, // Solana
tokenAddress: 'EKpQGSJtjMFqKZ9KQanSqYXRcF8fBopzLHYxdM65zcjm', // WIF
amount: '1000000', // ~0.001 SOL in lamports (raw units)
triggerPrice: '0.0001', // trigger when price drops to $0.0001
profitPercent: '50', // 50% take-profit
lossPercent: '30', // 30% stop-loss
});
// → { isSuccess: true, message: "Order created successfully", order: {...} }
// 3. Verify order appears in list
const updated = await skill.getLimitOrders({ userId, data, chainId: 622112261 });
// 4. Cancel the order
await skill.updateOrder({
apiKey, userId, sessionPrivateKey,
chainId: 622112261,
orderId: result.order.orderId,
isDelete: true,
});
amount must be in raw units (lamports for Solana, wei for EVM) — NOT floatprofitPercent and lossPercent are mandatory for limit_buy (both must be > 0)profitPercent and lossPercent must be valid 0-100 range (ABI-encoded as uint256)userId must be the control wallet address, lowercasetriggerPrice is in USD (string)The backend enforces config.chains[chainId].minLimitOrder per chain. For Solana, this is approximately 0.001 SOL (1000000 lamports). Going below returns "Insufficient balance".
To cancel, use updateOrder({ isDelete: true }). There is no separate cancel endpoint. The cancelLimitOrder() alias calls this internally.
| Error | Cause | Fix |
|---|---|---|
lossPercent must be between 0 and 100 | ABI encoding used string type instead of uint256 | SDK handles this correctly; only matters for manual encoding |
Insufficient balance | Amount too small or managed wallet underfunded | Increase amount or fund the managed Solana wallet |
Order not found (on update/delete) | Wrong orderId or order already filled/expired | Refresh order list with getLimitOrders() first |
Invalid nonce | Reused or stale nonce | Generate fresh: String(Date.now()) |