| name | gdex-copy-trading |
| description | Copy trade setup — discover top wallets, create/manage copy trades, view transaction history, and browse supported DEXes. Solana only for write operations. |
GDEX: Copy Trading
Automatically mirror trades from top-performing Solana wallets. Includes wallet leaderboards, hot token gems, backed by a background process that copies buys/sells in real-time.
When to Use
- Browsing the top wallet leaderboard (by PnL or net profit)
- Discovering hot new tokens from top wallets
- Creating a copy trade to follow a specific trader
- Updating, toggling, or deleting a copy trade
- Viewing copy trade transaction history with PnL
- Listing supported DEXes for exclusion
Prerequisites
@gdexsdk/gdex-skill installed
- For discovery:
loginWithApiKey() only
- For read (list/tx_list): Full sign-in with session key
- For write (create/update): Full sign-in + computedData
Auth Tiers
| Tier | Endpoints | Auth Needed |
|---|
| Discovery | wallets, custom_wallets, gems, dexes_list, top_traders | API key only |
| Read | list, tx_list | Session-key auth (userId + encrypted data) |
| Write | create, update | computedData (ABI-encode + sign + AES-encrypt) |
Write operations are Solana-only. All create/update calls reject non-Solana chain IDs.
Discovery Endpoints (No Auth)
Top Wallets by PnL
const wallets = await skill.getCopyTradeWallets();
Top Wallets by Net Received
const custom = await skill.getCopyTradeCustomWallets();
CopyTradeWallet Response Shape
interface CopyTradeWallet {
_id: string;
chainId: number;
address: string;
lastTxTimestamp: number;
receivedMinusSpent: number;
spent: number;
lastCalculateUnrealizedPnl: number;
totalPnl: number;
unrealizedValue: number;
received: number;
}
Hot Token Gems
const gems = await skill.getCopyTradeGems();
Supported DEXes
const dexes = await skill.getCopyTradeDexes(622112261);
Live DEX list (Solana):
| # | DEX | Program ID |
|---|
| 1 | pumpfun | 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P |
| 2 | pumpswap | pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA |
| 3 | raydium | 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8 |
| 4 | raydiumCpmm | CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C |
| 5 | meteoraDlmm | LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo |
Read Endpoints (Session-Key Auth)
Require userId and data (AES-encrypted session key from buildGdexUserSessionData).
List User's Copy Trades
import { buildGdexUserSessionData } from '@gdexsdk/gdex-skill';
const data = buildGdexUserSessionData(sessionKey, apiKey);
const list = await skill.getCopyTradeList({ userId, data });
CopyTradeConfig Shape
interface CopyTradeConfig {
copyTradeId: string;
copyTradeName: string;
buyMode: number;
chainId: number;
isActive: boolean;
userId: string;
userWallet: string;
traderWallet: string;
lossPercent: number;
profitPercent: number;
gasPrice: string;
copyBuyFixedAmount: string;
copyBuyPercent: number;
isBuyExistingToken: boolean;
copySell: boolean;
excludedProgramIds: string[];
excludedDexNumbers: number[];
txCount?: number;
lastTxTimestamp?: number;
}
Transaction History
const txList = await skill.getCopyTradeTxList({ userId, data });
Each CopyTradeTx includes:
isBuy, priceUsd, boughtPrice, pnlPercentage
tokenInfo: { address, symbol, name, decimals, dexId, marketCap, logoUrl }
Write Endpoints (ComputedData Auth, Solana Only)
Create a Copy Trade
await skill.createCopyTrade({
apiKey,
userId,
sessionPrivateKey,
chainId: 622112261,
traderWallet: 'SolanaWalletAddress',
copyTradeName: 'My Alpha Trader',
buyMode: 1,
copyBuyAmount: '0.5',
lossPercent: '50',
profitPercent: '100',
copySell: true,
isBuyExistingToken: true,
excludedDexNumbers: [],
});
Update a Copy Trade
await skill.updateCopyTrade({
apiKey,
userId,
sessionPrivateKey,
chainId: 622112261,
copyTradeId: 'a1b2c3...',
traderWallet: 'SolanaWalletAddress',
copyTradeName: 'Updated Name',
buyMode: 2,
copyBuyAmount: '50',
lossPercent: '30',
profitPercent: '200',
copySell: true,
});
Delete a Copy Trade (isChangeStatus)
⚠️ WARNING: isChangeStatus permanently DELETES the trade. It does NOT toggle isActive.
await skill.updateCopyTrade({
...existingParams,
isChangeStatus: true,
});
Delete a Copy Trade (isDelete)
await skill.updateCopyTrade({
...existingParams,
isDelete: true,
});
Backend Validation Rules
- Solana only: chainId must be the Solana chain ID (622112261)
- Valid wallet: traderWallet must be a valid Solana address
- TP/SL: lossPercent > 0 and < 100, profitPercent > 0
- buyMode 2: percentage must be > 0 and <= 100
- No duplicates: Can't copy the same wallet+chain+user twice
- Max limit: Backend enforces max copy trades per user
- Circular dependency: Prevents A→B→C→A copy chains (checked to depth 50)
How Copies Execute
Trades are NOT executed at API call time. A background process monitors tracked wallets in real-time:
- Detects trader buy/sell transactions
- Checks excluded DEXes and deduplication
- Calculates buy amount (fixed or percentage)
- Executes the copy trade
- Places automatic TP/SL orders based on your settings
Example: Full Copy Trading Flow
import {
GdexSkill,
buildGdexUserSessionData,
generateGdexSessionKeyPair,
buildGdexSignInMessage,
buildGdexSignInComputedData,
} from '@gdexsdk/gdex-skill';
import { ethers } from 'ethers';
const skill = new GdexSkill();
skill.loginWithApiKey(apiKey);
const wallet = ethers.Wallet.fromPhrase(mnemonic);
const { sessionPrivateKey, sessionKey } = generateGdexSessionKeyPair();
const nonce = String(Date.now());
const msg = buildGdexSignInMessage(wallet.address, nonce, sessionKey);
const sig = await wallet.signMessage(msg);
const payload = buildGdexSignInComputedData({ apiKey, userId: wallet.address, sessionKey, nonce, signature: sig });
await skill.signInWithComputedData({ computedData: payload.computedData, chainId: 1 });
const data = buildGdexUserSessionData(sessionKey, apiKey);
const userId = wallet.address.toLowerCase();
const wallets = await skill.getCopyTradeWallets();
const best = wallets[0];
console.log(`Top wallet: ${best.address}, PnL: $${best.totalPnl.toFixed(2)}`);
const { dexes } = await skill.getCopyTradeDexes(622112261);
await skill.createCopyTrade({
apiKey,
userId,
sessionPrivateKey,
chainId: 622112261,
traderWallet: best.address,
copyTradeName: `Top PnL: ${best.address.slice(0, 8)}`,
buyMode: 1,
copyBuyAmount: '0.1',
lossPercent: '50',
profitPercent: '100',
copySell: true,
});
const list = await skill.getCopyTradeList({ userId, data });
for (const ct of list.allCopyTrades) {
console.log(`${ct.copyTradeName}: active=${ct.isActive}, ${ct.txCount ?? 0} trades`);
}
Autonomous Agent Notes (Live-Tested)
- All 4 discovery endpoints work with API key only (E2E verified):
getCopyTradeWallets(), getCopyTradeCustomWallets(), getCopyTradeGems(), getCopyTradeDexes().
getCopyTradeGems() may return empty array — this is normal (cached 20 seconds, depends on hot wallet activity).
- Sign-in for Solana copy trading must use
chainId: 622112261 (Solana), not chainId: 1 (EVM). This is the opposite of HL perp copy trading.
- Both
isDelete and isChangeStatus permanently DELETE the copy trade. There is NO way to pause/toggle — you must delete and recreate.
- Boolean fields in ABI use
'' (empty string) for false and '1' for true. The string '0' is truthy and WILL trigger deletion.
copySell: true means the copy will also mirror sell transactions, not just buys.
Related Skills
- gdex-authentication — Auth setup and sign-in required for read/write
- gdex-token-discovery — Top trader rankings (
getTopTraders)
- gdex-portfolio — Monitor portfolio including copied positions
- gdex-spot-trading — Understand the trades being copied