Authentication
Complete guide to Web3 signature authentication, agent keys, and security best practices.
Authentication Overview
AsterDex uses Web3 signature-based authentication for secure, gasless trading. This system allows you to trade without exposing your private keys to our servers.
Parameters
Agent API Wallet Setup (REQUIRED)
Required for ALL authenticated API calls - Browser AND Server
Step-by-Step Guide
-
1
Navigate to API Wallet Dashboard:
-
2
Connect Wallet: Click "Connect Wallet" and approve in MetaMask.
-
3
Create Agent: Click the "Authorize new API wallet" button.
-
4
Sign Authorization: Approve the signature request in MetaMask.
-
5
CRITICAL - Save Immediately:
Copy your
Agent Private KeyandAgent Address. You will NOT see the private key again!
đ Key Types Explained
| Key Type | What It Is | When to Use |
|---|---|---|
| User Wallet | Your main MetaMask wallet (0x...) | Passed as user parameter |
| Agent Wallet | Authorized sub-key for trading | Passed as signer parameter |
| Agent Private Key | Secret key for signing requests | Used to generate signature |
đ Required Parameters (All Authenticated Requests)
Browser Authentication (MetaMask)
Complete guide for implementing Web3 authentication in your web application using MetaMask or other browser wallets.
Parameters
đą Browser Flow Step-by-Step
-
1
Connect Wallet: Request user's wallet address via
ethereum.request() -
2
Build EIP-712 Message: Create typed data structure with order details
-
3
Request Signature: User signs in MetaMask (no gas fees!)
-
4
Submit to API: Send signed message to AsterDex API
đģ What You Need
- â MetaMask installed in browser
- â Basic JavaScript knowledge
- â Web3 library (ethers.js or web3.js)
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/api/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signSpotRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// Manual Construction (Strict verified order from test_spot_standalone_cycle.js)
let paramString = '';
if (params.symbol) paramString += `symbol=${params.symbol}`;
if (params.side) paramString += `&side=${params.side}`;
if (params.type) paramString += `&type=${params.type}`;
if (params.quantity) paramString += `&quantity=${params.quantity}`;
if (params.quoteOrderQty) paramString += `"eOrderQty=${params.quoteOrderQty}`;
if (params.price) paramString += `&price=${params.price}`;
if (params.timeInForce) paramString += `&timeInForce=${params.timeInForce}`;
if (params.orderId) paramString += `&orderId=${params.orderId}`;
if (paramString.startsWith('&')) paramString = paramString.substring(1);
paramString += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
console.log(`đ Signing String (Fixed): ${paramString}`);
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: paramString });
return { ...params, nonce, user: CONFIG.USER_WALLET, signer: CONFIG.AGENT_WALLET, signature };
}
async function placeLimitBuy() {
console.log("đ Placing Spot LIMIT BUY...");
// LIMIT BUY: Quantity (Base) + Price
// 1. Fetch Price
let currentPrice = 0.5;
try {
const pRes = await axios.get('https://www.asterdex-testnet.com/api/v3/ticker/price?symbol=ASTERUSDT');
currentPrice = parseFloat(pRes.data.price);
console.log(`âšī¸ Current Price: ${currentPrice}`);
} catch (e) { }
const limitPrice = (currentPrice * 0.95).toFixed(4); // 5% below market
const quantity = (10 / limitPrice).toFixed(1); // Buy ~10 USDT worth (Minimum >5)
const params = {
symbol: 'ASTERUSDT',
side: 'BUY',
type: 'LIMIT',
quantity: quantity,
price: limitPrice,
timeInForce: 'GTC'
};
const signedBody = await signSpotRequest(params);
const body = new URLSearchParams(signedBody);
try {
const res = await axios.post(`${CONFIG.BASE_URL}/order`, body, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
console.log(`â
Limit Buy Placed: ID ${res.data.orderId}`);
} catch (e) {
console.error(`â Failed:`, e.response?.data || e.message);
}
}
placeLimitBuy();
Server-Side Authentication (Agent Keys)
Complete guide for implementing programmatic authentication using Agent Keys for automated trading bots and backend applications.
Parameters
âī¸ Server Flow Step-by-Step
-
1
Generate Agent Key:Go to AsterDex API Wallet.
- Connect your MetaMask wallet.
- Click the "Authorize new API wallet" button.
- Sign the transaction in MetaMask (this authorizes the agent).
- Copy your Agent Private Key and Agent Address immediately. You won't be able to see the private key again.
-
2
Store Securely:
Save these credentials in your environment variables. Never hardcode them.
-
3
Build & Sign:
Use the Agent Private Key to sign requests programmatically. See the code examples below for exact implementation.
- âĸ Never commit private keys to Git repositories
- âĸ Use environment variables or secret management services
- âĸ Rotate agent keys periodically
- âĸ Revoke immediately if compromised
đ ī¸ Language Support
Complete examples available for all major languages:
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/api/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signSpotRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// Alphabetical Sort (Spot Standard)
const sortedKeys = Object.keys(params).sort();
let paramString = sortedKeys.map(key => `${key}=${params[key]}`).join('&');
paramString += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: paramString });
return { ...params, nonce, user: CONFIG.USER_WALLET, signer: CONFIG.AGENT_WALLET, signature };
}
async function getAccountInfo() {
console.log("\n--- GET Spot Account Info ---");
// Spot Account Endpoint REQUIRES 'timestamp'
const params = {
timestamp: Date.now().toString()
};
const signedParams = await signSpotRequest(params);
const qs = new URLSearchParams(signedParams).toString();
try {
// GET Request -> No Content-Type header
const res = await axios.get(`${CONFIG.BASE_URL}/account?${qs}`);
console.log("â
Balance Data Retrieved:");
const balances = res.data.balances.filter(b => parseFloat(b.free) > 0 || parseFloat(b.locked) > 0);
balances.forEach(b => console.log(` - ${b.asset}: Free ${b.free} / Locked ${b.locked}`));
} catch (e) {
console.error(`â Failed:`, e.response?.data || e.message);
}
}
getAccountInfo();
Signature Technical Details (EIP-712)
Deep dive into the EIP-712 Typed Data signature standard used for secure, gasless Agent authentication.
Parameters
đ EIP-712 Specification
All Server/Agent requests must be signed using the EIP-712 standard. This ensures the user knows exactly what they are signing (if manual) and prevents replay attacks.
{
name: "AsterSignTransaction",
version: "1",
chainId: 714,
verifyingContract: "0x0000000000000000000000000000000000000000"
}
{
EIP712Domain: [
{ name: "name", type: "string" },
{ name: "version", type: "string" },
{ name: "chainId", type: "uint256" },
{ name: "verifyingContract", type: "address" }
],
Message: [
{ name: "msg", type: "string" }
]
}
msg field is a URL-encoded string of parameters sorted by importance (but typically Order keys first).
symbol=BTCUSDT&side=BUY&type=LIMIT&quantity=0.001&price=90000&timeInForce=GTC&nonce=172...&user=0xUser...&signer=0xAgent...
user is your Main Wallet. signer is the Agent Key signing this request.
đ Implementation
See the Python or JavaScript tabs above for ready-to-use signing functions (sign_futures_request) that implement this exact specification.
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/fapi/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signFuturesRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// STRICT LIST
const STRICT_KEYS = ['symbol', 'side', 'type', 'quantity', 'price', 'timeInForce', 'leverage', 'orderId'];
let val = "";
STRICT_KEYS.forEach(k => { if (params[k]) val += `${val ? '&' : ''}${k}=${params[k]}`; });
val += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: val });
return `${CONFIG.BASE_URL}/order?${val}&signature=${signature}`;
}
async function run() {
console.log("đ Placing Futures LIMIT BUY...");
const params = {
symbol: 'BTCUSDT',
side: 'BUY',
type: 'LIMIT',
quantity: '0.001',
price: '90000',
timeInForce: 'GTC'
};
try {
const url = await signFuturesRequest(params);
const res = await axios.post(url);
console.log(`â
Success: ${res.data.orderId}`);
} catch (e) { console.error(e.response?.data); }
}
run();
Spot Trading API
Execute secure, gasless trades on the Spot market. Requires Agent Authentication.
Account Information
Get current account balances and permissions.
Parameters
Requires standard authentication (nonce, signature, user, signer).
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/api/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signSpotRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// Alphabetical Sort (Spot Standard)
const sortedKeys = Object.keys(params).sort();
let paramString = sortedKeys.map(key => `${key}=${params[key]}`).join('&');
paramString += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: paramString });
return { ...params, nonce, user: CONFIG.USER_WALLET, signer: CONFIG.AGENT_WALLET, signature };
}
async function getAccountInfo() {
console.log("\n--- GET Spot Account Info ---");
// Spot Account Endpoint REQUIRES 'timestamp'
const params = {
timestamp: Date.now().toString()
};
const signedParams = await signSpotRequest(params);
const qs = new URLSearchParams(signedParams).toString();
try {
// GET Request -> No Content-Type header
const res = await axios.get(`${CONFIG.BASE_URL}/account?${qs}`);
console.log("â
Balance Data Retrieved:");
const balances = res.data.balances.filter(b => parseFloat(b.free) > 0 || parseFloat(b.locked) > 0);
balances.forEach(b => console.log(` - ${b.asset}: Free ${b.free} / Locked ${b.locked}`));
} catch (e) {
console.error(`â Failed:`, e.response?.data || e.message);
}
}
getAccountInfo();
Place Order
Place a new limit or market order.
Parameters
| Param | Required | Description |
|---|---|---|
| symbol | YES | BTCUSDT |
| side | YES | BUY / SELL |
| type | YES | LIMIT / MARKET |
| price | LIMIT | Price |
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/api/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signSpotRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// Manual Construction (Strict verified order from test_spot_standalone_cycle.js)
let paramString = '';
if (params.symbol) paramString += `symbol=${params.symbol}`;
if (params.side) paramString += `&side=${params.side}`;
if (params.type) paramString += `&type=${params.type}`;
if (params.quantity) paramString += `&quantity=${params.quantity}`;
if (params.quoteOrderQty) paramString += `"eOrderQty=${params.quoteOrderQty}`;
if (params.price) paramString += `&price=${params.price}`;
if (params.timeInForce) paramString += `&timeInForce=${params.timeInForce}`;
if (params.orderId) paramString += `&orderId=${params.orderId}`;
if (paramString.startsWith('&')) paramString = paramString.substring(1);
paramString += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
console.log(`đ Signing String (Fixed): ${paramString}`);
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: paramString });
return { ...params, nonce, user: CONFIG.USER_WALLET, signer: CONFIG.AGENT_WALLET, signature };
}
async function placeLimitBuy() {
console.log("đ Placing Spot LIMIT BUY...");
// LIMIT BUY: Quantity (Base) + Price
// 1. Fetch Price
let currentPrice = 0.5;
try {
const pRes = await axios.get('https://www.asterdex-testnet.com/api/v3/ticker/price?symbol=ASTERUSDT');
currentPrice = parseFloat(pRes.data.price);
console.log(`âšī¸ Current Price: ${currentPrice}`);
} catch (e) { }
const limitPrice = (currentPrice * 0.95).toFixed(4); // 5% below market
const quantity = (10 / limitPrice).toFixed(1); // Buy ~10 USDT worth (Minimum >5)
const params = {
symbol: 'ASTERUSDT',
side: 'BUY',
type: 'LIMIT',
quantity: quantity,
price: limitPrice,
timeInForce: 'GTC'
};
const signedBody = await signSpotRequest(params);
const body = new URLSearchParams(signedBody);
try {
const res = await axios.post(`${CONFIG.BASE_URL}/order`, body, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});
console.log(`â
Limit Buy Placed: ID ${res.data.orderId}`);
} catch (e) {
console.error(`â Failed:`, e.response?.data || e.message);
}
}
placeLimitBuy();
Cancel Order
Cancel an active order.
Parameters
orderId or origClientOrderId required.
// Cancel Spot Order
// Endpoint: /api/v3/order
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/api/v3/order';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT',
orderId: 123456
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Cancel All Orders
Cancel all open orders on a symbol.
Parameters
| Param | Required | Description |
|---|---|---|
| symbol | YES | BTCUSDT |
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/api/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signSpotRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// Manual Construction (Strict verified order from test_spot_standalone_cycle.js)
let paramString = '';
if (params.symbol) paramString += `symbol=${params.symbol}`;
if (params.side) paramString += `&side=${params.side}`;
if (params.type) paramString += `&type=${params.type}`;
if (params.quantity) paramString += `&quantity=${params.quantity}`;
if (params.quoteOrderQty) paramString += `"eOrderQty=${params.quoteOrderQty}`;
if (params.price) paramString += `&price=${params.price}`;
if (params.timeInForce) paramString += `&timeInForce=${params.timeInForce}`;
if (params.orderId) paramString += `&orderId=${params.orderId}`;
if (paramString.startsWith('&')) paramString = paramString.substring(1);
paramString += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: paramString });
return { ...params, nonce, user: CONFIG.USER_WALLET, signer: CONFIG.AGENT_WALLET, signature };
}
async function cancelAllSpotOrders() {
console.log("đ Spot Cancel All (Loop Strategy)...");
// 1. Fetch Open Orders
console.log("1. Fetching open orders...");
const openParams = { symbol: 'ASTERUSDT' }; // No timestamp needed for openOrders usually, check master guide.
// Master Guide says: "Open Orders ... GET symbol + Auth". No timestamp.
const signedOpen = await signSpotRequest(openParams);
const qs = new URLSearchParams(signedOpen).toString();
try {
const res = await axios.get(`${CONFIG.BASE_URL}/openOrders?${qs}`);
const orders = res.data;
console.log(` Found ${orders.length} open orders.`);
// 2. Loop and Cancel
for (const order of orders) {
console.log(` Cancelling ${order.orderId}...`);
const cancelParams = { symbol: 'ASTERUSDT', orderId: order.orderId };
const signedCancel = await signSpotRequest(cancelParams);
const cancelQs = new URLSearchParams(signedCancel).toString();
await axios.delete(`${CONFIG.BASE_URL}/order?${cancelQs}`);
console.log(` â
Cancelled ${order.orderId}`);
}
console.log("â
All Orders Cancelled.");
} catch (e) {
console.error(`â Failed:`, e.response?.data || e.message);
}
}
cancelAllSpotOrders();
Open Orders
Get all open orders on a symbol.
Parameters
Symbol required.
// Get Open Spot Orders
// Endpoint: /api/v3/openOrders
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/api/v3/openOrders';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT'
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Order History
Get all account orders; active, canceled, or filled.
Parameters
Symbol required.
// Get Spot Order History
// Endpoint: /api/v3/allOrders
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/api/v3/allOrders';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT'
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Futures Trading API
High-performance perpetual futures trading. Supports leverage, stop-loss, and advanced order types.
Account Information
Get futures account details including positions, margin balance, and unrealized profit.
Parameters
Requires standard authentication.
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/fapi/v3',
USER_WALLET: 'YOUR_USER_WALLET',
AGENT_WALLET: 'YOUR_AGENT_WALLET',
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY'
};
async function signFuturesRequest(endpoint) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
const val = `nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: val });
return `${CONFIG.BASE_URL}${endpoint}?${val}&signature=${signature}`;
}
async function run() {
console.log("đ Futures Account Data...");
try {
const url = await signFuturesRequest('/account');
const res = await axios.get(url);
console.log(`â
Balance: ${res.data.totalWalletBalance}`);
} catch (e) { console.error(e.response?.data || e.message); }
}
run();
Place Order
Place a new futures order. Supports STOP, TAKE_PROFIT, and HIDDEN orders.
Parameters
| Param | Required | Description |
|---|---|---|
| symbol | YES | BTCUSDT |
| side | YES | BUY / SELL |
| type | YES | LIMIT / MARKET / STOP / TAKE_PROFIT |
| timeInForce | NO | GTC / IOC / FOK / HIDDEN |
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/fapi/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signFuturesRequest(params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// STRICT LIST
const STRICT_KEYS = ['symbol', 'side', 'type', 'quantity', 'price', 'timeInForce', 'leverage', 'orderId'];
let val = "";
STRICT_KEYS.forEach(k => { if (params[k]) val += `${val ? '&' : ''}${k}=${params[k]}`; });
val += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: val });
return `${CONFIG.BASE_URL}/order?${val}&signature=${signature}`;
}
async function run() {
console.log("đ Placing Futures LIMIT BUY...");
const params = {
symbol: 'BTCUSDT',
side: 'BUY',
type: 'LIMIT',
quantity: '0.001',
price: '90000',
timeInForce: 'GTC'
};
try {
const url = await signFuturesRequest(params);
const res = await axios.post(url);
console.log(`â
Success: ${res.data.orderId}`);
} catch (e) { console.error(e.response?.data); }
}
run();
Cancel Order
Cancel an active order.
Parameters
orderId or origClientOrderId required.
// Cancel Futures Order
// Endpoint: /fapi/v3/order
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/fapi/v3/order';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT',
orderId: 123456
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Cancel All Orders
Cancel all open orders on a symbol.
Parameters
Symbol required.
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/fapi/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signFuturesRequest(endpoint, params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// STRICT LIST
const STRICT_KEYS = ['symbol', 'side', 'type', 'quantity', 'price', 'timeInForce', 'leverage', 'orderId'];
let val = "";
STRICT_KEYS.forEach(k => { if (params[k]) val += `${val ? '&' : ''}${k}=${params[k]}`; });
val += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: val });
return `${CONFIG.BASE_URL}${endpoint}?${val}&signature=${signature}`;
}
async function run() {
console.log("đ Futures CANCEL ALL...");
const params = { symbol: 'BTCUSDT' };
try {
const url = await signFuturesRequest('/allOpenOrders', params);
const res = await axios.delete(url);
console.log(`â
Success:`, res.data);
} catch (e) { console.error(e.response?.data); }
}
run();
Open Orders
Get all open orders on a symbol.
Parameters
Symbol required.
// Get Open Futures Orders
// Endpoint: /fapi/v3/openOrders
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/fapi/v3/openOrders';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT'
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Algorithmic Orders
Place advanced algorithmic orders like TWAP or VP.
Parameters
Advanced parameters required (strategyType, urgency, etc).
const { ethers } = require('ethers');
const axios = require('axios');
const CONFIG = {
BASE_URL: 'https://www.asterdex-testnet.com/fapi/v3',
USER_WALLET: 'YOUR_USER_WALLET', // Main Wallet
AGENT_WALLET: 'YOUR_AGENT_WALLET', // Agent Wallet
AGENT_PRIVATE_KEY: 'YOUR_AGENT_PRIVATE_KEY' // Agent Key
};
async function signAlgoRequest(endpoint, params) {
const wallet = new ethers.Wallet(CONFIG.AGENT_PRIVATE_KEY);
const nonce = (Date.now() * 1000).toString();
// 1. Standard Strict List
const STRICT_KEYS = [
'symbol', 'side', 'type', 'quantity', 'price',
'timeInForce', 'leverage', 'orderId'
];
let paramString = "";
STRICT_KEYS.forEach(key => {
if (params[key] !== undefined && params[key] !== null) {
paramString += `${paramString ? '&' : ''}${key}=${params[key]}`;
}
});
// 2. DYNAMIC ALGO PARAM: 'stopPrice'
// This MUST be appended if present, otherwise signature fails for SL/TP.
if (params.stopPrice) {
paramString += `&stopPrice=${params.stopPrice}`;
}
paramString += `&nonce=${nonce}&user=${CONFIG.USER_WALLET}&signer=${CONFIG.AGENT_WALLET}`;
console.log(`đ Signing String: ${paramString}`);
const domain = { name: "AsterSignTransaction", version: "1", chainId: 714, verifyingContract: "0x0000000000000000000000000000000000000000" };
const types = { Message: [{ name: "msg", type: "string" }] };
const signature = await wallet.signTypedData(domain, types, { msg: paramString });
return `${CONFIG.BASE_URL}${endpoint}?${paramString}&signature=${signature}`;
}
async function placeAlgoOrder(type, stopPrice, side) {
console.log(`\n--- Place ${type} @ ${stopPrice} ---`);
const params = {
symbol: 'BTCUSDT',
side: side,
type: type,
quantity: '0.001',
stopPrice: stopPrice,
timeInForce: 'GTC'
};
const url = await signAlgoRequest('/order', params);
try {
const res = await axios.post(url);
console.log(`â
Success: Order ID ${res.data.orderId}`);
} catch (e) {
console.error(`â Failed:`, e.response?.data);
}
}
async function run() {
// Note: You need an open position for SL/TP ReduceOnly to make sense usually.
// This script assumes you have a position or allows open orders.
// Stop Loss
await placeAlgoOrder('STOP_MARKET', '90000', 'SELL');
// Take Profit
await placeAlgoOrder('TAKE_PROFIT_MARKET', '100000', 'SELL');
}
run();
Position Information
Get current position information and risk details.
Parameters
Symbol optional.
// Get Position Risk
// Endpoint: /fapi/v3/positionRisk
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/fapi/v3/positionRisk';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT'
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Income History
Get income history (Realized PnL, Funding Fee, Commission, etc).
Parameters
None.
// Get Income History
// Endpoint: /fapi/v3/income
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/fapi/v3/income';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();
Funding Rate
Get funding rate history.
Parameters
Symbol optional.
// Get Funding Rate
// Endpoint: /fapi/v3/fundingRate
const axios = require('axios');
const { signature, getTimestamp } = require('./utils');
const BASE_URL = 'https://www.asterdex-testnet.com';
const KEY = 'YOUR_AGENT_WALLET';
const PRIVATE_KEY = 'YOUR_AGENT_PRIVATE_KEY';
async function main() {
const endpoint = '/fapi/v3/fundingRate';
const timestamp = getTimestamp();
// Params
const params = {
timestamp: timestamp,
symbol: 'BTCUSDT'
};
// Sign (if private)
// For public endpoints, authentication headers might not be needed
// but we include logic just in case.
const queryString = new URLSearchParams(params).toString();
const signatureVal = signature(timestamp, 'GET', endpoint, queryString, PRIVATE_KEY);
try {
const response = await axios.get(`${BASE_URL}${endpoint}?${queryString}`, {
headers: {
'X-Aster-Client-Id': KEY,
'X-Aster-Timestamp': timestamp,
'X-Aster-Signature': signatureVal
}
});
console.log('Response:', response.data);
} catch (error) {
console.error('Error:', error.response ? error.response.data : error.message);
}
}
main();