├── .babelrc ├── .eslintrc ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── .prettierrc ├── README.md ├── index.d.ts ├── package.json ├── src ├── http-client.js ├── index.js ├── open-websocket.js └── websocket.js ├── test ├── auth.js ├── index.js ├── types.ts └── utils.js ├── tsconfig.json ├── types ├── account.d.ts ├── base.d.ts ├── delivery.d.ts ├── futures.d.ts ├── generic.d.ts ├── margin.d.ts ├── market.d.ts ├── mining.d.ts ├── order.d.ts ├── papi.d.ts ├── portfolio-margin.d.ts ├── savings.d.ts ├── shared.d.ts ├── stream.d.ts └── utility.d.ts └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", { 5 | "targets": { 6 | "browsers": ["last 2 versions"], 7 | "node": "current", 8 | }, 9 | }, 10 | ] 11 | ], 12 | "plugins": [ 13 | ["module-resolver", { "root": ["src"] }], 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["zavatta", "prettier"], 3 | "rules": { 4 | "id-length": 0 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | push: 4 | branches: 5 | - master 6 | jobs: 7 | code-checks: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - uses: actions/checkout@v4 11 | 12 | - uses: actions/cache@v4 13 | with: 14 | path: '**/node_modules' 15 | key: ${{ runner.os }}-modules-${{ hashFiles('**/yarn.lock') }} 16 | 17 | - name: Install dependencies 18 | run: yarn 19 | 20 | - name: Install OpenVPN 21 | run: | 22 | sudo apt-get update 23 | sudo apt-get install -y openvpn 24 | 25 | - name: Download IVPN config 26 | run: | 27 | wget -O ivpn-config.zip "https://api.ivpn.net/v5/config/ivpn-openvpn-config.zip?country=NL&city=Amsterdam&proto=udp&port=2049" 28 | unzip ivpn-config.zip 29 | 30 | - name: Start IVPN connection 31 | run: | 32 | echo "${{ secrets.IVPN_ACCOUNT_NUMBER }}" > auth.txt 33 | echo "${{ secrets.IVPN_ACCOUNT_NUMBER }}" >> auth.txt 34 | sudo openvpn --config Netherlands-Amsterdam.ovpn --auth-user-pass auth.txt & 35 | sleep 10 # Wait for VPN to establish 36 | 37 | - name: Run typecheck 38 | run: yarn typecheck 39 | 40 | - name: Run checks 41 | run: yarn ci 42 | 43 | - name: Cleanup VPN 44 | if: always() 45 | run: | 46 | sudo killall openvpn || true 47 | rm -f auth.txt -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | .nyc_output/ 3 | dist/ 4 | 5 | .env 6 | .idea 7 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "tabWidth": 2, 7 | "arrowParens": "avoid", 8 | "overrides": [ 9 | { 10 | "files": "*.ts", 11 | "options": { 12 | "parser": "typescript" 13 | } 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './types/base'; 2 | import { GenericEndpoints } from './types/generic'; 3 | import { MarketEndpoints } from './types/market'; 4 | import { OrderEndpoints } from './types/order'; 5 | import { AccountEndpoints } from './types/account'; 6 | import { StreamEndpoints } from './types/stream'; 7 | import { FuturesEndpoints } from './types/futures'; 8 | import { DeliveryEndpoints } from './types/delivery'; 9 | import { PAPIEndpoints } from './types/papi'; 10 | import { MarginEndpoints } from './types/margin'; 11 | import { PortfolioMarginEndpoints } from './types/portfolio-margin'; 12 | import { SavingsEndpoints } from './types/savings'; 13 | import { MiningEndpoints } from './types/mining'; 14 | import { UtilityEndpoints } from './types/utility'; 15 | 16 | export interface BinanceRest extends 17 | GenericEndpoints, 18 | MarketEndpoints, 19 | OrderEndpoints, 20 | AccountEndpoints, 21 | StreamEndpoints, 22 | FuturesEndpoints, 23 | DeliveryEndpoints, 24 | PAPIEndpoints, 25 | MarginEndpoints, 26 | PortfolioMarginEndpoints, 27 | SavingsEndpoints, 28 | MiningEndpoints, 29 | UtilityEndpoints {} 30 | 31 | export * from './types/base'; 32 | export * from './types/market'; 33 | export * from './types/order'; 34 | export * from './types/account'; 35 | export * from './types/stream'; 36 | export * from './types/futures'; 37 | export * from './types/delivery'; 38 | export * from './types/papi'; 39 | export * from './types/margin'; 40 | export * from './types/portfolio-margin'; 41 | export * from './types/savings'; 42 | export * from './types/mining'; 43 | export * from './types/utility'; 44 | 45 | declare function Binance(options?: BinanceRestClient.BinanceRestOptions): BinanceRest; 46 | export default Binance; 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "binance-api-node", 3 | "version": "0.13.0", 4 | "description": "A node API wrapper for Binance", 5 | "main": "dist", 6 | "files": [ 7 | "dist", 8 | "index.d.ts" 9 | ], 10 | "scripts": { 11 | "build": "rm -rf dist && babel src -d dist", 12 | "prepare": "yarn build", 13 | "test": "ava --timeout=10s -v", 14 | "cover": "nyc ava", 15 | "report": "yarn cover && nyc report --reporter=text-lcov | coveralls", 16 | "lint": "eslint src", 17 | "prettier": "prettier --write '{src,test}/**/*.{ts,js}'", 18 | "prettier:check": "prettier -l '{src,test}/**/*.{ts,js}'", 19 | "ci": "yarn lint && yarn prettier:check && yarn test", 20 | "typecheck": "tsc --noEmit" 21 | }, 22 | "dependencies": { 23 | "https-proxy-agent": "^5.0.0", 24 | "isomorphic-fetch": "^3.0.0", 25 | "isomorphic-ws": "^4.0.1", 26 | "json-bigint": "^1.0.0", 27 | "lodash.zipobject": "^4.1.3", 28 | "reconnecting-websocket": "^4.2.0", 29 | "ws": "^7.2.0" 30 | }, 31 | "devDependencies": { 32 | "@babel/cli": "^7.7.4", 33 | "@babel/core": "^7.7.4", 34 | "@babel/polyfill": "^7.7.0", 35 | "@babel/preset-env": "^7.7.4", 36 | "@babel/register": "^7.7.4", 37 | "@types/node": "^18.0.0", 38 | "ava": "^4.1.0", 39 | "babel-eslint": "^10.0.3", 40 | "babel-plugin-module-resolver": "^3.2.0", 41 | "coveralls": "^3.0.9", 42 | "dotenv": "^8.2.0", 43 | "eslint": "^6.7.1", 44 | "eslint-config-prettier": "^6.7.0", 45 | "eslint-config-zavatta": "^6.0.3", 46 | "nyc": "^14.1.1", 47 | "prettier": "^3.5.3", 48 | "ts-node": "^10.9.1", 49 | "typescript": "^4.9.5" 50 | }, 51 | "resolutions": { 52 | "isomorphic-fetch/node-fetch": "2.6.1" 53 | }, 54 | "engines": { 55 | "yarn": ">= 1.0.0" 56 | }, 57 | "ava": { 58 | "require": [ 59 | "@babel/register", 60 | "@babel/polyfill" 61 | ], 62 | "files": [ 63 | "test/**/*", 64 | "!test/utils.js" 65 | ] 66 | }, 67 | "author": "Balthazar Gronon ", 68 | "homepage": "https://github.com/Ashlar/binance-api-node", 69 | "license": "MIT" 70 | } 71 | -------------------------------------------------------------------------------- /src/http-client.js: -------------------------------------------------------------------------------- 1 | import crypto from 'crypto' 2 | import zip from 'lodash.zipobject' 3 | import HttpsProxyAgent from 'https-proxy-agent' 4 | import JSONbig from 'json-bigint' 5 | 6 | import 'isomorphic-fetch' 7 | 8 | const getEndpoint = (endpoints, path, testnet) => { 9 | if (testnet) return 'https://testnet.binancefuture.com' 10 | 11 | if (path.includes('/fapi') || path.includes('/futures')) 12 | return endpoints.futures || 'https://fapi.binance.com' 13 | if (path.includes('/dapi')) return endpoints.delivery || 'https://dapi.binance.com' 14 | if (path.includes('/papi')) return endpoints.portfolioMargin || 'https://papi.binance.com' 15 | 16 | return endpoints.base || 'https://api.binance.com' 17 | } 18 | 19 | const getDomainName = url => { 20 | const match = url.match(/^(?:https?:\/\/)?(?:www\.)?([\w-]+(\.[\w-]+)+)/) 21 | return match ? match[1] : null 22 | } 23 | 24 | const defaultGetTime = () => Date.now() 25 | 26 | // Singleton holding header data like rate limits. 27 | const info = {} 28 | 29 | /** 30 | * Build query string for uri encoded url based on json object 31 | */ 32 | const makeQueryString = q => 33 | q 34 | ? `?${Object.keys(q) 35 | .map(k => `${encodeURIComponent(k)}=${encodeURIComponent(q[k])}`) 36 | .join('&')}` 37 | : '' 38 | 39 | /** 40 | * Get API limits info from headers 41 | */ 42 | const headersMapping = { 43 | 'x-mbx-used-weight-1m': 'usedWeight1m', 44 | 'x-mbx-order-count-10s': 'orderCount10s', 45 | 'x-mbx-order-count-1m': 'orderCount1m', 46 | 'x-mbx-order-count-1h': 'orderCount1h', 47 | 'x-mbx-order-count-1d': 'orderCount1d', 48 | 'x-response-time': 'responseTime', 49 | } 50 | 51 | const responseHandler = res => { 52 | if (!res.headers || !res.url) return 53 | 54 | const domain = getDomainName(res.url) 55 | if (!info[domain]) info[domain] = {} 56 | 57 | for (const key of Object.keys(headersMapping)) { 58 | const outKey = headersMapping[key] 59 | 60 | if (res.headers.has(key)) { 61 | info[domain][outKey] = res.headers.get(key) 62 | } 63 | } 64 | } 65 | 66 | /** 67 | * Finalize API response 68 | */ 69 | const sendResult = call => 70 | call.then(res => { 71 | // Get API limits info from headers 72 | responseHandler(res) 73 | 74 | // If response is ok, we can safely assume it is valid JSON 75 | if (res.ok) return res.text().then(text => JSONbig.parse(text)) 76 | 77 | // Errors might come from the API itself or the proxy Binance is using. 78 | // For API errors the response will be valid JSON,but for proxy errors 79 | // it will be HTML 80 | return res.text().then(text => { 81 | let error 82 | try { 83 | const json = JSONbig.parse(text) 84 | // The body was JSON parseable, assume it is an API response error 85 | error = new Error(json.msg || `${res.status} ${res.statusText}`) 86 | error.code = json.code 87 | error.url = res.url 88 | } catch (e) { 89 | // The body was not JSON parseable, assume it is proxy error 90 | error = new Error(`${res.status} ${res.statusText} ${text}`) 91 | error.response = res 92 | error.responseText = text 93 | } 94 | throw error 95 | }) 96 | }) 97 | 98 | /** 99 | * Util to validate existence of required parameter(s) 100 | */ 101 | const checkParams = (name, payload, requires = []) => { 102 | if (!payload) { 103 | throw new Error('You need to pass a payload object.') 104 | } 105 | 106 | requires.forEach(r => { 107 | if (!payload[r] && isNaN(payload[r])) { 108 | throw new Error(`Method ${name} requires ${r} parameter.`) 109 | } 110 | }) 111 | 112 | return true 113 | } 114 | 115 | /** 116 | * Make public calls against the api 117 | * 118 | * @param {string} path Endpoint path 119 | * @param {object} data The payload to be sent 120 | * @param {string} method HTTB VERB, GET by default 121 | * @param {object} headers 122 | * @returns {object} The api response 123 | */ 124 | const publicCall = 125 | ({ proxy, endpoints, testnet }) => 126 | (path, data, method = 'GET', headers = {}) => { 127 | return sendResult( 128 | fetch(`${getEndpoint(endpoints, path, testnet)}${path}${makeQueryString(data)}`, { 129 | method, 130 | json: true, 131 | headers, 132 | ...(proxy ? { agent: new HttpsProxyAgent(proxy) } : {}), 133 | }), 134 | ) 135 | } 136 | 137 | /** 138 | * Factory method for partial private calls against the api 139 | * 140 | * @param {string} path Endpoint path 141 | * @param {object} data The payload to be sent 142 | * @param {string} method HTTB VERB, GET by default 143 | * @returns {object} The api response 144 | */ 145 | const keyCall = 146 | ({ apiKey, pubCall }) => 147 | (path, data, method = 'GET') => { 148 | if (!apiKey) { 149 | throw new Error('You need to pass an API key to make this call.') 150 | } 151 | 152 | return pubCall(path, data, method, { 153 | 'X-MBX-APIKEY': apiKey, 154 | }) 155 | } 156 | 157 | /** 158 | * Factory method for private calls against the api 159 | * 160 | * @param {string} path Endpoint path 161 | * @param {object} data The payload to be sent 162 | * @param {string} method HTTB VERB, GET by default 163 | * @param {object} headers 164 | * @returns {object} The api response 165 | */ 166 | const privateCall = 167 | ({ apiKey, apiSecret, proxy, endpoints, getTime = defaultGetTime, pubCall, testnet }) => 168 | (path, data = {}, method = 'GET', noData, noExtra) => { 169 | if (!apiKey || !apiSecret) { 170 | throw new Error('You need to pass an API key and secret to make authenticated calls.') 171 | } 172 | 173 | return ( 174 | data && data.useServerTime 175 | ? pubCall('/api/v3/time').then(r => r.serverTime) 176 | : Promise.resolve(getTime()) 177 | ).then(timestamp => { 178 | if (data) { 179 | delete data.useServerTime 180 | } 181 | 182 | const signature = crypto 183 | .createHmac('sha256', apiSecret) 184 | .update(makeQueryString({ ...data, timestamp }).substr(1)) 185 | .digest('hex') 186 | 187 | const newData = noExtra ? data : { ...data, timestamp, signature } 188 | 189 | return sendResult( 190 | fetch( 191 | `${getEndpoint(endpoints, path, testnet)}${path}${noData ? '' : makeQueryString(newData)}`, 192 | { 193 | method, 194 | headers: { 'X-MBX-APIKEY': apiKey }, 195 | json: true, 196 | ...(proxy ? { agent: new HttpsProxyAgent(proxy) } : {}), 197 | }, 198 | ), 199 | ) 200 | }) 201 | } 202 | 203 | export const candleFields = [ 204 | 'openTime', 205 | 'open', 206 | 'high', 207 | 'low', 208 | 'close', 209 | 'volume', 210 | 'closeTime', 211 | 'quoteVolume', 212 | 'trades', 213 | 'baseAssetVolume', 214 | 'quoteAssetVolume', 215 | ] 216 | 217 | export const deliveryCandleFields = [ 218 | 'openTime', 219 | 'open', 220 | 'high', 221 | 'low', 222 | 'close', 223 | 'volume', 224 | 'closeTime', 225 | 'baseVolume', 226 | 'trades', 227 | 'quoteAssetVolume', 228 | 'baseAssetVolume', 229 | ] 230 | 231 | /** 232 | * Get candles for a specific pair and interval and convert response 233 | * to a user friendly collection. 234 | */ 235 | const candles = (pubCall, payload, endpoint = '/api/v3/klines') => 236 | checkParams('candles', payload, endpoint.includes('indexPrice') ? ['pair'] : ['symbol']) && 237 | pubCall(endpoint, { interval: '5m', ...payload }).then(candles => 238 | candles.map(candle => 239 | zip(!endpoint.includes('dapi') ? candleFields : deliveryCandleFields, candle), 240 | ), 241 | ) 242 | 243 | /** 244 | * Create a new order wrapper for market order simplicity 245 | */ 246 | const order = (privCall, payload = {}, url) => { 247 | const newPayload = 248 | ['LIMIT', 'STOP_LOSS_LIMIT', 'TAKE_PROFIT_LIMIT'].includes(payload.type) || !payload.type 249 | ? { timeInForce: 'GTC', ...payload } 250 | : payload 251 | 252 | const requires = ['symbol', 'side'] 253 | 254 | if ( 255 | !(newPayload.type === 'MARKET' && newPayload.quoteOrderQty) && 256 | !(newPayload.type === 'STOP_MARKET') && 257 | !(newPayload.type === 'TAKE_PROFIT_MARKET') && 258 | !(newPayload.type === 'TRAILING_STOP_MARKET') 259 | ) { 260 | requires.push('quantity') 261 | } 262 | 263 | if (newPayload.type === 'TRAILING_STOP_MARKET') { 264 | requires.push('callbackRate') 265 | } 266 | 267 | return ( 268 | checkParams('order', newPayload, requires) && 269 | privCall(url, { type: 'LIMIT', ...newPayload }, 'POST') 270 | ) 271 | } 272 | 273 | const orderOco = (privCall, payload = {}, url) => { 274 | const newPayload = 275 | payload.stopLimitPrice && !payload.stopLimitTimeInForce 276 | ? { stopLimitTimeInForce: 'GTC', ...payload } 277 | : payload 278 | 279 | return ( 280 | checkParams('order', newPayload, ['symbol', 'side', 'quantity', 'price', 'stopPrice']) && 281 | privCall(url, newPayload, 'POST') 282 | ) 283 | } 284 | 285 | /** 286 | * Zip asks and bids reponse from order book 287 | */ 288 | const book = (pubCall, payload, endpoint = '/api/v3/depth') => 289 | checkParams('book', payload, ['symbol']) && 290 | pubCall(endpoint, payload).then(({ lastUpdateId, asks, bids }) => ({ 291 | lastUpdateId, 292 | asks: asks.map(a => zip(['price', 'quantity'], a)), 293 | bids: bids.map(b => zip(['price', 'quantity'], b)), 294 | })) 295 | 296 | const aggTrades = (pubCall, payload, endpoint = '/api/v3/aggTrades') => 297 | checkParams('aggTrades', payload, ['symbol']) && 298 | pubCall(endpoint, payload).then(trades => 299 | trades.map(trade => { 300 | const transformed = { 301 | aggId: trade.a, 302 | symbol: payload.symbol, 303 | price: trade.p, 304 | quantity: trade.q, 305 | firstId: trade.f, 306 | lastId: trade.l, 307 | timestamp: trade.T, 308 | isBuyerMaker: trade.m, 309 | } 310 | if (trade.M) transformed.wasBestPrice = trade.M 311 | 312 | return transformed 313 | }), 314 | ) 315 | 316 | export default opts => { 317 | const endpoints = { 318 | base: opts && opts.httpBase, 319 | futures: opts && opts.httpFutures, 320 | delivery: opts && opts.httpDelivery, 321 | portfolioMargin: opts && opts.httpPortfolioMargin, 322 | } 323 | 324 | const pubCall = publicCall({ ...opts, endpoints }) 325 | const deliveryPubCall = publicCall({ 326 | ...opts, 327 | endpoints: { futures: endpoints.delivery }, 328 | }) 329 | const privCall = privateCall({ ...opts, endpoints, pubCall }) 330 | const kCall = keyCall({ ...opts, pubCall }) 331 | 332 | return { 333 | // Generic endpoints 334 | getInfo: () => info, 335 | ping: () => pubCall('/api/v3/ping').then(() => true), 336 | time: () => pubCall('/api/v3/time').then(r => r.serverTime), 337 | exchangeInfo: payload => pubCall('/api/v3/exchangeInfo', payload), 338 | 339 | // Market Data endpoints 340 | book: payload => book(pubCall, payload), 341 | aggTrades: payload => aggTrades(pubCall, payload), 342 | candles: payload => candles(pubCall, payload), 343 | trades: payload => 344 | checkParams('trades', payload, ['symbol']) && pubCall('/api/v3/trades', payload), 345 | tradesHistory: payload => 346 | checkParams('tradesHitory', payload, ['symbol']) && 347 | kCall('/api/v3/historicalTrades', payload), 348 | dailyStats: payload => pubCall('/api/v3/ticker/24hr', payload), 349 | prices: payload => 350 | pubCall('/api/v3/ticker/price', payload).then(r => 351 | (Array.isArray(r) ? r : [r]).reduce((out, cur) => ((out[cur.symbol] = cur.price), out), {}), 352 | ), 353 | avgPrice: payload => pubCall('/api/v3/avgPrice', payload), 354 | allBookTickers: () => 355 | pubCall('/api/v3/ticker/bookTicker').then(r => 356 | (Array.isArray(r) ? r : [r]).reduce((out, cur) => ((out[cur.symbol] = cur), out), {}), 357 | ), 358 | 359 | // Order endpoints 360 | order: payload => order(privCall, payload, '/api/v3/order'), 361 | orderOco: payload => orderOco(privCall, payload, '/api/v3/order/oco'), 362 | orderTest: payload => order(privCall, payload, '/api/v3/order/test'), 363 | getOrder: payload => privCall('/api/v3/order', payload), 364 | getOrderOco: payload => privCall('/api/v3/orderList', payload), 365 | cancelOrder: payload => privCall('/api/v3/order', payload, 'DELETE'), 366 | cancelOrderOco: payload => privCall('/api/v3/orderList', payload, 'DELETE'), 367 | cancelOpenOrders: payload => privCall('/api/v3/openOrders', payload, 'DELETE'), 368 | openOrders: payload => privCall('/api/v3/openOrders', payload), 369 | allOrders: payload => privCall('/api/v3/allOrders', payload), 370 | allOrdersOCO: payload => privCall('/api/v3/allOrderList', payload), 371 | 372 | // Account endpoints 373 | accountInfo: payload => privCall('/api/v3/account', payload), 374 | myTrades: payload => privCall('/api/v3/myTrades', payload), 375 | withdraw: payload => privCall('/sapi/v1/capital/withdraw/apply', payload, 'POST'), 376 | withdrawHistory: payload => privCall('/sapi/v1/capital/withdraw/history', payload), 377 | depositHistory: payload => privCall('/sapi/v1/capital/deposit/hisrec', payload), 378 | depositAddress: payload => privCall('/sapi/v1/capital/deposit/address', payload), 379 | tradeFee: payload => privCall('/sapi/v1/asset/tradeFee', payload), 380 | assetDetail: payload => privCall('/sapi/v1/asset/assetDetail', payload), 381 | accountSnapshot: payload => privCall('/sapi/v1/accountSnapshot', payload), 382 | universalTransfer: payload => privCall('/sapi/v1/asset/transfer', payload, 'POST'), 383 | universalTransferHistory: payload => privCall('/sapi/v1/asset/transfer', payload), 384 | dustLog: payload => privCall('/sapi/v1/asset/dribblet', payload), 385 | dustTransfer: payload => privCall('/sapi/v1/asset/dust', payload, 'POST'), 386 | accountCoins: payload => privCall('/sapi/v1/capital/config/getall', payload), 387 | getBnbBurn: payload => privCall('/sapi/v1/bnbBurn', payload), 388 | setBnbBurn: payload => privCall('/sapi/v1/bnbBurn', payload, 'POST'), 389 | capitalConfigs: () => privCall('/sapi/v1/capital/config/getall'), 390 | 391 | // User Data Stream endpoints 392 | getDataStream: () => privCall('/api/v3/userDataStream', null, 'POST', true), 393 | keepDataStream: payload => privCall('/api/v3/userDataStream', payload, 'PUT', false, true), 394 | closeDataStream: payload => privCall('/api/v3/userDataStream', payload, 'DELETE', false, true), 395 | marginGetDataStream: () => privCall('/sapi/v1/userDataStream', null, 'POST', true), 396 | marginKeepDataStream: payload => 397 | privCall('/sapi/v1/userDataStream', payload, 'PUT', false, true), 398 | marginCloseDataStream: payload => 399 | privCall('/sapi/v1/userDataStream', payload, 'DELETE', false, true), 400 | futuresGetDataStream: () => privCall('/fapi/v1/listenKey', null, 'POST', true), 401 | futuresKeepDataStream: payload => privCall('/fapi/v1/listenKey', payload, 'PUT', false, true), 402 | futuresCloseDataStream: payload => 403 | privCall('/fapi/v1/listenKey', payload, 'DELETE', false, true), 404 | deliveryGetDataStream: () => privCall('/dapi/v1/listenKey', null, 'POST', true), 405 | deliveryKeepDataStream: payload => privCall('/dapi/v1/listenKey', payload, 'PUT', false, true), 406 | deliveryCloseDataStream: payload => 407 | privCall('/dapi/v1/listenKey', payload, 'DELETE', false, true), 408 | 409 | // Futures endpoints 410 | futuresPing: () => pubCall('/fapi/v1/ping').then(() => true), 411 | futuresTime: () => pubCall('/fapi/v1/time').then(r => r.serverTime), 412 | futuresExchangeInfo: () => pubCall('/fapi/v1/exchangeInfo'), 413 | futuresBook: payload => book(pubCall, payload, '/fapi/v1/depth'), 414 | futuresAggTrades: payload => aggTrades(pubCall, payload, '/fapi/v1/aggTrades'), 415 | futuresMarkPrice: payload => pubCall('/fapi/v1/premiumIndex', payload), 416 | futuresAllForceOrders: payload => pubCall('/fapi/v1/allForceOrders', payload), 417 | futuresLongShortRatio: payload => pubCall('/futures/data/globalLongShortAccountRatio', payload), 418 | futuresCandles: payload => candles(pubCall, payload, '/fapi/v1/klines'), 419 | futuresMarkPriceCandles: payload => candles(pubCall, payload, '/fapi/v1/markPriceKlines'), 420 | futuresIndexPriceCandles: payload => candles(pubCall, payload, '/fapi/v1/indexPriceKlines'), 421 | futuresTrades: payload => 422 | checkParams('trades', payload, ['symbol']) && pubCall('/fapi/v1/trades', payload), 423 | futuresDailyStats: payload => pubCall('/fapi/v1/ticker/24hr', payload), 424 | futuresPrices: payload => 425 | pubCall('/fapi/v1/ticker/price', payload).then(r => 426 | (Array.isArray(r) ? r : [r]).reduce((out, cur) => ((out[cur.symbol] = cur.price), out), {}), 427 | ), 428 | futuresAllBookTickers: () => 429 | pubCall('/fapi/v1/ticker/bookTicker').then(r => 430 | (Array.isArray(r) ? r : [r]).reduce((out, cur) => ((out[cur.symbol] = cur), out), {}), 431 | ), 432 | futuresFundingRate: payload => 433 | checkParams('fundingRate', payload, ['symbol']) && pubCall('/fapi/v1/fundingRate', payload), 434 | futuresOrder: payload => order(privCall, payload, '/fapi/v1/order'), 435 | futuresBatchOrders: payload => privCall('/fapi/v1/batchOrders', payload, 'POST'), 436 | futuresGetOrder: payload => privCall('/fapi/v1/order', payload), 437 | futuresCancelOrder: payload => privCall('/fapi/v1/order', payload, 'DELETE'), 438 | futuresCancelAllOpenOrders: payload => privCall('/fapi/v1/allOpenOrders', payload, 'DELETE'), 439 | futuresCancelBatchOrders: payload => privCall('/fapi/v1/batchOrders', payload, 'DELETE'), 440 | futuresOpenOrders: payload => privCall('/fapi/v1/openOrders', payload), 441 | futuresAllOrders: payload => privCall('/fapi/v1/allOrders', payload), 442 | futuresPositionRisk: payload => privCall('/fapi/v2/positionRisk', payload), 443 | futuresLeverageBracket: payload => privCall('/fapi/v1/leverageBracket', payload), 444 | futuresAccountBalance: payload => privCall('/fapi/v2/balance', payload), 445 | futuresAccountInfo: payload => privCall('/fapi/v2/account', payload), 446 | futuresUserTrades: payload => privCall('/fapi/v1/userTrades', payload), 447 | futuresPositionMode: payload => privCall('/fapi/v1/positionSide/dual', payload), 448 | futuresPositionModeChange: payload => privCall('/fapi/v1/positionSide/dual', payload, 'POST'), 449 | futuresLeverage: payload => privCall('/fapi/v1/leverage', payload, 'POST'), 450 | futuresMarginType: payload => privCall('/fapi/v1/marginType', payload, 'POST'), 451 | futuresPositionMargin: payload => privCall('/fapi/v1/positionMargin', payload, 'POST'), 452 | futuresMarginHistory: payload => privCall('/fapi/v1/positionMargin/history', payload), 453 | futuresIncome: payload => privCall('/fapi/v1/income', payload), 454 | getMultiAssetsMargin: payload => privCall('/fapi/v1/multiAssetsMargin', payload), 455 | setMultiAssetsMargin: payload => privCall('/fapi/v1/multiAssetsMargin', payload, 'POST'), 456 | 457 | // Delivery endpoints 458 | deliveryPing: () => pubCall('/dapi/v1/ping').then(() => true), 459 | deliveryTime: () => pubCall('/dapi/v1/time').then(r => r.serverTime), 460 | deliveryExchangeInfo: () => pubCall('/dapi/v1/exchangeInfo'), 461 | deliveryBook: payload => book(pubCall, payload, '/dapi/v1/depth'), 462 | deliveryAggTrades: payload => aggTrades(pubCall, payload, '/dapi/v1/aggTrades'), 463 | deliveryMarkPrice: payload => pubCall('/dapi/v1/premiumIndex', payload), 464 | deliveryAllForceOrders: payload => pubCall('/dapi/v1/allForceOrders', payload), 465 | deliveryLongShortRatio: payload => 466 | deliveryPubCall('/futures/data/globalLongShortAccountRatio', payload), 467 | deliveryCandles: payload => candles(pubCall, payload, '/dapi/v1/klines'), 468 | deliveryMarkPriceCandles: payload => candles(pubCall, payload, '/dapi/v1/markPriceKlines'), 469 | deliveryIndexPriceCandles: payload => candles(pubCall, payload, '/dapi/v1/indexPriceKlines'), 470 | deliveryTrades: payload => 471 | checkParams('trades', payload, ['symbol']) && pubCall('/dapi/v1/trades', payload), 472 | deliveryDailyStats: payload => pubCall('/dapi/v1/ticker/24hr', payload), 473 | deliveryPrices: () => 474 | pubCall('/dapi/v1/ticker/price').then(r => 475 | (Array.isArray(r) ? r : [r]).reduce((out, cur) => ((out[cur.symbol] = cur.price), out), {}), 476 | ), 477 | deliveryAllBookTickers: () => 478 | pubCall('/dapi/v1/ticker/bookTicker').then(r => 479 | (Array.isArray(r) ? r : [r]).reduce((out, cur) => ((out[cur.symbol] = cur), out), {}), 480 | ), 481 | deliveryFundingRate: payload => 482 | checkParams('fundingRate', payload, ['symbol']) && pubCall('/dapi/v1/fundingRate', payload), 483 | deliveryOrder: payload => order(privCall, payload, '/dapi/v1/order'), 484 | deliveryBatchOrders: payload => privCall('/dapi/v1/batchOrders', payload, 'POST'), 485 | deliveryGetOrder: payload => privCall('/dapi/v1/order', payload), 486 | deliveryCancelOrder: payload => privCall('/dapi/v1/order', payload, 'DELETE'), 487 | deliveryCancelAllOpenOrders: payload => privCall('/dapi/v1/allOpenOrders', payload, 'DELETE'), 488 | deliveryCancelBatchOrders: payload => privCall('/dapi/v1/batchOrders', payload, 'DELETE'), 489 | deliveryOpenOrders: payload => privCall('/dapi/v1/openOrders', payload), 490 | deliveryAllOrders: payload => privCall('/dapi/v1/allOrders', payload), 491 | deliveryPositionRisk: payload => privCall('/dapi/v1/positionRisk', payload), 492 | deliveryLeverageBracket: payload => privCall('/dapi/v1/leverageBracket', payload), 493 | deliveryAccountBalance: payload => privCall('/dapi/v1/balance', payload), 494 | deliveryAccountInfo: payload => privCall('/dapi/v1/account', payload), 495 | deliveryUserTrades: payload => privCall('/dapi/v1/userTrades', payload), 496 | deliveryPositionMode: payload => privCall('/dapi/v1/positionSide/dual', payload), 497 | deliveryPositionModeChange: payload => privCall('/dapi/v1/positionSide/dual', payload, 'POST'), 498 | deliveryLeverage: payload => privCall('/dapi/v1/leverage', payload, 'POST'), 499 | deliveryMarginType: payload => privCall('/dapi/v1/marginType', payload, 'POST'), 500 | deliveryPositionMargin: payload => privCall('/dapi/v1/positionMargin', payload, 'POST'), 501 | deliveryMarginHistory: payload => privCall('/dapi/v1/positionMargin/history', payload), 502 | deliveryIncome: payload => privCall('/dapi/v1/income', payload), 503 | 504 | // PAPI endpoints 505 | papiPing: () => privCall('/papi/v1/ping'), 506 | papiAccount: () => privCall('/papi/v1/account'), 507 | papiBalance: payload => privCall('/papi/v1/balance', payload), 508 | papiUmOrder: payload => privCall('/papi/v1/um/order', payload), 509 | papiUmConditionalOrder: payload => privCall('/papi/v1/um/conditional/order', payload, 'POST'), 510 | papiCmOrder: payload => privCall('/papi/v1/cm/order', payload, 'POST'), 511 | papiCmConditionalOrder: payload => privCall('/papi/v1/cm/conditional/order', payload, 'POST'), 512 | papiMarginOrder: payload => privCall('/papi/v1/margin/order', payload, 'POST'), 513 | papiMarginLoan: payload => privCall('/papi/v1/marginLoan', payload, 'POST'), 514 | papiRepayLoan: payload => privCall('/papi/v1/repayLoan', payload, 'POST'), 515 | papiMarginOrderOco: payload => privCall('/papi/v1/margin/order/oco', payload, 'POST'), 516 | papiUmCancelOrder: payload => privCall('/papi/v1/um/order', payload, 'DELETE'), 517 | papiUmCancelAllOpenOrders: payload => privCall('/papi/v1/um/allOpenOrders', payload, 'DELETE'), 518 | papiUmCancelConditionalOrder: payload => 519 | privCall('/papi/v1/um/conditional/order', payload, 'DELETE'), 520 | papiUmCancelConditionalAllOpenOrders: payload => 521 | privCall('/papi/v1/um/conditional/allOpenOrders', payload, 'DELETE'), 522 | papiCmCancelOrder: payload => privCall('/papi/v1/cm/order', payload, 'DELETE'), 523 | papiCmCancelAllOpenOrders: payload => privCall('/papi/v1/cm/allOpenOrders', payload, 'DELETE'), 524 | papiCmCancelConditionalOrder: payload => 525 | privCall('/papi/v1/cm/conditional/order', payload, 'DELETE'), 526 | papiCmCancelConditionalAllOpenOrders: payload => 527 | privCall('/papi/v1/cm/conditional/allOpenOrders', payload, 'DELETE'), 528 | papiMarginCancelOrder: payload => privCall('/papi/v1/margin/order', payload, 'DELETE'), 529 | papiMarginCancelOrderList: payload => privCall('/papi/v1/margin/orderList', payload, 'DELETE'), 530 | papiMarginCancelAllOpenOrders: payload => 531 | privCall('/papi/v1/margin/allOpenOrders', payload, 'DELETE'), 532 | papiUmUpdateOrder: payload => privCall('/papi/v1/um/order', payload, 'PUT'), 533 | papiCmUpdateOrder: payload => privCall('/papi/v1/cm/order', payload, 'PUT'), 534 | papiUmGetOrder: payload => privCall('/papi/v1/um/order', payload), 535 | papiUmGetAllOrders: payload => privCall('/papi/v1/um/allOrders', payload), 536 | papiUmGetOpenOrder: payload => privCall('/papi/v1/um/openOrder', payload), 537 | papiUmGetOpenOrders: payload => privCall('/papi/v1/um/openOrders', payload), 538 | papiUmGetConditionalAllOrders: payload => 539 | privCall('/papi/v1/um/conditional/allOrders', payload), 540 | papiUmGetConditionalOpenOrders: payload => 541 | privCall('/papi/v1/um/conditional/openOrders', payload), 542 | papiUmGetConditionalOpenOrder: payload => 543 | privCall('/papi/v1/um/conditional/openOrder', payload), 544 | papiUmGetConditionalOrderHistory: payload => 545 | privCall('/papi/v1/um/conditional/orderHistory', payload), 546 | papiCmGetOrder: payload => privCall('/papi/v1/cm/order', payload), 547 | papiCmGetAllOrders: payload => privCall('/papi/v1/cm/allOrders', payload), 548 | papiCmGetOpenOrder: payload => privCall('/papi/v1/cm/openOrder', payload), 549 | papiCmGetOpenOrders: payload => privCall('/papi/v1/cm/openOrders', payload), 550 | papiCmGetConditionalOpenOrders: payload => 551 | privCall('/papi/v1/cm/conditional/openOrders', payload), 552 | papiCmGetConditionalOpenOrder: payload => 553 | privCall('/papi/v1/cm/conditional/openOrder', payload), 554 | papiCmGetConditionalAllOrders: payload => 555 | privCall('/papi/v1/cm/conditional/allOrders', payload), 556 | papiCmGetConditionalOrderHistory: payload => 557 | privCall('/papi/v1/cm/conditional/orderHistory', payload), 558 | papiUmGetForceOrders: payload => privCall('/papi/v1/um/forceOrders', payload), 559 | papiCmGetForceOrders: payload => privCall('/papi/v1/cm/forceOrders', payload), 560 | papiUmGetOrderAmendment: payload => privCall('/papi/v1/um/orderAmendment', payload), 561 | papiCmGetOrderAmendment: payload => privCall('/papi/v1/cm/orderAmendment', payload), 562 | papiMarginGetForceOrders: payload => privCall('/papi/v1/margin/forceOrders', payload), 563 | papiUmGetUserTrades: payload => privCall('/papi/v1/um/userTrades', payload), 564 | papiCmGetUserTrades: payload => privCall('/papi/v1/cm/userTrades', payload), 565 | papiUmGetAdlQuantile: payload => privCall('/papi/v1/um/adlQuantile', payload), 566 | papiCmGetAdlQuantile: payload => privCall('/papi/v1/cm/adlQuantile', payload), 567 | papiUmFeeBurn: payload => privCall('/papi/v1/um/feeBurn', payload, 'POST'), 568 | papiUmGetFeeBurn: payload => privCall('/papi/v1/um/feeBurn', payload), 569 | papiMarginGetOrder: payload => privCall('/papi/v1/margin/order', payload), 570 | papiMarginGetOpenOrders: payload => privCall('/papi/v1/margin/openOrders', payload), 571 | papiMarginGetAllOrders: payload => privCall('/papi/v1/margin/allOrders', payload), 572 | papiMarginGetOrderList: payload => privCall('/papi/v1/margin/orderList', payload), 573 | papiMarginGetAllOrderList: payload => privCall('/papi/v1/margin/allOrderList', payload), 574 | papiMarginGetOpenOrderList: payload => privCall('/papi/v1/margin/openOrderList', payload), 575 | papiMarginGetMyTrades: payload => privCall('/papi/v1/margin/myTrades', payload), 576 | papiMarginRepayDebt: payload => privCall('/papi/v1/margin/repay-debt', payload, 'POST'), 577 | 578 | // Margin endpoints 579 | marginAllOrders: payload => privCall('/sapi/v1/margin/allOrders', payload), 580 | marginOrder: payload => order(privCall, payload, '/sapi/v1/margin/order'), 581 | marginOrderOco: payload => orderOco(privCall, payload, '/sapi/v1/margin/order/oco'), 582 | marginGetOrder: payload => privCall('/sapi/v1/margin/order', payload), 583 | marginGetOrderOco: payload => privCall('/sapi/v1/margin/orderList', payload), 584 | marginCancelOrder: payload => privCall('/sapi/v1/margin/order', payload, 'DELETE'), 585 | marginOpenOrders: payload => privCall('/sapi/v1/margin/openOrders', payload), 586 | marginCancelOpenOrders: payload => privCall('/sapi/v1/margin/openOrders', payload, 'DELETE'), 587 | marginAccountInfo: payload => privCall('/sapi/v1/margin/account', payload), 588 | marginMyTrades: payload => privCall('/sapi/v1/margin/myTrades', payload), 589 | marginRepay: payload => privCall('/sapi/v1/margin/repay', payload, 'POST'), 590 | marginLoan: payload => privCall('/sapi/v1/margin/loan', payload, 'POST'), 591 | marginIsolatedAccount: payload => privCall('/sapi/v1/margin/isolated/account', payload), 592 | marginMaxBorrow: payload => privCall('/sapi/v1/margin/maxBorrowable', payload), 593 | marginCreateIsolated: payload => privCall('/sapi/v1/margin/isolated/create', payload, 'POST'), 594 | marginIsolatedTransfer: payload => 595 | privCall('/sapi/v1/margin/isolated/transfer', payload, 'POST'), 596 | marginIsolatedTransferHistory: payload => 597 | privCall('/sapi/v1/margin/isolated/transfer', payload), 598 | disableMarginAccount: payload => 599 | privCall('/sapi/v1/margin/isolated/account', payload, 'DELETE'), 600 | enableMarginAccount: payload => privCall('/sapi/v1/margin/isolated/account', payload, 'POST'), 601 | marginAccount: () => privCall('/sapi/v1/margin/account'), 602 | 603 | // Portfolio Margin endpoints 604 | portfolioMarginAccountInfo: () => privCall('/sapi/v1/portfolio/account'), 605 | portfolioMarginCollateralRate: () => privCall('/sapi/v1/portfolio/collateralRate'), 606 | portfolioMarginLoan: payload => privCall('/sapi/v1/portfolio/pmLoan', payload), 607 | portfolioMarginLoanRepay: payload => privCall('/sapi/v1/portfolio/repay', payload, 'POST'), 608 | portfolioMarginInterestHistory: payload => 609 | privCall('/sapi/v1/portfolio/interest-history', payload), 610 | 611 | // Savings endpoints 612 | savingsAccount: payload => privCall('/sapi/v1/lending/union/account', payload), 613 | savingsPurchase: payload => privCall('/sapi/v1/lending/union/purchase', payload, 'POST'), 614 | savingsRedeem: payload => privCall('/sapi/v1/lending/union/redeem', payload, 'POST'), 615 | fundingWallet: payload => privCall('/sapi/v1/asset/get-funding-asset', payload, 'POST'), 616 | convertTradeFlow: payload => privCall('/sapi/v1/convert/tradeFlow', payload), 617 | rebateTaxQuery: () => privCall('/sapi/v1/rebate/taxQuery'), 618 | payTradeHistory: payload => privCall('/sapi/v1/pay/transactions', payload), 619 | apiRestrictions: payload => privCall('/sapi/v1/account/apiRestrictions', payload), 620 | 621 | // Mining endpoints 622 | miningHashrateResaleRequest: payload => 623 | privCall('/sapi/v1/mining/hash-transfer/config', payload, 'POST'), 624 | miningHashrateResaleCancel: payload => 625 | privCall('/sapi/v1/mining/hash-transfer/config/cancel', payload, 'POST'), 626 | miningStatistics: payload => privCall('/sapi/v1/mining/statistics/user/status', payload), 627 | 628 | // Utility endpoints 629 | privateRequest: (method, url, payload) => privCall(url, payload, method), 630 | publicRequest: (method, url, payload) => pubCall(url, payload, method), 631 | } 632 | } 633 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import httpMethods from 'http-client' 2 | import wsMethods from 'websocket' 3 | 4 | export default (opts = {}) => ({ 5 | ...httpMethods(opts), 6 | ws: wsMethods(opts), 7 | }) 8 | 9 | export const ErrorCodes = { 10 | UNKNOWN: -1000, 11 | DISCONNECTED: -1001, 12 | UNAUTHORIZED: -1002, 13 | TOO_MANY_REQUESTS: -1003, 14 | UNEXPECTED_RESP: -1006, 15 | TIMEOUT: -1007, 16 | INVALID_MESSAGE: -1013, 17 | UNKNOWN_ORDER_COMPOSITION: -1014, 18 | TOO_MANY_ORDERS: -1015, 19 | SERVICE_SHUTTING_DOWN: -1016, 20 | UNSUPPORTED_OPERATION: -1020, 21 | INVALID_TIMESTAMP: -1021, 22 | INVALID_SIGNATURE: -1022, 23 | ILLEGAL_CHARS: -1100, 24 | TOO_MANY_PARAMETERS: -1101, 25 | MANDATORY_PARAM_EMPTY_OR_MALFORMED: -1102, // eslint-disable-line id-length 26 | UNKNOWN_PARAM: -1103, 27 | UNREAD_PARAMETERS: -1104, 28 | PARAM_EMPTY: -1105, 29 | PARAM_NOT_REQUIRED: -1106, 30 | NO_DEPTH: -1112, 31 | TIF_NOT_REQUIRED: -1114, 32 | INVALID_TIF: -1115, 33 | INVALID_ORDER_TYPE: -1116, 34 | INVALID_SIDE: -1117, 35 | EMPTY_NEW_CL_ORD_ID: -1118, 36 | EMPTY_ORG_CL_ORD_ID: -1119, 37 | BAD_INTERVAL: -1120, 38 | BAD_SYMBOL: -1121, 39 | INVALID_LISTEN_KEY: -1125, 40 | MORE_THAN_XX_HOURS: -1127, 41 | OPTIONAL_PARAMS_BAD_COMBO: -1128, 42 | INVALID_PARAMETER: -1130, 43 | BAD_API_ID: -2008, 44 | DUPLICATE_API_KEY_DESC: -2009, 45 | INSUFFICIENT_BALANCE: -2010, 46 | CANCEL_REJECTED: -2011, 47 | CANCEL_ALL_FAIL: -2012, 48 | NO_SUCH_ORDER: -2013, 49 | BAD_API_KEY_FMT: -2014, 50 | REJECTED_MBX_KEY: -2015, 51 | } 52 | 53 | export const CandleChartInterval = { 54 | ONE_MINUTE: '1m', 55 | THREE_MINUTES: '3m', 56 | FIVE_MINUTES: '5m', 57 | FIFTEEN_MINUTES: '15m', 58 | THIRTY_MINUTES: '30m', 59 | ONE_HOUR: '1h', 60 | TWO_HOURS: '2h', 61 | FOUR_HOURS: '4h', 62 | SIX_HOURS: '6h', 63 | EIGHT_HOURS: '8h', 64 | TWELVE_HOURS: '12h', 65 | ONE_DAY: '1d', 66 | THREE_DAYS: '3d', 67 | ONE_WEEK: '1w', 68 | ONE_MONTH: '1M', 69 | } 70 | 71 | export const DepositStatus = { 72 | PENDING: 0, 73 | SUCCESS: 1, 74 | } 75 | 76 | export const WithdrawStatus = { 77 | EMAIL_SENT: 0, 78 | CANCELLED: 1, 79 | AWAITING_APPROVAL: 2, 80 | REJECTED: 3, 81 | PROCESSING: 4, 82 | FAILURE: 5, 83 | COMPLETED: 6, 84 | } 85 | 86 | export const SavingsStatus = { 87 | HOLDING: 'HOLDING', 88 | REDEEMED: 'REDEEMED', 89 | TRANSFERRED: 'TRANSFERRED', 90 | } 91 | 92 | export const SavingsType = { 93 | FAST: 'FAST', 94 | NORMAL: 'NORMAL', 95 | } 96 | 97 | export const MiningAlgo = { 98 | SHA256: 'sha256', 99 | SCRYPT: 'scrypt', 100 | ETHASH: 'ethash', 101 | X11: 'x11', 102 | } 103 | 104 | export const MiningStatus = { 105 | HASH_RATE: 'hash_rate', 106 | REJECTED: 'rejected', 107 | EARNINGS: 'earnings', 108 | } 109 | 110 | export const ConvertStatus = { 111 | PROCESSING: 'PROCESSING', 112 | SUCCESS: 'SUCCESS', 113 | FAILURE: 'FAILURE', 114 | } 115 | 116 | export const PayStatus = { 117 | PENDING: 'PENDING', 118 | SUCCESS: 'SUCCESS', 119 | FAILED: 'FAILED', 120 | } 121 | -------------------------------------------------------------------------------- /src/open-websocket.js: -------------------------------------------------------------------------------- 1 | import ws from 'isomorphic-ws' 2 | import ReconnectingWebSocket from 'reconnecting-websocket' 3 | 4 | export default (url, opts) => { 5 | const rws = new ReconnectingWebSocket(url, [], { 6 | WebSocket: ws, 7 | connectionTimeout: 4e3, 8 | debug: false, 9 | maxReconnectionDelay: 10e3, 10 | maxRetries: Infinity, 11 | minReconnectionDelay: 4e3, 12 | ...opts, 13 | }) 14 | 15 | // TODO Maybe we have to pass the proxy to this line 16 | // https://github.com/pladaria/reconnecting-websocket/blob/05a2f7cb0e31f15dff5ff35ad53d07b1bec5e197/reconnecting-websocket.ts#L383 17 | 18 | const pong = () => rws._ws.pong(() => null) 19 | 20 | rws.addEventListener('open', () => { 21 | // .on only works in node env, not in browser. https://github.com/Ashlar/binance-api-node/issues/404#issuecomment-833668033 22 | if (rws._ws.on) { 23 | rws._ws.on('ping', pong) 24 | } 25 | }) 26 | 27 | return rws 28 | } 29 | -------------------------------------------------------------------------------- /src/websocket.js: -------------------------------------------------------------------------------- 1 | import zip from 'lodash.zipobject' 2 | import JSONbig from 'json-bigint' 3 | 4 | import httpMethods from 'http-client' 5 | import _openWebSocket from 'open-websocket' 6 | 7 | const endpoints = { 8 | base: 'wss://stream.binance.com:9443/ws', 9 | futures: 'wss://fstream.binance.com/ws', 10 | delivery: 'wss://dstream.binance.com/ws', 11 | } 12 | 13 | const wsOptions = {} 14 | 15 | function openWebSocket(url) { 16 | return _openWebSocket(url, wsOptions) 17 | } 18 | 19 | const depthTransform = m => ({ 20 | eventType: m.e, 21 | eventTime: m.E, 22 | symbol: m.s, 23 | firstUpdateId: m.U, 24 | finalUpdateId: m.u, 25 | bidDepth: m.b.map(b => zip(['price', 'quantity'], b)), 26 | askDepth: m.a.map(a => zip(['price', 'quantity'], a)), 27 | }) 28 | 29 | const futuresDepthTransform = m => ({ 30 | eventType: m.e, 31 | eventTime: m.E, 32 | transactionTime: m.T, 33 | symbol: m.s, 34 | firstUpdateId: m.U, 35 | finalUpdateId: m.u, 36 | prevFinalUpdateId: m.pu, 37 | bidDepth: m.b.map(b => zip(['price', 'quantity'], b)), 38 | askDepth: m.a.map(a => zip(['price', 'quantity'], a)), 39 | }) 40 | 41 | const deliveryDepthTransform = m => ({ 42 | eventType: m.e, 43 | eventTime: m.E, 44 | transactionTime: m.T, 45 | symbol: m.s, 46 | pair: m.ps, 47 | firstUpdateId: m.U, 48 | finalUpdateId: m.u, 49 | prevFinalUpdateId: m.pu, 50 | bidDepth: m.b.map(b => zip(['price', 'quantity'], b)), 51 | askDepth: m.a.map(a => zip(['price', 'quantity'], a)), 52 | }) 53 | 54 | const depth = (payload, cb, transform = true, variator) => { 55 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 56 | const [symbolName, updateSpeed] = symbol.toLowerCase().split('@') 57 | const w = openWebSocket( 58 | `${variator ? endpoints[variator] : endpoints.base}/${symbolName}@depth${ 59 | updateSpeed ? `@${updateSpeed}` : '' 60 | }`, 61 | ) 62 | w.onmessage = msg => { 63 | const obj = JSONbig.parse(msg.data) 64 | 65 | cb( 66 | transform 67 | ? variator === 'futures' 68 | ? futuresDepthTransform(obj) 69 | : variator === 'delivery' 70 | ? deliveryDepthTransform(obj) 71 | : depthTransform(obj) 72 | : obj, 73 | ) 74 | } 75 | 76 | return w 77 | }) 78 | 79 | return options => 80 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 81 | } 82 | 83 | const partialDepthTransform = (symbol, level, m) => ({ 84 | symbol, 85 | level, 86 | lastUpdateId: m.lastUpdateId, 87 | bids: m.bids.map(b => zip(['price', 'quantity'], b)), 88 | asks: m.asks.map(a => zip(['price', 'quantity'], a)), 89 | }) 90 | 91 | const futuresPartDepthTransform = (level, m) => ({ 92 | level, 93 | eventType: m.e, 94 | eventTime: m.E, 95 | transactionTime: m.T, 96 | symbol: m.s, 97 | firstUpdateId: m.U, 98 | finalUpdateId: m.u, 99 | prevFinalUpdateId: m.pu, 100 | bidDepth: m.b.map(b => zip(['price', 'quantity'], b)), 101 | askDepth: m.a.map(a => zip(['price', 'quantity'], a)), 102 | }) 103 | 104 | const deliveryPartDepthTransform = (level, m) => ({ 105 | level, 106 | eventType: m.e, 107 | eventTime: m.E, 108 | transactionTime: m.T, 109 | symbol: m.s, 110 | pair: m.ps, 111 | firstUpdateId: m.U, 112 | finalUpdateId: m.u, 113 | prevFinalUpdateId: m.pu, 114 | bidDepth: m.b.map(b => zip(['price', 'quantity'], b)), 115 | askDepth: m.a.map(a => zip(['price', 'quantity'], a)), 116 | }) 117 | 118 | const partialDepth = (payload, cb, transform = true, variator) => { 119 | const cache = (Array.isArray(payload) ? payload : [payload]).map(({ symbol, level }) => { 120 | const [symbolName, updateSpeed] = symbol.toLowerCase().split('@') 121 | const w = openWebSocket( 122 | `${variator ? endpoints[variator] : endpoints.base}/${symbolName}@depth${level}${ 123 | updateSpeed ? `@${updateSpeed}` : '' 124 | }`, 125 | ) 126 | w.onmessage = msg => { 127 | const obj = JSONbig.parse(msg.data) 128 | 129 | cb( 130 | transform 131 | ? variator === 'futures' 132 | ? futuresPartDepthTransform(level, obj) 133 | : variator === 'delivery' 134 | ? deliveryPartDepthTransform(level, obj) 135 | : partialDepthTransform(symbol, level, obj) 136 | : obj, 137 | ) 138 | } 139 | 140 | return w 141 | }) 142 | 143 | return options => 144 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 145 | } 146 | 147 | const candleTransform = m => ({ 148 | startTime: m.t, 149 | closeTime: m.T, 150 | firstTradeId: m.f, 151 | lastTradeId: m.L, 152 | open: m.o, 153 | high: m.h, 154 | low: m.l, 155 | close: m.c, 156 | volume: m.v, 157 | trades: m.n, 158 | interval: m.i, 159 | isFinal: m.x, 160 | quoteVolume: m.q, 161 | buyVolume: m.V, 162 | quoteBuyVolume: m.Q, 163 | }) 164 | 165 | const deliveryCandleTransform = m => ({ 166 | startTime: m.t, 167 | closeTime: m.T, 168 | firstTradeId: m.f, 169 | lastTradeId: m.L, 170 | open: m.o, 171 | high: m.h, 172 | low: m.l, 173 | close: m.c, 174 | volume: m.v, 175 | trades: m.n, 176 | interval: m.i, 177 | isFinal: m.x, 178 | baseVolume: m.q, 179 | buyVolume: m.V, 180 | baseBuyVolume: m.Q, 181 | }) 182 | 183 | const candles = (payload, interval, cb, transform = true, variator) => { 184 | if (!interval || !cb) { 185 | throw new Error('Please pass a symbol, interval and callback.') 186 | } 187 | 188 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 189 | const w = openWebSocket( 190 | `${ 191 | variator ? endpoints[variator] : endpoints.base 192 | }/${symbol.toLowerCase()}@kline_${interval}`, 193 | ) 194 | w.onmessage = msg => { 195 | const obj = JSONbig.parse(msg.data) 196 | const { e: eventType, E: eventTime, s: symbol, k: tick } = obj 197 | 198 | cb( 199 | transform 200 | ? { 201 | eventType, 202 | eventTime, 203 | symbol, 204 | ...(variator === 'delivery' ? deliveryCandleTransform(tick) : candleTransform(tick)), 205 | } 206 | : obj, 207 | ) 208 | } 209 | 210 | return w 211 | }) 212 | 213 | return options => 214 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 215 | } 216 | 217 | const bookTickerTransform = m => ({ 218 | updateId: m.u, 219 | symbol: m.s, 220 | bestBid: m.b, 221 | bestBidQnt: m.B, 222 | bestAsk: m.a, 223 | bestAskQnt: m.A, 224 | }) 225 | 226 | const miniTickerTransform = m => ({ 227 | eventType: m.e, 228 | eventTime: m.E, 229 | symbol: m.s, 230 | curDayClose: m.c, 231 | open: m.o, 232 | high: m.h, 233 | low: m.l, 234 | volume: m.v, 235 | volumeQuote: m.q, 236 | }) 237 | 238 | const deliveryMiniTickerTransform = m => ({ 239 | eventType: m.e, 240 | eventTime: m.E, 241 | symbol: m.s, 242 | pair: m.ps, 243 | curDayClose: m.c, 244 | open: m.o, 245 | high: m.h, 246 | low: m.l, 247 | volume: m.v, 248 | volumeBase: m.q, 249 | }) 250 | 251 | const tickerTransform = m => ({ 252 | eventType: m.e, 253 | eventTime: m.E, 254 | symbol: m.s, 255 | priceChange: m.p, 256 | priceChangePercent: m.P, 257 | weightedAvg: m.w, 258 | prevDayClose: m.x, 259 | curDayClose: m.c, 260 | closeTradeQuantity: m.Q, 261 | bestBid: m.b, 262 | bestBidQnt: m.B, 263 | bestAsk: m.a, 264 | bestAskQnt: m.A, 265 | open: m.o, 266 | high: m.h, 267 | low: m.l, 268 | volume: m.v, 269 | volumeQuote: m.q, 270 | openTime: m.O, 271 | closeTime: m.C, 272 | firstTradeId: m.F, 273 | lastTradeId: m.L, 274 | totalTrades: m.n, 275 | }) 276 | 277 | const futuresTickerTransform = m => ({ 278 | eventType: m.e, 279 | eventTime: m.E, 280 | symbol: m.s, 281 | priceChange: m.p, 282 | priceChangePercent: m.P, 283 | weightedAvg: m.w, 284 | curDayClose: m.c, 285 | closeTradeQuantity: m.Q, 286 | open: m.o, 287 | high: m.h, 288 | low: m.l, 289 | volume: m.v, 290 | volumeQuote: m.q, 291 | openTime: m.O, 292 | closeTime: m.C, 293 | firstTradeId: m.F, 294 | lastTradeId: m.L, 295 | totalTrades: m.n, 296 | }) 297 | 298 | const deliveryTickerTransform = m => ({ 299 | eventType: m.e, 300 | eventTime: m.E, 301 | symbol: m.s, 302 | pair: m.ps, 303 | priceChange: m.p, 304 | priceChangePercent: m.P, 305 | weightedAvg: m.w, 306 | curDayClose: m.c, 307 | closeTradeQuantity: m.Q, 308 | open: m.o, 309 | high: m.h, 310 | low: m.l, 311 | volume: m.v, 312 | volumeBase: m.q, 313 | openTime: m.O, 314 | closeTime: m.C, 315 | firstTradeId: m.F, 316 | lastTradeId: m.L, 317 | totalTrades: m.n, 318 | }) 319 | 320 | const bookTicker = (payload, cb, transform = true) => { 321 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 322 | const w = openWebSocket(`${endpoints.base}/${symbol.toLowerCase()}@bookTicker`) 323 | 324 | w.onmessage = msg => { 325 | const obj = JSONbig.parse(msg.data) 326 | cb(transform ? bookTickerTransform(obj) : obj) 327 | } 328 | 329 | return w 330 | }) 331 | 332 | return options => 333 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 334 | } 335 | 336 | const ticker = (payload, cb, transform = true, variator) => { 337 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 338 | const w = openWebSocket( 339 | `${ 340 | variator === 'futures' 341 | ? endpoints.futures 342 | : variator === 'delivery' 343 | ? endpoints.delivery 344 | : endpoints.base 345 | }/${symbol.toLowerCase()}@ticker`, 346 | ) 347 | 348 | w.onmessage = msg => { 349 | const obj = JSONbig.parse(msg.data) 350 | cb( 351 | transform 352 | ? variator === 'futures' 353 | ? futuresTickerTransform(obj) 354 | : variator === 'delivery' 355 | ? deliveryTickerTransform(obj) 356 | : tickerTransform(obj) 357 | : obj, 358 | ) 359 | } 360 | 361 | return w 362 | }) 363 | 364 | return options => 365 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 366 | } 367 | 368 | const allTickers = (cb, transform = true, variator) => { 369 | const w = new openWebSocket( 370 | `${ 371 | variator === 'futures' 372 | ? endpoints.futures 373 | : variator === 'delivery' 374 | ? endpoints.delivery 375 | : endpoints.base 376 | }/!ticker@arr`, 377 | ) 378 | 379 | w.onmessage = msg => { 380 | const arr = JSONbig.parse(msg.data) 381 | cb( 382 | transform 383 | ? variator === 'futures' 384 | ? arr.map(m => futuresTickerTransform(m)) 385 | : variator === 'delivery' 386 | ? arr.map(m => deliveryTickerTransform(m)) 387 | : arr.map(m => tickerTransform(m)) 388 | : arr, 389 | ) 390 | } 391 | 392 | return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options }) 393 | } 394 | 395 | const miniTicker = (payload, cb, transform = true, variator) => { 396 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 397 | const w = openWebSocket(`${endpoints.base}/${symbol.toLowerCase()}@miniTicker`) 398 | 399 | w.onmessage = msg => { 400 | const obj = JSONbig.parse(msg.data) 401 | cb( 402 | transform 403 | ? variator === 'delivery' 404 | ? deliveryMiniTickerTransform(obj) 405 | : miniTickerTransform(obj) 406 | : obj, 407 | ) 408 | } 409 | 410 | return w 411 | }) 412 | 413 | return options => 414 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 415 | } 416 | 417 | const allMiniTickers = (cb, transform = true, variator) => { 418 | const w = openWebSocket(`${endpoints.base}/!miniTicker@arr`) 419 | 420 | w.onmessage = msg => { 421 | const arr = JSONbig.parse(msg.data) 422 | cb( 423 | transform 424 | ? arr.map(variator === 'delivery' ? deliveryMiniTickerTransform : miniTickerTransform) 425 | : arr, 426 | ) 427 | } 428 | 429 | return options => w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options }) 430 | } 431 | 432 | const customSubStream = (payload, cb, variator) => { 433 | const cache = (Array.isArray(payload) ? payload : [payload]).map(sub => { 434 | const w = openWebSocket( 435 | `${ 436 | variator === 'futures' 437 | ? endpoints.futures 438 | : variator === 'delivery' 439 | ? endpoints.delivery 440 | : endpoints.base 441 | }/${sub}`, 442 | ) 443 | 444 | w.onmessage = msg => { 445 | const data = JSONbig.parse(msg.data) 446 | cb(data) 447 | } 448 | 449 | return w 450 | }) 451 | 452 | return options => 453 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 454 | } 455 | 456 | const aggTradesTransform = m => ({ 457 | eventType: m.e, 458 | eventTime: m.E, 459 | timestamp: m.T, 460 | symbol: m.s, 461 | price: m.p, 462 | quantity: m.q, 463 | isBuyerMaker: m.m, 464 | wasBestPrice: m.M, 465 | aggId: m.a, 466 | firstId: m.f, 467 | lastId: m.l, 468 | }) 469 | 470 | const futuresAggTradesTransform = m => ({ 471 | eventType: m.e, 472 | eventTime: m.E, 473 | symbol: m.s, 474 | aggId: m.a, 475 | price: m.p, 476 | quantity: m.q, 477 | firstId: m.f, 478 | lastId: m.l, 479 | timestamp: m.T, 480 | isBuyerMaker: m.m, 481 | }) 482 | 483 | const aggTrades = (payload, cb, transform = true, variator) => { 484 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 485 | const w = openWebSocket( 486 | `${ 487 | variator === 'futures' 488 | ? endpoints.futures 489 | : variator === 'delivery' 490 | ? endpoints.delivery 491 | : endpoints.base 492 | }/${symbol.toLowerCase()}@aggTrade`, 493 | ) 494 | w.onmessage = msg => { 495 | const obj = JSONbig.parse(msg.data) 496 | 497 | cb( 498 | transform 499 | ? variator === 'futures' || variator === 'delivery' 500 | ? futuresAggTradesTransform(obj) 501 | : aggTradesTransform(obj) 502 | : obj, 503 | ) 504 | } 505 | 506 | return w 507 | }) 508 | 509 | return options => 510 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 511 | } 512 | 513 | const futuresLiqsTransform = m => ({ 514 | symbol: m.s, 515 | price: m.p, 516 | origQty: m.q, 517 | lastFilledQty: m.l, 518 | accumulatedQty: m.z, 519 | averagePrice: m.ap, 520 | status: m.X, 521 | timeInForce: m.f, 522 | type: m.o, 523 | side: m.S, 524 | time: m.T, 525 | }) 526 | 527 | const futuresLiquidations = (payload, cb, transform = true) => { 528 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 529 | const w = openWebSocket(`${endpoints.futures}/${symbol.toLowerCase()}@forceOrder`) 530 | w.onmessage = msg => { 531 | const obj = JSONbig.parse(msg.data) 532 | 533 | cb(transform ? futuresLiqsTransform(obj.o) : obj) 534 | } 535 | 536 | return w 537 | }) 538 | 539 | return options => 540 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 541 | } 542 | 543 | const futuresAllLiquidations = (cb, transform = true) => { 544 | const w = new openWebSocket(`${endpoints.futures}/!forceOrder@arr`) 545 | 546 | w.onmessage = msg => { 547 | const obj = JSONbig.parse(msg.data) 548 | cb(transform ? futuresLiqsTransform(obj.o) : obj) 549 | } 550 | 551 | return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options }) 552 | } 553 | 554 | const tradesTransform = m => ({ 555 | eventType: m.e, 556 | eventTime: m.E, 557 | tradeTime: m.T, 558 | symbol: m.s, 559 | price: m.p, 560 | quantity: m.q, 561 | isBuyerMaker: m.m, 562 | maker: m.M, 563 | tradeId: m.t, 564 | buyerOrderId: m.b, 565 | sellerOrderId: m.a, 566 | }) 567 | 568 | const trades = (payload, cb, transform = true) => { 569 | const cache = (Array.isArray(payload) ? payload : [payload]).map(symbol => { 570 | const w = openWebSocket(`${endpoints.base}/${symbol.toLowerCase()}@trade`) 571 | w.onmessage = msg => { 572 | const obj = JSONbig.parse(msg.data) 573 | cb(transform ? tradesTransform(obj) : obj) 574 | } 575 | 576 | return w 577 | }) 578 | 579 | return options => 580 | cache.forEach(w => w.close(1000, 'Close handle was called', { keepClosed: true, ...options })) 581 | } 582 | 583 | const userTransforms = { 584 | // https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md#balance-update 585 | balanceUpdate: m => ({ 586 | asset: m.a, 587 | balanceDelta: m.d, 588 | clearTime: m.T, 589 | eventTime: m.E, 590 | eventType: 'balanceUpdate', 591 | }), 592 | // https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md#account-update 593 | outboundAccountInfo: m => ({ 594 | eventType: 'account', 595 | eventTime: m.E, 596 | makerCommissionRate: m.m, 597 | takerCommissionRate: m.t, 598 | buyerCommissionRate: m.b, 599 | sellerCommissionRate: m.s, 600 | canTrade: m.T, 601 | canWithdraw: m.W, 602 | canDeposit: m.D, 603 | lastAccountUpdate: m.u, 604 | balances: m.B.reduce((out, cur) => { 605 | out[cur.a] = { available: cur.f, locked: cur.l } 606 | return out 607 | }, {}), 608 | }), 609 | // https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md#account-update 610 | outboundAccountPosition: m => ({ 611 | balances: m.B.map(({ a, f, l }) => ({ asset: a, free: f, locked: l })), 612 | eventTime: m.E, 613 | eventType: 'outboundAccountPosition', 614 | lastAccountUpdate: m.u, 615 | }), 616 | // https://github.com/binance-exchange/binance-official-api-docs/blob/master/user-data-stream.md#order-update 617 | executionReport: m => ({ 618 | eventType: 'executionReport', 619 | eventTime: m.E, 620 | symbol: m.s, 621 | newClientOrderId: m.c, 622 | originalClientOrderId: m.C, 623 | side: m.S, 624 | orderType: m.o, 625 | timeInForce: m.f, 626 | quantity: m.q, 627 | price: m.p, 628 | executionType: m.x, 629 | stopPrice: m.P, 630 | trailingDelta: m.d, 631 | icebergQuantity: m.F, 632 | orderStatus: m.X, 633 | orderRejectReason: m.r, 634 | orderId: m.i, 635 | orderTime: m.T, 636 | lastTradeQuantity: m.l, 637 | totalTradeQuantity: m.z, 638 | priceLastTrade: m.L, 639 | commission: m.n, 640 | commissionAsset: m.N, 641 | tradeId: m.t, 642 | isOrderWorking: m.w, 643 | isBuyerMaker: m.m, 644 | creationTime: m.O, 645 | totalQuoteTradeQuantity: m.Z, 646 | orderListId: m.g, 647 | quoteOrderQuantity: m.Q, 648 | lastQuoteTransacted: m.Y, 649 | trailingTime: m.D, 650 | }), 651 | listStatus: m => ({ 652 | eventType: 'listStatus', 653 | eventTime: m.E, 654 | symbol: m.s, 655 | orderListId: m.g, 656 | contingencyType: m.c, 657 | listStatusType: m.l, 658 | listOrderStatus: m.L, 659 | listRejectReason: m.r, 660 | listClientOrderId: m.C, 661 | transactionTime: m.T, 662 | orders: m.O.map(o => ({ 663 | symbol: o.s, 664 | orderId: o.i, 665 | clientOrderId: o.c, 666 | })), 667 | }), 668 | } 669 | 670 | const futuresUserTransforms = { 671 | // https://binance-docs.github.io/apidocs/futures/en/#close-user-data-stream-user_stream 672 | listenKeyExpired: function USER_DATA_STREAM_EXPIRED(m) { 673 | return { 674 | eventTime: m.E, 675 | eventType: 'USER_DATA_STREAM_EXPIRED', 676 | } 677 | }, 678 | // https://binance-docs.github.io/apidocs/futures/en/#event-margin-call 679 | MARGIN_CALL: m => ({ 680 | eventTime: m.E, 681 | crossWalletBalance: m.cw, 682 | eventType: 'MARGIN_CALL', 683 | positions: m.p.map(cur => ({ 684 | symbol: cur.s, 685 | positionSide: cur.ps, 686 | positionAmount: cur.pa, 687 | marginType: cur.mt, 688 | isolatedWallet: cur.iw, 689 | markPrice: cur.mp, 690 | unrealizedPnL: cur.up, 691 | maintenanceMarginRequired: cur.mm, 692 | })), 693 | }), 694 | // https://binance-docs.github.io/apidocs/futures/en/#event-balance-and-position-update 695 | ACCOUNT_UPDATE: m => ({ 696 | eventTime: m.E, 697 | transactionTime: m.T, 698 | eventType: 'ACCOUNT_UPDATE', 699 | eventReasonType: m.a.m, 700 | balances: m.a.B.map(b => ({ 701 | asset: b.a, 702 | walletBalance: b.wb, 703 | crossWalletBalance: b.cw, 704 | balanceChange: b.bc, 705 | })), 706 | positions: m.a.P.map(p => ({ 707 | symbol: p.s, 708 | positionAmount: p.pa, 709 | entryPrice: p.ep, 710 | accumulatedRealized: p.cr, 711 | unrealizedPnL: p.up, 712 | marginType: p.mt, 713 | isolatedWallet: p.iw, 714 | positionSide: p.ps, 715 | })), 716 | }), 717 | // https://binance-docs.github.io/apidocs/futures/en/#event-order-update 718 | ORDER_TRADE_UPDATE: m => ({ 719 | eventType: 'ORDER_TRADE_UPDATE', 720 | eventTime: m.E, 721 | transactionTime: m.T, 722 | symbol: m.o.s, 723 | clientOrderId: m.o.c, 724 | side: m.o.S, 725 | orderType: m.o.o, 726 | timeInForce: m.o.f, 727 | quantity: m.o.q, 728 | price: m.o.p, 729 | averagePrice: m.o.ap, 730 | stopPrice: m.o.sp, 731 | executionType: m.o.x, 732 | orderStatus: m.o.X, 733 | orderId: m.o.i, 734 | lastTradeQuantity: m.o.l, 735 | totalTradeQuantity: m.o.z, 736 | priceLastTrade: m.o.L, 737 | commissionAsset: m.o.N, 738 | commission: m.o.n, 739 | orderTime: m.o.T, 740 | tradeId: m.o.t, 741 | bidsNotional: m.o.b, 742 | asksNotional: m.o.a, 743 | isMaker: m.o.m, 744 | isReduceOnly: m.o.R, 745 | workingType: m.o.wt, 746 | originalOrderType: m.o.ot, 747 | positionSide: m.o.ps, 748 | closePosition: m.o.cp, 749 | activationPrice: m.o.AP, 750 | callbackRate: m.o.cr, 751 | realizedProfit: m.o.rp, 752 | }), 753 | // https://binance-docs.github.io/apidocs/futures/en/#event-account-configuration-update-previous-leverage-update 754 | ACCOUNT_CONFIG_UPDATE: m => ({ 755 | eventType: 'ACCOUNT_CONFIG_UPDATE', 756 | eventTime: m.E, 757 | transactionTime: m.T, 758 | type: m.ac ? 'ACCOUNT_CONFIG' : 'MULTI_ASSETS', 759 | ...(m.ac 760 | ? { 761 | symbol: m.ac.s, 762 | leverage: m.ac.l, 763 | } 764 | : { 765 | multiAssets: m.ai.j, 766 | }), 767 | }), 768 | } 769 | 770 | export const userEventHandler = 771 | (cb, transform = true, variator) => 772 | msg => { 773 | const { e: type, ...rest } = JSONbig.parse(msg.data) 774 | 775 | cb( 776 | variator === 'futures' || variator === 'delivery' 777 | ? transform && futuresUserTransforms[type] 778 | ? futuresUserTransforms[type](rest) 779 | : { type, ...rest } 780 | : transform && userTransforms[type] 781 | ? userTransforms[type](rest) 782 | : { type, ...rest }, 783 | ) 784 | } 785 | 786 | const userOpenHandler = 787 | (cb, transform = true) => 788 | () => { 789 | cb({ [transform ? 'eventType' : 'type']: 'open' }) 790 | } 791 | 792 | const userErrorHandler = 793 | (cb, transform = true) => 794 | error => { 795 | cb({ [transform ? 'eventType' : 'type']: 'error', error }) 796 | } 797 | 798 | const STREAM_METHODS = ['get', 'keep', 'close'] 799 | 800 | const capitalize = (str, check) => (check ? `${str[0].toUpperCase()}${str.slice(1)}` : str) 801 | 802 | const getStreamMethods = (opts, variator = '') => { 803 | const methods = httpMethods(opts) 804 | 805 | return STREAM_METHODS.reduce( 806 | (acc, key) => [...acc, methods[`${variator}${capitalize(`${key}DataStream`, !!variator)}`]], 807 | [], 808 | ) 809 | } 810 | 811 | export const keepStreamAlive = (method, listenKey) => method({ listenKey }) 812 | 813 | const user = (opts, variator) => (cb, transform) => { 814 | const [getDataStream, keepDataStream, closeDataStream] = getStreamMethods(opts, variator) 815 | 816 | let currentListenKey = null 817 | let int = null 818 | let w = null 819 | let keepClosed = false 820 | const errorHandler = userErrorHandler(cb, transform) 821 | 822 | const keepAlive = isReconnecting => { 823 | if (currentListenKey) { 824 | keepStreamAlive(keepDataStream, currentListenKey).catch(err => { 825 | closeStream({}, true) 826 | 827 | if (isReconnecting) { 828 | setTimeout(() => makeStream(true), 30e3) 829 | } else { 830 | makeStream(true) 831 | } 832 | 833 | if (opts.emitStreamErrors) { 834 | errorHandler(err) 835 | } 836 | }) 837 | } 838 | } 839 | 840 | const closeStream = (options, catchErrors, setKeepClosed = false) => { 841 | keepClosed = setKeepClosed 842 | 843 | if (!currentListenKey) { 844 | return Promise.resolve() 845 | } 846 | 847 | clearInterval(int) 848 | 849 | const p = closeDataStream({ listenKey: currentListenKey }) 850 | 851 | if (catchErrors) { 852 | p.catch(f => f) 853 | } 854 | 855 | w.close(1000, 'Close handle was called', { keepClosed: true, ...options }) 856 | currentListenKey = null 857 | 858 | return p 859 | } 860 | 861 | const makeStream = isReconnecting => { 862 | return ( 863 | !keepClosed && 864 | getDataStream() 865 | .then(({ listenKey }) => { 866 | if (keepClosed) { 867 | return closeDataStream({ listenKey }).catch(f => f) 868 | } 869 | 870 | w = openWebSocket( 871 | `${ 872 | variator === 'futures' 873 | ? endpoints.futures 874 | : variator === 'delivery' 875 | ? endpoints.delivery 876 | : endpoints.base 877 | }/${listenKey}`, 878 | ) 879 | 880 | w.onmessage = msg => userEventHandler(cb, transform, variator)(msg) 881 | if (opts.emitSocketOpens) { 882 | w.onopen = () => userOpenHandler(cb, transform)() 883 | } 884 | if (opts.emitSocketErrors) { 885 | w.onerror = ({ error }) => errorHandler(error) 886 | } 887 | 888 | currentListenKey = listenKey 889 | 890 | int = setInterval(() => keepAlive(false), 50e3) 891 | 892 | keepAlive(true) 893 | 894 | return options => closeStream(options, false, true) 895 | }) 896 | .catch(err => { 897 | if (isReconnecting) { 898 | if (!keepClosed) { 899 | setTimeout(() => makeStream(true), 30e3) 900 | } 901 | 902 | if (opts.emitStreamErrors) { 903 | errorHandler(err) 904 | } 905 | } else { 906 | throw err 907 | } 908 | }) 909 | ) 910 | } 911 | 912 | return makeStream(false) 913 | } 914 | 915 | const futuresAllMarkPricesTransform = m => 916 | m.map(x => ({ 917 | eventType: x.e, 918 | eventTime: x.E, 919 | symbol: x.s, 920 | markPrice: x.p, 921 | indexPrice: x.i, 922 | settlePrice: x.P, 923 | fundingRate: x.r, 924 | nextFundingRate: x.T, 925 | })) 926 | 927 | const futuresAllMarkPrices = (payload, cb, transform = true) => { 928 | const variant = payload.updateSpeed === '1s' ? '!markPrice@arr@1s' : '!markPrice@arr' 929 | 930 | const w = openWebSocket(`${endpoints.futures}/${variant}`) 931 | 932 | w.onmessage = msg => { 933 | const arr = JSONbig.parse(msg.data) 934 | cb(transform ? futuresAllMarkPricesTransform(arr) : arr) 935 | } 936 | 937 | return options => w.close(1000, 'Close handle was called', { keepClosed: true, ...options }) 938 | } 939 | 940 | export default opts => { 941 | if (opts && opts.wsBase) endpoints.base = opts.wsBase 942 | if (opts && opts.wsFutures) endpoints.futures = opts.wsFutures 943 | if (opts && opts.wsDelivery) endpoints.delivery = opts.wsDelivery 944 | 945 | if (opts && opts.proxy) { 946 | wsOptions.proxy = opts.proxy 947 | } 948 | 949 | return { 950 | depth, 951 | partialDepth, 952 | candles, 953 | trades, 954 | aggTrades, 955 | bookTicker, 956 | ticker, 957 | allTickers, 958 | miniTicker, 959 | allMiniTickers, 960 | customSubStream, 961 | user: user(opts), 962 | 963 | marginUser: user(opts, 'margin'), 964 | 965 | futuresDepth: (payload, cb, transform) => depth(payload, cb, transform, 'futures'), 966 | deliveryDepth: (payload, cb, transform) => depth(payload, cb, transform, 'delivery'), 967 | futuresPartialDepth: (payload, cb, transform) => 968 | partialDepth(payload, cb, transform, 'futures'), 969 | deliveryPartialDepth: (payload, cb, transform) => 970 | partialDepth(payload, cb, transform, 'delivery'), 971 | futuresCandles: (payload, interval, cb, transform) => 972 | candles(payload, interval, cb, transform, 'futures'), 973 | deliveryCandles: (payload, interval, cb, transform) => 974 | candles(payload, interval, cb, transform, 'delivery'), 975 | futuresTicker: (payload, cb, transform) => ticker(payload, cb, transform, 'futures'), 976 | deliveryTicker: (payload, cb, transform) => ticker(payload, cb, transform, 'delivery'), 977 | futuresAllTickers: (cb, transform) => allTickers(cb, transform, 'futures'), 978 | deliveryAllTickers: (cb, transform) => allTickers(cb, transform, 'delivery'), 979 | futuresAggTrades: (payload, cb, transform) => aggTrades(payload, cb, transform, 'futures'), 980 | deliveryAggTrades: (payload, cb, transform) => aggTrades(payload, cb, transform, 'delivery'), 981 | futuresLiquidations, 982 | futuresAllLiquidations, 983 | futuresUser: user(opts, 'futures'), 984 | deliveryUser: user(opts, 'delivery'), 985 | futuresCustomSubStream: (payload, cb) => customSubStream(payload, cb, 'futures'), 986 | deliveryCustomSubStream: (payload, cb) => customSubStream(payload, cb, 'delivery'), 987 | futuresAllMarkPrices: (payload, cb) => futuresAllMarkPrices(payload, cb), 988 | } 989 | } 990 | -------------------------------------------------------------------------------- /test/auth.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | import dotenv from 'dotenv' 3 | 4 | import Binance from 'index' 5 | 6 | import { checkFields } from './utils' 7 | 8 | dotenv.config() 9 | 10 | const main = () => { 11 | if (!process.env.API_KEY || !process.env.API_SECRET) { 12 | return test('[AUTH] ⚠️ Skipping tests.', t => { 13 | t.log('Provide an API_KEY and API_SECRET to run them.') 14 | t.pass() 15 | }) 16 | } 17 | 18 | const client = Binance({ 19 | apiKey: process.env.API_KEY, 20 | apiSecret: process.env.API_SECRET, 21 | }) 22 | 23 | test('[REST] order', async t => { 24 | try { 25 | await client.orderTest({ 26 | symbol: 'ETHBTC', 27 | side: 'BUY', 28 | quantity: 1, 29 | price: 1, 30 | }) 31 | } catch (e) { 32 | t.is(e.message, 'Filter failure: PERCENT_PRICE') 33 | } 34 | 35 | await client.orderTest({ 36 | symbol: 'ETHBTC', 37 | side: 'BUY', 38 | quantity: 1, 39 | type: 'MARKET', 40 | }) 41 | 42 | t.pass() 43 | }) 44 | 45 | test('[REST] make a MARKET order with quoteOrderQty', async t => { 46 | try { 47 | await client.orderTest({ 48 | symbol: 'ETHBTC', 49 | side: 'BUY', 50 | quoteOrderQty: 10, 51 | type: 'MARKET', 52 | }) 53 | } catch (e) { 54 | t.is(e.message, 'Filter failure: PERCENT_PRICE') 55 | } 56 | 57 | await client.orderTest({ 58 | symbol: 'ETHBTC', 59 | side: 'BUY', 60 | quantity: 1, 61 | type: 'MARKET', 62 | }) 63 | 64 | t.pass() 65 | }) 66 | 67 | test('[REST] allOrders / getOrder', async t => { 68 | try { 69 | await client.getOrder({ symbol: 'ASTETH' }) 70 | } catch (e) { 71 | t.is( 72 | e.message, 73 | "Param 'origClientOrderId' or 'orderId' must be sent, but both were empty/null!", 74 | ) 75 | } 76 | 77 | try { 78 | await client.getOrder({ symbol: 'ASTETH', orderId: 1 }) 79 | } catch (e) { 80 | t.is(e.message, 'Order does not exist.') 81 | } 82 | 83 | // Note that this test will fail if you don't have any ETH/BTC order in your account 84 | const orders = await client.allOrders({ 85 | symbol: 'ETHBTC', 86 | }) 87 | 88 | t.true(Array.isArray(orders)) 89 | t.truthy(orders.length) 90 | 91 | const [order] = orders 92 | 93 | checkFields(t, order, ['orderId', 'symbol', 'price', 'type', 'side']) 94 | 95 | const res = await client.getOrder({ 96 | symbol: 'ETHBTC', 97 | orderId: order.orderId, 98 | }) 99 | 100 | t.truthy(res) 101 | checkFields(t, res, ['orderId', 'symbol', 'price', 'type', 'side']) 102 | }) 103 | 104 | test('[REST] allOrdersOCO', async t => { 105 | const orderLists = await client.allOrdersOCO({ 106 | timestamp: new Date().getTime(), 107 | }) 108 | 109 | t.true(Array.isArray(orderLists)) 110 | 111 | if (orderLists.length) { 112 | const [orderList] = orderLists 113 | checkFields(t, orderList, [ 114 | 'orderListId', 115 | 'symbol', 116 | 'transactionTime', 117 | 'listStatusType', 118 | 'orders', 119 | ]) 120 | } 121 | }) 122 | 123 | test('[REST] getOrder with useServerTime', async t => { 124 | const orders = await client.allOrders({ 125 | symbol: 'ETHBTC', 126 | useServerTime: true, 127 | }) 128 | 129 | t.true(Array.isArray(orders)) 130 | t.truthy(orders.length) 131 | }) 132 | 133 | test('[REST] openOrders', async t => { 134 | const orders = await client.openOrders({ 135 | symbol: 'ETHBTC', 136 | }) 137 | 138 | t.true(Array.isArray(orders)) 139 | }) 140 | 141 | test('[REST] cancelOrder', async t => { 142 | try { 143 | await client.cancelOrder({ symbol: 'ETHBTC', orderId: 1 }) 144 | } catch (e) { 145 | t.is(e.message, 'Unknown order sent.') 146 | } 147 | }) 148 | 149 | test('[REST] cancelOpenOrders', async t => { 150 | try { 151 | await client.cancelOpenOrders({ symbol: 'ETHBTC' }) 152 | } catch (e) { 153 | t.is(e.message, 'Unknown order sent.') 154 | } 155 | }) 156 | 157 | test('[REST] accountInfo', async t => { 158 | const account = await client.accountInfo() 159 | t.truthy(account) 160 | checkFields(t, account, ['makerCommission', 'takerCommission', 'balances']) 161 | t.truthy(account.balances.length) 162 | }) 163 | 164 | test('[REST] tradeFee', async t => { 165 | const tfee = (await client.tradeFee()).tradeFee 166 | t.truthy(tfee) 167 | t.truthy(tfee.length) 168 | checkFields(t, tfee[0], ['symbol', 'maker', 'taker']) 169 | }) 170 | 171 | test('[REST] depositHistory', async t => { 172 | const history = await client.depositHistory() 173 | t.true(history.success) 174 | t.truthy(Array.isArray(history.depositList)) 175 | }) 176 | 177 | test('[REST] withdrawHistory', async t => { 178 | const history = await client.withdrawHistory() 179 | t.true(history.success) 180 | t.is(typeof history.withdrawList.length, 'number') 181 | }) 182 | 183 | test('[REST] depositAddress', async t => { 184 | const out = await client.depositAddress({ asset: 'ETH' }) 185 | t.true(out.success) 186 | t.is(out.asset, 'ETH') 187 | t.truthy(out.address) 188 | }) 189 | 190 | test('[REST] myTrades', async t => { 191 | const trades = await client.myTrades({ symbol: 'ETHBTC' }) 192 | t.true(Array.isArray(trades)) 193 | const [trade] = trades 194 | checkFields(t, trade, ['id', 'orderId', 'qty', 'commission', 'time']) 195 | }) 196 | 197 | test('[REST] tradesHistory', async t => { 198 | const trades = await client.tradesHistory({ symbol: 'ETHBTC', fromId: 28457 }) 199 | t.is(trades.length, 500) 200 | }) 201 | 202 | test('[REST] error code', async t => { 203 | try { 204 | await client.orderTest({ 205 | symbol: 'TRXETH', 206 | side: 'SELL', 207 | type: 'LIMIT', 208 | quantity: '-1337.00000000', 209 | price: '1.00000000', 210 | }) 211 | } catch (e) { 212 | t.is(e.code, -1100) 213 | } 214 | }) 215 | 216 | test('[WS] user', async t => { 217 | const clean = await client.ws.user() 218 | t.truthy(clean) 219 | t.true(typeof clean === 'function') 220 | }) 221 | 222 | test('[FUTURES-REST] walletBalance', async t => { 223 | const walletBalance = await client.futuresAccountBalance() 224 | t.truthy(walletBalance) 225 | checkFields(t, walletBalance[0], [ 226 | 'asset', 227 | 'balance', 228 | 'crossWalletBalance', 229 | 'crossUnPnl', 230 | 'availableBalance', 231 | 'maxWithdrawAmount', 232 | ]) 233 | }) 234 | 235 | test('[DELIVERY-REST] walletBalance', async t => { 236 | const walletBalance = await client.deliveryAccountBalance() 237 | t.truthy(walletBalance) 238 | checkFields(t, walletBalance[0], [ 239 | 'asset', 240 | 'balance', 241 | 'withdrawAvailable', 242 | 'crossWalletBalance', 243 | 'crossUnPnl', 244 | 'availableBalance', 245 | 'maxWithdrawAmount', 246 | ]) 247 | }) 248 | } 249 | 250 | main() 251 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import test from 'ava' 2 | 3 | import Binance, { ErrorCodes } from 'index' 4 | import { candleFields, deliveryCandleFields } from 'http-client' 5 | import { userEventHandler } from 'websocket' 6 | 7 | import { checkFields, createHttpServer } from './utils' 8 | 9 | const client = Binance() 10 | 11 | test('[MISC] Some error codes are defined', t => { 12 | t.truthy(ErrorCodes, 'The map is there') 13 | t.truthy(ErrorCodes.TOO_MANY_ORDERS, 'And we have this') 14 | }) 15 | 16 | test('[REST] ping', async t => { 17 | t.truthy(await client.ping(), 'A simple ping should work') 18 | }) 19 | 20 | test('[REST] time', async t => { 21 | const ts = await client.time() 22 | t.truthy(new Date(ts).getTime() > 0, 'The returned timestamp should be valid') 23 | }) 24 | 25 | test('[REST] exchangeInfo', async t => { 26 | const res = await client.exchangeInfo() 27 | checkFields(t, res, ['timezone', 'serverTime', 'rateLimits', 'symbols']) 28 | }) 29 | 30 | test('[REST] book', async t => { 31 | try { 32 | await client.book() 33 | } catch (e) { 34 | t.is(e.message, 'You need to pass a payload object.') 35 | } 36 | 37 | try { 38 | await client.book({}) 39 | } catch (e) { 40 | t.is(e.message, 'Method book requires symbol parameter.') 41 | } 42 | 43 | const book = await client.book({ symbol: 'ETHBTC' }) 44 | t.truthy(book.lastUpdateId) 45 | t.truthy(book.asks.length) 46 | t.truthy(book.bids.length) 47 | 48 | const [bid] = book.bids 49 | t.truthy(typeof bid.price === 'string') 50 | t.truthy(typeof bid.quantity === 'string') 51 | }) 52 | 53 | test('[REST] candles', async t => { 54 | try { 55 | await client.candles({}) 56 | } catch (e) { 57 | t.is(e.message, 'Method candles requires symbol parameter.') 58 | } 59 | 60 | const candles = await client.candles({ symbol: 'ETHBTC' }) 61 | 62 | t.truthy(candles.length) 63 | 64 | const [candle] = candles 65 | checkFields(t, candle, candleFields) 66 | }) 67 | 68 | test('[REST] aggTrades', async t => { 69 | try { 70 | await client.aggTrades({}) 71 | } catch (e) { 72 | t.is(e.message, 'Method aggTrades requires symbol parameter.') 73 | } 74 | 75 | const trades = await client.aggTrades({ symbol: 'ETHBTC' }) 76 | t.truthy(trades.length) 77 | 78 | const [trade] = trades 79 | t.truthy(trade.aggId) 80 | t.truthy(trade.symbol) 81 | }) 82 | 83 | test('[REST] trades', async t => { 84 | const trades = await client.trades({ symbol: 'ETHBTC' }) 85 | t.is(trades.length, 500) 86 | }) 87 | 88 | test('[REST] dailyStats', async t => { 89 | const res = await client.dailyStats({ symbol: 'ETHBTC' }) 90 | t.truthy(res) 91 | checkFields(t, res, ['highPrice', 'lowPrice', 'volume', 'priceChange']) 92 | }) 93 | 94 | test('[REST] prices', async t => { 95 | const prices = await client.prices() 96 | t.truthy(prices) 97 | t.truthy(prices.ETHBTC) 98 | }) 99 | 100 | test('[REST] individual price', async t => { 101 | const prices = await client.prices({ symbol: 'ETHUSDT' }) 102 | t.truthy(prices) 103 | t.truthy(prices.ETHUSDT) 104 | }) 105 | 106 | test('[REST] avgPrice', async t => { 107 | const res = await client.avgPrice({ symbol: 'ETHBTC' }) 108 | t.truthy(res) 109 | checkFields(t, res, ['mins', 'price']) 110 | }) 111 | 112 | test('[REST] allBookTickers', async t => { 113 | const tickers = await client.allBookTickers() 114 | t.truthy(tickers) 115 | t.truthy(tickers.ETHBTC) 116 | }) 117 | 118 | test('[REST] Signed call without creds', async t => { 119 | try { 120 | await client.accountInfo() 121 | } catch (e) { 122 | t.is(e.message, 'You need to pass an API key and secret to make authenticated calls.') 123 | } 124 | }) 125 | 126 | test('[REST] Signed call without creds - attempt getting tradeFee', async t => { 127 | try { 128 | await client.tradeFee() 129 | } catch (e) { 130 | t.is(e.message, 'You need to pass an API key and secret to make authenticated calls.') 131 | } 132 | }) 133 | 134 | test('[REST] Server-side JSON error', async t => { 135 | const server = createHttpServer((req, res) => { 136 | res.statusCode = 500 137 | res.write( 138 | JSON.stringify({ 139 | msg: 'Server unkown error', 140 | code: -1337, 141 | }), 142 | ) 143 | res.end() 144 | }) 145 | const localClient = Binance({ httpBase: server.url }) 146 | 147 | try { 148 | await server.start() 149 | await localClient.ping() 150 | t.fail('did not throw') 151 | } catch (e) { 152 | t.is(e.message, 'Server unkown error') 153 | t.is(e.code, -1337) 154 | } finally { 155 | await server.stop() 156 | } 157 | }) 158 | 159 | test('[REST] Server-side HTML error', async t => { 160 | const serverReponse = 'Server Internal Error' 161 | const server = createHttpServer((req, res) => { 162 | res.statusCode = 500 163 | res.write(serverReponse) 164 | res.end() 165 | }) 166 | const localClient = Binance({ httpBase: server.url }) 167 | 168 | try { 169 | await server.start() 170 | await localClient.ping() 171 | t.fail('did not throw') 172 | } catch (e) { 173 | t.is(e.message, `500 Internal Server Error ${serverReponse}`) 174 | t.truthy(e.response) 175 | t.is(e.responseText, serverReponse) 176 | } finally { 177 | await server.stop() 178 | } 179 | }) 180 | 181 | test('[WS] depth', t => { 182 | return new Promise(resolve => { 183 | client.ws.depth('ETHBTC', depth => { 184 | checkFields(t, depth, [ 185 | 'eventType', 186 | 'eventTime', 187 | 'firstUpdateId', 188 | 'finalUpdateId', 189 | 'symbol', 190 | 'bidDepth', 191 | 'askDepth', 192 | ]) 193 | resolve() 194 | }) 195 | }) 196 | }) 197 | 198 | test('[WS] depth with update speed', t => { 199 | return new Promise(resolve => { 200 | client.ws.depth('ETHBTC@100ms', depth => { 201 | checkFields(t, depth, [ 202 | 'eventType', 203 | 'eventTime', 204 | 'firstUpdateId', 205 | 'finalUpdateId', 206 | 'symbol', 207 | 'bidDepth', 208 | 'askDepth', 209 | ]) 210 | resolve() 211 | }) 212 | }) 213 | }) 214 | 215 | test('[WS] partial depth', t => { 216 | return new Promise(resolve => { 217 | client.ws.partialDepth({ symbol: 'ETHBTC', level: 10 }, depth => { 218 | checkFields(t, depth, ['lastUpdateId', 'bids', 'asks']) 219 | resolve() 220 | }) 221 | }) 222 | }) 223 | 224 | test('[WS] partial depth with update speed', t => { 225 | return new Promise(resolve => { 226 | client.ws.partialDepth({ symbol: 'ETHBTC@100ms', level: 10 }, depth => { 227 | checkFields(t, depth, ['lastUpdateId', 'bids', 'asks']) 228 | resolve() 229 | }) 230 | }) 231 | }) 232 | 233 | test('[WS] ticker', t => { 234 | return new Promise(resolve => { 235 | client.ws.ticker('ETHBTC', ticker => { 236 | checkFields(t, ticker, ['open', 'high', 'low', 'eventTime', 'symbol', 'volume']) 237 | resolve() 238 | }) 239 | }) 240 | }) 241 | 242 | test('[WS] allTicker', t => { 243 | return new Promise(resolve => { 244 | client.ws.allTickers(tickers => { 245 | t.truthy(Array.isArray(tickers)) 246 | t.is(tickers[0].eventType, '24hrTicker') 247 | checkFields(t, tickers[0], ['symbol', 'priceChange', 'priceChangePercent']) 248 | resolve() 249 | }) 250 | }) 251 | }) 252 | 253 | test('[WS] miniTicker', t => { 254 | return new Promise(resolve => { 255 | client.ws.miniTicker('ETHBTC', ticker => { 256 | checkFields(t, ticker, [ 257 | 'open', 258 | 'high', 259 | 'low', 260 | 'curDayClose', 261 | 'eventTime', 262 | 'symbol', 263 | 'volume', 264 | 'volumeQuote', 265 | ]) 266 | resolve() 267 | }) 268 | }) 269 | }) 270 | 271 | test('[WS] allMiniTickers', t => { 272 | return new Promise(resolve => { 273 | client.ws.allMiniTickers(tickers => { 274 | t.truthy(Array.isArray(tickers)) 275 | t.is(tickers[0].eventType, '24hrMiniTicker') 276 | checkFields(t, tickers[0], [ 277 | 'open', 278 | 'high', 279 | 'low', 280 | 'curDayClose', 281 | 'eventTime', 282 | 'symbol', 283 | 'volume', 284 | 'volumeQuote', 285 | ]) 286 | resolve() 287 | }) 288 | }) 289 | }) 290 | 291 | test('[WS] candles', t => { 292 | try { 293 | client.ws.candles('ETHBTC', d => d) 294 | } catch (e) { 295 | t.is(e.message, 'Please pass a symbol, interval and callback.') 296 | } 297 | 298 | return new Promise(resolve => { 299 | client.ws.candles(['ETHBTC', 'BNBBTC', 'BNTBTC'], '5m', candle => { 300 | checkFields(t, candle, ['open', 'high', 'low', 'close', 'volume', 'trades', 'quoteVolume']) 301 | resolve() 302 | }) 303 | }) 304 | }) 305 | 306 | test('[WS] trades', t => { 307 | return new Promise(resolve => { 308 | client.ws.trades(['BNBBTC', 'ETHBTC', 'BNTBTC'], trade => { 309 | checkFields(t, trade, [ 310 | 'eventType', 311 | 'tradeId', 312 | 'tradeTime', 313 | 'quantity', 314 | 'price', 315 | 'symbol', 316 | // 'buyerOrderId', 317 | // 'sellerOrderId', 318 | ]) 319 | resolve() 320 | }) 321 | }) 322 | }) 323 | 324 | test('[WS] aggregate trades', t => { 325 | return new Promise(resolve => { 326 | client.ws.aggTrades(['BNBBTC', 'ETHBTC', 'BNTBTC'], trade => { 327 | checkFields(t, trade, [ 328 | 'eventType', 329 | 'aggId', 330 | 'timestamp', 331 | 'quantity', 332 | 'price', 333 | 'symbol', 334 | 'firstId', 335 | 'lastId', 336 | ]) 337 | resolve() 338 | }) 339 | }) 340 | }) 341 | 342 | test.skip('[WS] liquidations', t => { 343 | return new Promise(resolve => { 344 | client.ws.futuresLiquidations('ETHBTC', liquidation => { 345 | checkFields(t, liquidation, [ 346 | 'symbol', 347 | 'price', 348 | 'origQty', 349 | 'lastFilledQty', 350 | 'accumulatedQty', 351 | 'averagePrice', 352 | 'status', 353 | 'timeInForce', 354 | 'type', 355 | 'side', 356 | 'time', 357 | ]) 358 | resolve() 359 | }) 360 | }) 361 | }) 362 | 363 | test.skip('[FUTURES-WS] all liquidations', t => { 364 | return new Promise(resolve => { 365 | client.ws.futuresAllLiquidations(liquidation => { 366 | checkFields(t, liquidation, [ 367 | 'symbol', 368 | 'price', 369 | 'origQty', 370 | 'lastFilledQty', 371 | 'accumulatedQty', 372 | 'averagePrice', 373 | 'status', 374 | 'timeInForce', 375 | 'type', 376 | 'side', 377 | 'time', 378 | ]) 379 | resolve() 380 | }) 381 | }) 382 | }) 383 | 384 | test('[WS] userEvents', t => { 385 | const accountPayload = { 386 | e: 'outboundAccountInfo', 387 | E: 1499405658849, 388 | m: 0, 389 | t: 0, 390 | b: 0, 391 | s: 0, 392 | T: true, 393 | W: true, 394 | D: true, 395 | u: 1499405658849, 396 | B: [ 397 | { 398 | a: 'LTC', 399 | f: '17366.18538083', 400 | l: '0.00000000', 401 | }, 402 | { 403 | a: 'BTC', 404 | f: '10537.85314051', 405 | l: '2.19464093', 406 | }, 407 | { 408 | a: 'ETH', 409 | f: '17902.35190619', 410 | l: '0.00000000', 411 | }, 412 | { 413 | a: 'BNC', 414 | f: '1114503.29769312', 415 | l: '0.00000000', 416 | }, 417 | { 418 | a: 'NEO', 419 | f: '0.00000000', 420 | l: '0.00000000', 421 | }, 422 | ], 423 | } 424 | 425 | userEventHandler(res => { 426 | t.deepEqual(res, { 427 | eventType: 'account', 428 | eventTime: 1499405658849, 429 | makerCommissionRate: 0, 430 | takerCommissionRate: 0, 431 | buyerCommissionRate: 0, 432 | sellerCommissionRate: 0, 433 | canTrade: true, 434 | canWithdraw: true, 435 | canDeposit: true, 436 | lastAccountUpdate: 1499405658849, 437 | balances: { 438 | LTC: { available: '17366.18538083', locked: '0.00000000' }, 439 | BTC: { available: '10537.85314051', locked: '2.19464093' }, 440 | ETH: { available: '17902.35190619', locked: '0.00000000' }, 441 | BNC: { available: '1114503.29769312', locked: '0.00000000' }, 442 | NEO: { available: '0.00000000', locked: '0.00000000' }, 443 | }, 444 | }) 445 | })({ data: JSON.stringify(accountPayload) }) 446 | 447 | const orderPayload = { 448 | e: 'executionReport', 449 | E: 1499405658658, 450 | s: 'ETHBTC', 451 | c: 'mUvoqJxFIILMdfAW5iGSOW', 452 | S: 'BUY', 453 | o: 'LIMIT', 454 | f: 'GTC', 455 | q: '1.00000000', 456 | p: '0.10264410', 457 | P: '0.10285410', 458 | F: '0.00000000', 459 | g: -1, 460 | C: 'null', 461 | x: 'NEW', 462 | X: 'NEW', 463 | r: 'NONE', 464 | i: 4293153, 465 | l: '0.00000000', 466 | z: '0.00000000', 467 | L: '0.00000000', 468 | n: '0', 469 | N: null, 470 | T: 1499405658657, 471 | t: -1, 472 | I: 8641984, 473 | w: true, 474 | m: false, 475 | M: false, 476 | O: 1499405658657, 477 | Q: 0, 478 | Y: 0, 479 | Z: '0.00000000', 480 | } 481 | 482 | userEventHandler(res => { 483 | t.deepEqual(res, { 484 | commission: '0', 485 | commissionAsset: null, 486 | creationTime: 1499405658657, 487 | eventTime: 1499405658658, 488 | eventType: 'executionReport', 489 | executionType: 'NEW', 490 | icebergQuantity: '0.00000000', 491 | isBuyerMaker: false, 492 | isOrderWorking: true, 493 | lastQuoteTransacted: 0, 494 | lastTradeQuantity: '0.00000000', 495 | newClientOrderId: 'mUvoqJxFIILMdfAW5iGSOW', 496 | orderId: 4293153, 497 | orderListId: -1, 498 | orderRejectReason: 'NONE', 499 | orderStatus: 'NEW', 500 | orderTime: 1499405658657, 501 | orderType: 'LIMIT', 502 | originalClientOrderId: 'null', 503 | price: '0.10264410', 504 | priceLastTrade: '0.00000000', 505 | quantity: '1.00000000', 506 | quoteOrderQuantity: 0, 507 | side: 'BUY', 508 | stopPrice: '0.10285410', 509 | symbol: 'ETHBTC', 510 | timeInForce: 'GTC', 511 | totalQuoteTradeQuantity: '0.00000000', 512 | totalTradeQuantity: '0.00000000', 513 | tradeId: -1, 514 | trailingDelta: undefined, 515 | trailingTime: undefined, 516 | }) 517 | })({ data: JSON.stringify(orderPayload) }) 518 | 519 | const tradePayload = { 520 | e: 'executionReport', 521 | E: 1499406026404, 522 | s: 'ETHBTC', 523 | c: '1hRLKJhTRsXy2ilYdSzhkk', 524 | S: 'BUY', 525 | o: 'LIMIT', 526 | f: 'GTC', 527 | q: '22.42906458', 528 | p: '0.10279999', 529 | P: '0.10280001', 530 | F: '0.00000000', 531 | g: -1, 532 | C: 'null', 533 | x: 'TRADE', 534 | X: 'FILLED', 535 | r: 'NONE', 536 | i: 4294220, 537 | l: '17.42906458', 538 | z: '22.42906458', 539 | L: '0.10279999', 540 | n: '0.00000001', 541 | N: 'BNC', 542 | T: 1499406026402, 543 | t: 77517, 544 | I: 8644124, 545 | w: false, 546 | m: false, 547 | M: true, 548 | O: 1499405658657, 549 | Q: 0, 550 | Y: 0, 551 | Z: '2.30570761', 552 | } 553 | 554 | userEventHandler(res => { 555 | t.deepEqual(res, { 556 | eventType: 'executionReport', 557 | eventTime: 1499406026404, 558 | symbol: 'ETHBTC', 559 | newClientOrderId: '1hRLKJhTRsXy2ilYdSzhkk', 560 | originalClientOrderId: 'null', 561 | side: 'BUY', 562 | orderType: 'LIMIT', 563 | timeInForce: 'GTC', 564 | quantity: '22.42906458', 565 | price: '0.10279999', 566 | stopPrice: '0.10280001', 567 | executionType: 'TRADE', 568 | icebergQuantity: '0.00000000', 569 | orderStatus: 'FILLED', 570 | orderRejectReason: 'NONE', 571 | orderId: 4294220, 572 | orderTime: 1499406026402, 573 | lastTradeQuantity: '17.42906458', 574 | totalTradeQuantity: '22.42906458', 575 | priceLastTrade: '0.10279999', 576 | commission: '0.00000001', 577 | commissionAsset: 'BNC', 578 | tradeId: 77517, 579 | isOrderWorking: false, 580 | isBuyerMaker: false, 581 | creationTime: 1499405658657, 582 | totalQuoteTradeQuantity: '2.30570761', 583 | lastQuoteTransacted: 0, 584 | orderListId: -1, 585 | quoteOrderQuantity: 0, 586 | trailingDelta: undefined, 587 | trailingTime: undefined, 588 | }) 589 | })({ data: JSON.stringify(tradePayload) }) 590 | 591 | const listStatusPayload = { 592 | e: 'listStatus', 593 | E: 1661588112531, 594 | s: 'TWTUSDT', 595 | g: 73129826, 596 | c: 'OCO', 597 | l: 'EXEC_STARTED', 598 | L: 'EXECUTING', 599 | r: 'NONE', 600 | C: 'Y3ZgLMRPHZFNqEVSZwoJI7', 601 | T: 1661588112530, 602 | O: [ 603 | { 604 | s: 'TWTUSDT', 605 | i: 209259206, 606 | c: 'electron_f675d1bdea454cd4afeac5664be', 607 | }, 608 | { 609 | s: 'TWTUSDT', 610 | i: 209259207, 611 | c: 'electron_38d852a65a89486c98e59879327', 612 | }, 613 | ], 614 | } 615 | 616 | userEventHandler(res => { 617 | t.deepEqual(res, { 618 | eventType: 'listStatus', 619 | eventTime: 1661588112531, 620 | symbol: 'TWTUSDT', 621 | orderListId: 73129826, 622 | contingencyType: 'OCO', 623 | listStatusType: 'EXEC_STARTED', 624 | listOrderStatus: 'EXECUTING', 625 | listRejectReason: 'NONE', 626 | listClientOrderId: 'Y3ZgLMRPHZFNqEVSZwoJI7', 627 | transactionTime: 1661588112530, 628 | orders: [ 629 | { 630 | symbol: 'TWTUSDT', 631 | orderId: 209259206, 632 | clientOrderId: 'electron_f675d1bdea454cd4afeac5664be', 633 | }, 634 | { 635 | symbol: 'TWTUSDT', 636 | orderId: 209259207, 637 | clientOrderId: 'electron_38d852a65a89486c98e59879327', 638 | }, 639 | ], 640 | }) 641 | })({ data: JSON.stringify(listStatusPayload) }) 642 | 643 | const newEvent = { e: 'totallyNewEvent', yolo: 42 } 644 | 645 | userEventHandler(res => { 646 | t.deepEqual(res, { type: 'totallyNewEvent', yolo: 42 }) 647 | })({ data: JSON.stringify(newEvent) }) 648 | }) 649 | 650 | // FUTURES TESTS 651 | 652 | test('[FUTURES-REST] ping', async t => { 653 | t.truthy(await client.futuresPing(), 'A simple ping should work') 654 | }) 655 | 656 | test('[FUTURES-REST] time', async t => { 657 | const ts = await client.futuresTime() 658 | t.truthy(new Date(ts).getTime() > 0, 'The returned timestamp should be valid') 659 | }) 660 | 661 | test('[FUTURES-REST] exchangeInfo', async t => { 662 | const res = await client.futuresExchangeInfo() 663 | checkFields(t, res, ['timezone', 'serverTime', 'rateLimits', 'symbols']) 664 | }) 665 | 666 | test('[FUTURES-REST] book', async t => { 667 | try { 668 | await client.futuresBook() 669 | } catch (e) { 670 | t.is(e.message, 'You need to pass a payload object.') 671 | } 672 | 673 | try { 674 | await client.futuresBook({}) 675 | } catch (e) { 676 | t.is(e.message, 'Method book requires symbol parameter.') 677 | } 678 | 679 | const book = await client.futuresBook({ symbol: 'BTCUSDT' }) 680 | t.truthy(book.lastUpdateId) 681 | t.truthy(book.asks.length) 682 | t.truthy(book.bids.length) 683 | 684 | const [bid] = book.bids 685 | t.truthy(typeof bid.price === 'string') 686 | t.truthy(typeof bid.quantity === 'string') 687 | }) 688 | 689 | test('[FUTURES-REST] markPrice', async t => { 690 | const res = await client.futuresMarkPrice() 691 | t.truthy(Array.isArray(res)) 692 | checkFields(t, res[0], ['symbol', 'markPrice', 'lastFundingRate', 'nextFundingTime', 'time']) 693 | }) 694 | 695 | test.skip('[FUTURES-REST] allForceOrders', async t => { 696 | const res = await client.futuresAllForceOrders() 697 | t.truthy(Array.isArray(res)) 698 | t.truthy(res.length === 100) 699 | checkFields(t, res[0], [ 700 | 'symbol', 701 | 'price', 702 | 'origQty', 703 | 'executedQty', 704 | 'averagePrice', 705 | 'timeInForce', 706 | 'type', 707 | 'side', 708 | 'time', 709 | ]) 710 | }) 711 | 712 | test('[FUTURES-REST] candles', async t => { 713 | try { 714 | await client.futuresCandles({}) 715 | } catch (e) { 716 | t.is(e.message, 'Method candles requires symbol parameter.') 717 | } 718 | 719 | const candles = await client.futuresCandles({ symbol: 'BTCUSDT' }) 720 | 721 | t.truthy(candles.length) 722 | 723 | const [candle] = candles 724 | checkFields(t, candle, candleFields) 725 | }) 726 | 727 | test('[FUTURES-REST] mark price candles', async t => { 728 | try { 729 | await client.futuresMarkPriceCandles({}) 730 | } catch (e) { 731 | t.is(e.message, 'Method candles requires symbol parameter.') 732 | } 733 | 734 | const candles = await client.futuresMarkPriceCandles({ symbol: 'BTCUSDT' }) 735 | 736 | t.truthy(candles.length) 737 | 738 | const [candle] = candles 739 | checkFields(t, candle, candleFields) 740 | }) 741 | 742 | test('[FUTURES-REST] index price candles', async t => { 743 | try { 744 | await client.futuresIndexPriceCandles({}) 745 | } catch (e) { 746 | t.is(e.message, 'Method candles requires pair parameter.') 747 | } 748 | 749 | const candles = await client.futuresIndexPriceCandles({ pair: 'BTCUSDT' }) 750 | 751 | t.truthy(candles.length) 752 | 753 | const [candle] = candles 754 | checkFields(t, candle, candleFields) 755 | }) 756 | 757 | test('[FUTURES-REST] trades', async t => { 758 | const trades = await client.futuresTrades({ symbol: 'BTCUSDT', limit: 10 }) 759 | t.is(trades.length, 10) 760 | checkFields(t, trades[0], ['id', 'price', 'qty', 'quoteQty', 'time']) 761 | }) 762 | 763 | test('[FUTURES-REST] dailyStats', async t => { 764 | const res = await client.futuresDailyStats({ symbol: 'BTCUSDT' }) 765 | t.truthy(res) 766 | checkFields(t, res, ['highPrice', 'lowPrice', 'volume', 'priceChange']) 767 | }) 768 | 769 | test('[FUTURES-REST] prices', async t => { 770 | const prices = await client.futuresPrices() 771 | t.truthy(prices) 772 | t.truthy(prices.BTCUSDT) 773 | }) 774 | 775 | test('[FUTURES-REST] allBookTickers', async t => { 776 | const tickers = await client.futuresAllBookTickers() 777 | t.truthy(tickers) 778 | t.truthy(tickers.BTCUSDT) 779 | }) 780 | 781 | test('[FUTURES-REST] aggTrades', async t => { 782 | try { 783 | await client.futuresAggTrades({}) 784 | } catch (e) { 785 | t.is(e.message, 'Method aggTrades requires symbol parameter.') 786 | } 787 | 788 | const trades = await client.futuresAggTrades({ symbol: 'BTCUSDT' }) 789 | t.truthy(trades.length) 790 | 791 | const [trade] = trades 792 | t.truthy(trade.aggId) 793 | }) 794 | 795 | test('[FUTURES-REST] fundingRate', async t => { 796 | const fundingRate = await client.futuresFundingRate({ symbol: 'BTCUSDT' }) 797 | checkFields(t, fundingRate[0], ['symbol', 'fundingTime', 'fundingRate']) 798 | t.is(fundingRate.length, 100) 799 | }) 800 | 801 | // DELIVERY TESTS 802 | 803 | test('[DELIVERY-REST] ping', async t => { 804 | t.truthy(await client.deliveryPing(), 'A simple ping should work') 805 | }) 806 | 807 | test('[DELIVERY-REST] time', async t => { 808 | const ts = await client.deliveryTime() 809 | t.truthy(new Date(ts).getTime() > 0, 'The returned timestamp should be valid') 810 | }) 811 | 812 | test('[DELIVERY-REST] exchangeInfo', async t => { 813 | const res = await client.deliveryExchangeInfo() 814 | checkFields(t, res, ['timezone', 'serverTime', 'rateLimits', 'exchangeFilters', 'symbols']) 815 | }) 816 | 817 | test('[DELIVERY-REST] book', async t => { 818 | try { 819 | await client.deliveryBook() 820 | } catch (e) { 821 | t.is(e.message, 'You need to pass a payload object.') 822 | } 823 | 824 | try { 825 | await client.deliveryBook({}) 826 | } catch (e) { 827 | t.is(e.message, 'Method book requires symbol parameter.') 828 | } 829 | 830 | const book = await client.deliveryBook({ symbol: 'TRXUSD_perp' }) 831 | t.truthy(book.lastUpdateId) 832 | t.truthy(book.asks.length) 833 | t.truthy(book.bids.length) 834 | 835 | const [bid] = book.bids 836 | t.truthy(typeof bid.price === 'string') 837 | t.truthy(typeof bid.quantity === 'string') 838 | }) 839 | 840 | test('[DELIVERY-REST] markPrice', async t => { 841 | const res = await client.deliveryMarkPrice() 842 | t.truthy(Array.isArray(res)) 843 | checkFields(t, res[0], [ 844 | 'symbol', 845 | 'pair', 846 | 'markPrice', 847 | 'indexPrice', 848 | 'estimatedSettlePrice', 849 | 'time', 850 | ]) 851 | }) 852 | 853 | test('[DELIVERY-REST] candles', async t => { 854 | try { 855 | await client.deliveryCandles({}) 856 | } catch (e) { 857 | t.is(e.message, 'Method candles requires symbol parameter.') 858 | } 859 | 860 | const candles = await client.deliveryCandles({ symbol: 'TRXUSD_perp' }) 861 | 862 | t.truthy(candles.length) 863 | 864 | const [candle] = candles 865 | checkFields(t, candle, deliveryCandleFields) 866 | }) 867 | 868 | test('[DELIVERY-REST] mark price candles', async t => { 869 | try { 870 | await client.deliveryMarkPriceCandles({}) 871 | } catch (e) { 872 | t.is(e.message, 'Method candles requires symbol parameter.') 873 | } 874 | 875 | const candles = await client.deliveryMarkPriceCandles({ symbol: 'TRXUSD_perp' }) 876 | 877 | t.truthy(candles.length) 878 | 879 | const [candle] = candles 880 | checkFields(t, candle, deliveryCandleFields) 881 | }) 882 | 883 | test('[DELIVERY-REST] index price candles', async t => { 884 | try { 885 | await client.deliveryIndexPriceCandles({}) 886 | } catch (e) { 887 | t.is(e.message, 'Method candles requires pair parameter.') 888 | } 889 | 890 | const candles = await client.deliveryIndexPriceCandles({ pair: 'TRXUSD' }) 891 | 892 | t.truthy(candles.length) 893 | 894 | const [candle] = candles 895 | checkFields(t, candle, deliveryCandleFields) 896 | }) 897 | 898 | test('[DELIVERY-REST] trades', async t => { 899 | const trades = await client.deliveryTrades({ symbol: 'TRXUSD_perp', limit: 10 }) 900 | t.is(trades.length, 10) 901 | checkFields(t, trades[0], ['id', 'price', 'qty', 'baseQty', 'time']) 902 | }) 903 | 904 | test('[DELIVERY-REST] dailyStats', async t => { 905 | const res = await client.deliveryDailyStats({ symbol: 'TRXUSD_perp' }) 906 | t.truthy(res) 907 | // Note : delivery API always returns an array hence the res[0] 908 | checkFields(t, res[0], ['pair', 'highPrice', 'lowPrice', 'volume', 'priceChange']) 909 | }) 910 | 911 | test('[DELIVERY-REST] prices', async t => { 912 | const prices = await client.deliveryPrices() 913 | t.truthy(prices) 914 | t.truthy(prices.TRXUSD_PERP) 915 | }) 916 | 917 | test('[DELIVERY-REST] allBookTickers', async t => { 918 | const tickers = await client.deliveryAllBookTickers() 919 | t.truthy(tickers) 920 | t.truthy(tickers.TRXUSD_PERP) 921 | }) 922 | 923 | test('[DELIVERY-REST] aggTrades', async t => { 924 | try { 925 | await client.deliveryAggTrades({}) 926 | } catch (e) { 927 | t.is(e.message, 'Method aggTrades requires symbol parameter.') 928 | } 929 | 930 | const trades = await client.deliveryAggTrades({ symbol: 'TRXUSD_perp' }) 931 | t.truthy(trades.length) 932 | 933 | const [trade] = trades 934 | t.truthy(trade.aggId) 935 | }) 936 | 937 | test('[DELIVERY-REST] fundingRate', async t => { 938 | const fundingRate = await client.deliveryFundingRate({ symbol: 'TRXUSD_perp' }) 939 | checkFields(t, fundingRate[0], ['symbol', 'fundingTime', 'fundingRate']) 940 | t.is(fundingRate.length, 100) 941 | }) 942 | -------------------------------------------------------------------------------- /test/types.ts: -------------------------------------------------------------------------------- 1 | import type { BinanceRest } from '../index.d' 2 | import { OrderType, OrderSide, TimeInForce } from '../types/base' 3 | import test from 'ava' 4 | 5 | // This type represents all methods from http-client.js 6 | type HttpClientMethods = { 7 | getInfo: () => Promise 8 | ping: () => Promise 9 | time: () => Promise<{ serverTime: number }> 10 | exchangeInfo: (payload?: any) => Promise 11 | book: (payload: { symbol: string }) => Promise 12 | aggTrades: (payload: { symbol: string }) => Promise 13 | candles: (payload: { symbol: string; interval: string }) => Promise 14 | trades: (payload: { symbol: string }) => Promise 15 | tradesHistory: (payload: { symbol: string }) => Promise 16 | dailyStats: (payload: { symbol: string }) => Promise 17 | prices: () => Promise 18 | avgPrice: (payload: { symbol: string }) => Promise 19 | allBookTickers: () => Promise 20 | order: (payload: any) => Promise 21 | orderOco: (payload: any) => Promise 22 | orderTest: (payload: any) => Promise 23 | getOrder: (payload: any) => Promise 24 | getOrderOco: (payload: any) => Promise 25 | cancelOrder: (payload: any) => Promise 26 | cancelOrderOco: (payload: any) => Promise 27 | cancelOpenOrders: (payload: any) => Promise 28 | openOrders: (payload?: any) => Promise 29 | allOrders: (payload: any) => Promise 30 | allOrdersOCO: (payload: any) => Promise 31 | accountInfo: (payload?: any) => Promise 32 | myTrades: (payload: any) => Promise 33 | withdraw: (payload: any) => Promise 34 | withdrawHistory: (payload: any) => Promise 35 | depositHistory: (payload: any) => Promise 36 | depositAddress: (payload: any) => Promise 37 | tradeFee: (payload: any) => Promise 38 | assetDetail: (payload: any) => Promise 39 | accountSnapshot: (payload: any) => Promise 40 | universalTransfer: (payload: any) => Promise 41 | universalTransferHistory: (payload: any) => Promise 42 | dustLog: (payload?: any) => Promise 43 | dustTransfer: (payload: any) => Promise 44 | accountCoins: (payload?: any) => Promise 45 | getBnbBurn: (payload?: any) => Promise 46 | setBnbBurn: (payload: any) => Promise 47 | capitalConfigs: () => Promise 48 | 49 | // User Data Stream endpoints 50 | getDataStream: () => Promise 51 | keepDataStream: (payload: any) => Promise 52 | closeDataStream: (payload: any) => Promise 53 | marginGetDataStream: () => Promise 54 | marginKeepDataStream: (payload: any) => Promise 55 | marginCloseDataStream: (payload: any) => Promise 56 | futuresGetDataStream: () => Promise 57 | futuresKeepDataStream: (payload: any) => Promise 58 | futuresCloseDataStream: (payload: any) => Promise 59 | deliveryGetDataStream: () => Promise 60 | deliveryKeepDataStream: (payload: any) => Promise 61 | deliveryCloseDataStream: (payload: any) => Promise 62 | 63 | // Futures endpoints 64 | futuresPing: () => Promise 65 | futuresTime: () => Promise<{ serverTime: number }> 66 | futuresExchangeInfo: () => Promise 67 | futuresBook: (payload: any) => Promise 68 | futuresAggTrades: (payload: any) => Promise 69 | futuresMarkPrice: (payload: any) => Promise 70 | futuresAllForceOrders: (payload: any) => Promise 71 | futuresLongShortRatio: (payload: any) => Promise 72 | futuresCandles: (payload: any) => Promise 73 | futuresMarkPriceCandles: (payload: any) => Promise 74 | futuresIndexPriceCandles: (payload: any) => Promise 75 | futuresTrades: (payload: any) => Promise 76 | futuresDailyStats: (payload: any) => Promise 77 | futuresPrices: (payload: any) => Promise 78 | futuresAllBookTickers: () => Promise 79 | futuresFundingRate: (payload: any) => Promise 80 | futuresOrder: (payload: any) => Promise 81 | futuresBatchOrders: (payload: any) => Promise 82 | futuresGetOrder: (payload: any) => Promise 83 | futuresCancelOrder: (payload: any) => Promise 84 | futuresCancelAllOpenOrders: (payload: any) => Promise 85 | futuresCancelBatchOrders: (payload: any) => Promise 86 | futuresOpenOrders: (payload: any) => Promise 87 | futuresAllOrders: (payload: any) => Promise 88 | futuresPositionRisk: (payload: any) => Promise 89 | futuresLeverageBracket: (payload: any) => Promise 90 | futuresAccountBalance: (payload?: any) => Promise 91 | futuresAccountInfo: (payload?: any) => Promise 92 | futuresUserTrades: (payload: any) => Promise 93 | futuresPositionMode: (payload: any) => Promise 94 | futuresPositionModeChange: (payload: any) => Promise 95 | futuresLeverage: (payload: any) => Promise 96 | futuresMarginType: (payload: any) => Promise 97 | futuresPositionMargin: (payload: any) => Promise 98 | futuresMarginHistory: (payload: any) => Promise 99 | futuresIncome: (payload: any) => Promise 100 | getMultiAssetsMargin: (payload: any) => Promise 101 | setMultiAssetsMargin: (payload: any) => Promise 102 | 103 | // Delivery endpoints 104 | deliveryPing: () => Promise 105 | deliveryTime: () => Promise<{ serverTime: number }> 106 | deliveryExchangeInfo: () => Promise 107 | deliveryBook: (payload: any) => Promise 108 | deliveryAggTrades: (payload: any) => Promise 109 | deliveryMarkPrice: (payload: any) => Promise 110 | deliveryAllForceOrders: (payload: any) => Promise 111 | deliveryLongShortRatio: (payload: any) => Promise 112 | deliveryCandles: (payload: any) => Promise 113 | deliveryMarkPriceCandles: (payload: any) => Promise 114 | deliveryIndexPriceCandles: (payload: any) => Promise 115 | deliveryTrades: (payload: any) => Promise 116 | deliveryDailyStats: (payload: any) => Promise 117 | deliveryPrices: () => Promise 118 | deliveryAllBookTickers: () => Promise 119 | deliveryFundingRate: (payload: any) => Promise 120 | deliveryOrder: (payload: any) => Promise 121 | deliveryBatchOrders: (payload: any) => Promise 122 | deliveryGetOrder: (payload: any) => Promise 123 | deliveryCancelOrder: (payload: any) => Promise 124 | deliveryCancelAllOpenOrders: (payload: any) => Promise 125 | deliveryCancelBatchOrders: (payload: any) => Promise 126 | deliveryOpenOrders: (payload: any) => Promise 127 | deliveryAllOrders: (payload: any) => Promise 128 | deliveryPositionRisk: (payload: any) => Promise 129 | deliveryLeverageBracket: (payload: any) => Promise 130 | deliveryAccountBalance: (payload?: any) => Promise 131 | deliveryAccountInfo: (payload?: any) => Promise 132 | deliveryUserTrades: (payload: any) => Promise 133 | deliveryPositionMode: (payload: any) => Promise 134 | deliveryPositionModeChange: (payload: any) => Promise 135 | deliveryLeverage: (payload: any) => Promise 136 | deliveryMarginType: (payload: any) => Promise 137 | deliveryPositionMargin: (payload: any) => Promise 138 | deliveryMarginHistory: (payload: any) => Promise 139 | deliveryIncome: (payload: any) => Promise 140 | 141 | // PAPI endpoints 142 | papiPing: () => Promise 143 | papiUmOrder: (payload: any) => Promise 144 | papiUmConditionalOrder: (payload: any) => Promise 145 | papiCmOrder: (payload: any) => Promise 146 | papiCmConditionalOrder: (payload: any) => Promise 147 | papiMarginOrder: (payload: any) => Promise 148 | papiMarginLoan: (payload: any) => Promise 149 | papiRepayLoan: (payload: any) => Promise 150 | papiMarginOrderOco: (payload: any) => Promise 151 | papiUmCancelOrder: (payload: any) => Promise 152 | papiUmCancelAllOpenOrders: (payload: any) => Promise 153 | papiUmCancelConditionalOrder: (payload: any) => Promise 154 | papiUmCancelConditionalAllOpenOrders: (payload: any) => Promise 155 | papiCmCancelOrder: (payload: any) => Promise 156 | papiCmCancelAllOpenOrders: (payload: any) => Promise 157 | papiCmCancelConditionalOrder: (payload: any) => Promise 158 | papiCmCancelConditionalAllOpenOrders: (payload: any) => Promise 159 | papiMarginCancelOrder: (payload: any) => Promise 160 | papiMarginCancelOrderList: (payload: any) => Promise 161 | papiMarginCancelAllOpenOrders: (payload: any) => Promise 162 | papiUmUpdateOrder: (payload: any) => Promise 163 | papiCmUpdateOrder: (payload: any) => Promise 164 | papiUmGetOrder: (payload: any) => Promise 165 | papiUmGetAllOrders: (payload: any) => Promise 166 | papiUmGetOpenOrder: (payload: any) => Promise 167 | papiUmGetOpenOrders: (payload: any) => Promise 168 | papiUmGetConditionalAllOrders: (payload: any) => Promise 169 | papiUmGetConditionalOpenOrders: (payload: any) => Promise 170 | papiUmGetConditionalOpenOrder: (payload: any) => Promise 171 | papiUmGetConditionalOrderHistory: (payload: any) => Promise 172 | papiCmGetOrder: (payload: any) => Promise 173 | papiCmGetAllOrders: (payload: any) => Promise 174 | papiCmGetOpenOrder: (payload: any) => Promise 175 | papiCmGetOpenOrders: (payload: any) => Promise 176 | papiCmGetConditionalOpenOrders: (payload: any) => Promise 177 | papiCmGetConditionalOpenOrder: (payload: any) => Promise 178 | papiCmGetConditionalAllOrders: (payload: any) => Promise 179 | papiCmGetConditionalOrderHistory: (payload: any) => Promise 180 | papiUmGetForceOrders: (payload: any) => Promise 181 | papiCmGetForceOrders: (payload: any) => Promise 182 | papiUmGetOrderAmendment: (payload: any) => Promise 183 | papiCmGetOrderAmendment: (payload: any) => Promise 184 | papiMarginGetForceOrders: (payload: any) => Promise 185 | papiUmGetUserTrades: (payload: any) => Promise 186 | papiCmGetUserTrades: (payload: any) => Promise 187 | papiUmGetAdlQuantile: (payload: any) => Promise 188 | papiCmGetAdlQuantile: (payload: any) => Promise 189 | papiUmFeeBurn: (payload: any) => Promise 190 | papiUmGetFeeBurn: (payload: any) => Promise 191 | papiMarginGetOrder: (payload: any) => Promise 192 | papiMarginGetOpenOrders: (payload: any) => Promise 193 | papiMarginGetAllOrders: (payload: any) => Promise 194 | papiMarginGetOrderList: (payload: any) => Promise 195 | papiMarginGetAllOrderList: (payload: any) => Promise 196 | papiMarginGetOpenOrderList: (payload: any) => Promise 197 | papiMarginGetMyTrades: (payload: any) => Promise 198 | papiMarginRepayDebt: (payload: any) => Promise 199 | 200 | // Margin endpoints 201 | marginOrder: (payload: any) => Promise 202 | marginOrderOco: (payload: any) => Promise 203 | marginGetOrder: (payload: any) => Promise 204 | marginGetOrderOco: (payload: any) => Promise 205 | marginCancelOrder: (payload: any) => Promise 206 | marginOpenOrders: (payload: any) => Promise 207 | marginCancelOpenOrders: (payload: any) => Promise 208 | marginAccountInfo: (payload: any) => Promise 209 | marginRepay: (payload: any) => Promise 210 | marginLoan: (payload: any) => Promise 211 | marginIsolatedAccount: (payload: any) => Promise 212 | marginMaxBorrow: (payload: any) => Promise 213 | marginCreateIsolated: (payload: any) => Promise 214 | marginIsolatedTransfer: (payload: any) => Promise 215 | marginIsolatedTransferHistory: (payload: any) => Promise 216 | disableMarginAccount: (payload: any) => Promise 217 | enableMarginAccount: (payload: any) => Promise 218 | marginAccount: () => Promise 219 | 220 | // Portfolio margin endpoints 221 | portfolioMarginAccountInfo: () => Promise 222 | portfolioMarginCollateralRate: () => Promise 223 | portfolioMarginLoan: (payload: any) => Promise 224 | portfolioMarginLoanRepay: (payload: any) => Promise 225 | portfolioMarginInterestHistory: (payload: any) => Promise 226 | 227 | // Savings endpoints 228 | savingsProducts: (payload: any) => Promise 229 | savingsPurchase: (payload: any) => Promise 230 | savingsRedeem: (payload: any) => Promise 231 | savingsRedemptionQuota: (payload: any) => Promise 232 | fundingWallet: (payload: any) => Promise 233 | convertTradeFlow: (payload: any) => Promise 234 | rebateTaxQuery: () => Promise 235 | payTradeHistory: (payload: any) => Promise 236 | apiRestrictions: (payload: any) => Promise 237 | savingsAccount: () => Promise 238 | 239 | // Mining endpoints 240 | miningHashrateResaleRequest: (payload: any) => Promise 241 | miningHashrateResaleCancel: (payload: any) => Promise 242 | miningStatistics: (payload: any) => Promise 243 | 244 | // Utility endpoints 245 | privateRequest: (method: string, url: string, payload: any) => Promise 246 | publicRequest: (method: string, url: string, payload: any) => Promise 247 | } 248 | 249 | // This test will fail at compile time if the types are incorrect 250 | test('types should compile correctly', async t => { 251 | // Create a typed instance 252 | const Binance = (await import('..')).default 253 | const client: BinanceRest = Binance({ 254 | apiKey: 'dummy', 255 | apiSecret: 'dummy', 256 | }) 257 | 258 | // Test base/generic endpoints 259 | const info = client.getInfo() 260 | const ping = client.ping() 261 | const time = client.time() 262 | const exchangeInfo = client.exchangeInfo() 263 | 264 | // Test market data endpoints 265 | const book = client.book({ symbol: 'BTCUSDT' }) 266 | const aggTrades = client.aggTrades({ symbol: 'BTCUSDT' }) 267 | const candles = client.candles({ symbol: 'BTCUSDT', interval: '1m' }) 268 | const trades = client.trades({ symbol: 'BTCUSDT' }) 269 | const tradesHistory = client.tradesHistory({ symbol: 'BTCUSDT' }) 270 | const dailyStats = client.dailyStats({ symbol: 'BTCUSDT' }) 271 | const prices = client.prices() 272 | const avgPrice = client.avgPrice({ symbol: 'BTCUSDT' }) 273 | const allBookTickers = client.allBookTickers() 274 | 275 | // Test order endpoints 276 | const order = client.order({ 277 | symbol: 'BTCUSDT', 278 | side: OrderSide.BUY, 279 | type: OrderType.LIMIT, 280 | quantity: '1', 281 | price: '50000', 282 | timeInForce: TimeInForce.GTC, 283 | }) 284 | const orderOco = client.orderOco({ 285 | symbol: 'BTCUSDT', 286 | side: OrderSide.BUY, 287 | quantity: '1', 288 | price: '50000', 289 | stopPrice: '51000', 290 | }) 291 | const orderTest = client.orderTest({ 292 | symbol: 'BTCUSDT', 293 | side: OrderSide.BUY, 294 | type: OrderType.LIMIT, 295 | quantity: '1', 296 | price: '50000', 297 | }) 298 | const getOrder = client.getOrder({ symbol: 'BTCUSDT', orderId: 12345 }) 299 | const getOrderOco = client.getOrderOco({ orderListId: 12345 }) 300 | const cancelOrder = client.cancelOrder({ symbol: 'BTCUSDT', orderId: 12345 }) 301 | const cancelOrderOco = client.cancelOrderOco({ symbol: 'BTCUSDT', orderListId: 12345 }) 302 | const cancelOpenOrders = client.cancelOpenOrders({ symbol: 'BTCUSDT' }) 303 | const openOrders = client.openOrders({ symbol: 'BTCUSDT' }) 304 | const allOrders = client.allOrders({ symbol: 'BTCUSDT' }) 305 | const allOrdersOCO = client.allOrdersOCO({ fromId: 12345 }) 306 | 307 | // Test account endpoints 308 | const accountInfo = client.accountInfo() 309 | const myTrades = client.myTrades({ symbol: 'BTCUSDT' }) 310 | const withdraw = client.withdraw({ coin: 'BTC', address: 'address', amount: '1' }) 311 | const withdrawHistory = client.withdrawHistory({ coin: 'BTC' }) 312 | const depositHistory = client.depositHistory({ coin: 'BTC' }) 313 | const depositAddress = client.depositAddress({ coin: 'BTC' }) 314 | const tradeFee = client.tradeFee({ symbol: 'BTCUSDT' }) 315 | const assetDetail = client.assetDetail({ asset: 'BTC' }) 316 | const accountSnapshot = client.accountSnapshot({ type: 'SPOT' }) 317 | const universalTransfer = client.universalTransfer({ 318 | type: 'MAIN_UMFUTURE', 319 | asset: 'BTC', 320 | amount: '1', 321 | }) 322 | const universalTransferHistory = client.universalTransferHistory({ type: 'MAIN_UMFUTURE' }) 323 | const dustLog = client.dustLog() 324 | const dustTransfer = client.dustTransfer({ asset: ['BTC', 'ETH'] }) 325 | const accountCoins = client.accountCoins() 326 | const getBnbBurn = client.getBnbBurn() 327 | const setBnbBurn = client.setBnbBurn({ spotBNBBurn: true }) 328 | 329 | // Test user data stream endpoints 330 | const getDataStream = client.getDataStream() 331 | const keepDataStream = client.keepDataStream({ listenKey: 'key' }) 332 | const closeDataStream = client.closeDataStream({ listenKey: 'key' }) 333 | const marginGetDataStream = client.marginGetDataStream() 334 | const marginKeepDataStream = client.marginKeepDataStream({ listenKey: 'key' }) 335 | const marginCloseDataStream = client.marginCloseDataStream({ listenKey: 'key' }) 336 | const futuresGetDataStream = client.futuresGetDataStream() 337 | const futuresKeepDataStream = client.futuresKeepDataStream({ listenKey: 'key' }) 338 | const futuresCloseDataStream = client.futuresCloseDataStream({ listenKey: 'key' }) 339 | const deliveryGetDataStream = client.deliveryGetDataStream() 340 | const deliveryKeepDataStream = client.deliveryKeepDataStream({ listenKey: 'key' }) 341 | const deliveryCloseDataStream = client.deliveryCloseDataStream({ listenKey: 'key' }) 342 | 343 | // Test futures endpoints 344 | const futuresPing = client.futuresPing() 345 | const futuresTime = client.futuresTime() 346 | const futuresExchangeInfo = client.futuresExchangeInfo() 347 | const futuresBook = client.futuresBook({ symbol: 'BTCUSDT' }) 348 | const futuresAggTrades = client.futuresAggTrades({ symbol: 'BTCUSDT' }) 349 | const futuresMarkPrice = client.futuresMarkPrice({ symbol: 'BTCUSDT' }) 350 | const futuresAllForceOrders = client.futuresAllForceOrders({ symbol: 'BTCUSDT' }) 351 | const futuresLongShortRatio = client.futuresLongShortRatio({ symbol: 'BTCUSDT' }) 352 | const futuresCandles = client.futuresCandles({ symbol: 'BTCUSDT', interval: '1m' }) 353 | const futuresMarkPriceCandles = client.futuresMarkPriceCandles({ 354 | symbol: 'BTCUSDT', 355 | interval: '1m', 356 | }) 357 | const futuresIndexPriceCandles = client.futuresIndexPriceCandles({ 358 | pair: 'BTCUSDT', 359 | interval: '1m', 360 | }) 361 | const futuresTrades = client.futuresTrades({ symbol: 'BTCUSDT' }) 362 | const futuresDailyStats = client.futuresDailyStats({ symbol: 'BTCUSDT' }) 363 | const futuresPrices = client.futuresPrices({ symbol: 'BTCUSDT' }) 364 | const futuresAllBookTickers = client.futuresAllBookTickers() 365 | const futuresFundingRate = client.futuresFundingRate({ symbol: 'BTCUSDT' }) 366 | const futuresOrder = client.futuresOrder({ 367 | symbol: 'BTCUSDT', 368 | side: OrderSide.BUY, 369 | type: OrderType.LIMIT, 370 | quantity: '1', 371 | price: '50000', 372 | }) 373 | const futuresBatchOrders = client.futuresBatchOrders({ 374 | batchOrders: [ 375 | { 376 | symbol: 'BTCUSDT', 377 | side: OrderSide.BUY, 378 | type: OrderType.LIMIT, 379 | quantity: '1', 380 | price: '50000', 381 | }, 382 | ], 383 | }) 384 | const futuresGetOrder = client.futuresGetOrder({ symbol: 'BTCUSDT', orderId: 12345 }) 385 | const futuresCancelOrder = client.futuresCancelOrder({ symbol: 'BTCUSDT', orderId: 12345 }) 386 | const futuresCancelAllOpenOrders = client.futuresCancelAllOpenOrders({ symbol: 'BTCUSDT' }) 387 | const futuresCancelBatchOrders = client.futuresCancelBatchOrders({ 388 | symbol: 'BTCUSDT', 389 | orderIdList: [12345], 390 | }) 391 | const futuresOpenOrders = client.futuresOpenOrders({ symbol: 'BTCUSDT' }) 392 | const futuresAllOrders = client.futuresAllOrders({ symbol: 'BTCUSDT' }) 393 | const futuresPositionRisk = client.futuresPositionRisk({ symbol: 'BTCUSDT' }) 394 | const futuresLeverageBracket = client.futuresLeverageBracket({ symbol: 'BTCUSDT' }) 395 | const futuresAccountBalance = client.futuresAccountBalance() 396 | const futuresAccountInfo = client.futuresAccountInfo() 397 | const futuresUserTrades = client.futuresUserTrades({ symbol: 'BTCUSDT' }) 398 | const futuresPositionMode = client.futuresPositionMode({ dualSidePosition: true }) 399 | const futuresPositionModeChange = client.futuresPositionModeChange({ dualSidePosition: true }) 400 | const futuresLeverage = client.futuresLeverage({ symbol: 'BTCUSDT', leverage: 10 }) 401 | const futuresMarginType = client.futuresMarginType({ symbol: 'BTCUSDT', marginType: 'ISOLATED' }) 402 | const futuresPositionMargin = client.futuresPositionMargin({ 403 | symbol: 'BTCUSDT', 404 | positionSide: 'BOTH', 405 | amount: '1', 406 | type: 1, 407 | }) 408 | const futuresMarginHistory = client.futuresMarginHistory({ symbol: 'BTCUSDT' }) 409 | const futuresIncome = client.futuresIncome({ symbol: 'BTCUSDT' }) 410 | const getMultiAssetsMargin = client.getMultiAssetsMargin({ multiAssetsMargin: true }) 411 | const setMultiAssetsMargin = client.setMultiAssetsMargin({ multiAssetsMargin: true }) 412 | 413 | // Test delivery endpoints 414 | const deliveryPing = client.deliveryPing() 415 | const deliveryTime = client.deliveryTime() 416 | const deliveryExchangeInfo = client.deliveryExchangeInfo() 417 | const deliveryBook = client.deliveryBook({ symbol: 'BTCUSD_PERP' }) 418 | const deliveryAggTrades = client.deliveryAggTrades({ symbol: 'BTCUSD_PERP' }) 419 | const deliveryMarkPrice = client.deliveryMarkPrice({ symbol: 'BTCUSD_PERP' }) 420 | const deliveryAllForceOrders = client.deliveryAllForceOrders({ symbol: 'BTCUSD_PERP' }) 421 | const deliveryLongShortRatio = client.deliveryLongShortRatio({ symbol: 'BTCUSD_PERP' }) 422 | const deliveryCandles = client.deliveryCandles({ symbol: 'BTCUSD_PERP', interval: '1m' }) 423 | const deliveryMarkPriceCandles = client.deliveryMarkPriceCandles({ 424 | symbol: 'BTCUSD_PERP', 425 | interval: '1m', 426 | }) 427 | const deliveryIndexPriceCandles = client.deliveryIndexPriceCandles({ 428 | pair: 'BTCUSD', 429 | interval: '1m', 430 | }) 431 | const deliveryTrades = client.deliveryTrades({ symbol: 'BTCUSD_PERP' }) 432 | const deliveryDailyStats = client.deliveryDailyStats({ symbol: 'BTCUSD_PERP' }) 433 | const deliveryPrices = client.deliveryPrices() 434 | const deliveryAllBookTickers = client.deliveryAllBookTickers() 435 | const deliveryFundingRate = client.deliveryFundingRate({ symbol: 'BTCUSD_PERP' }) 436 | const deliveryOrder = client.deliveryOrder({ 437 | symbol: 'BTCUSD_PERP', 438 | side: OrderSide.BUY, 439 | type: OrderType.LIMIT, 440 | quantity: '1', 441 | price: '50000', 442 | }) 443 | const deliveryBatchOrders = client.deliveryBatchOrders({ 444 | batchOrders: [ 445 | { 446 | symbol: 'BTCUSD_PERP', 447 | side: OrderSide.BUY, 448 | type: OrderType.LIMIT, 449 | quantity: '1', 450 | price: '50000', 451 | }, 452 | ], 453 | }) 454 | const deliveryGetOrder = client.deliveryGetOrder({ symbol: 'BTCUSD_PERP', orderId: 12345 }) 455 | const deliveryCancelOrder = client.deliveryCancelOrder({ symbol: 'BTCUSD_PERP', orderId: 12345 }) 456 | const deliveryCancelAllOpenOrders = client.deliveryCancelAllOpenOrders({ symbol: 'BTCUSD_PERP' }) 457 | const deliveryCancelBatchOrders = client.deliveryCancelBatchOrders({ 458 | symbol: 'BTCUSD_PERP', 459 | orderIdList: [12345], 460 | }) 461 | const deliveryOpenOrders = client.deliveryOpenOrders({ symbol: 'BTCUSD_PERP' }) 462 | const deliveryAllOrders = client.deliveryAllOrders({ symbol: 'BTCUSD_PERP' }) 463 | const deliveryPositionRisk = client.deliveryPositionRisk({ symbol: 'BTCUSD_PERP' }) 464 | const deliveryLeverageBracket = client.deliveryLeverageBracket({ symbol: 'BTCUSD_PERP' }) 465 | const deliveryAccountBalance = client.deliveryAccountBalance() 466 | const deliveryAccountInfo = client.deliveryAccountInfo() 467 | const deliveryUserTrades = client.deliveryUserTrades({ symbol: 'BTCUSD_PERP' }) 468 | const deliveryPositionMode = client.deliveryPositionMode({ dualSidePosition: true }) 469 | const deliveryPositionModeChange = client.deliveryPositionModeChange({ dualSidePosition: true }) 470 | const deliveryLeverage = client.deliveryLeverage({ symbol: 'BTCUSD_PERP', leverage: 10 }) 471 | const deliveryMarginType = client.deliveryMarginType({ 472 | symbol: 'BTCUSD_PERP', 473 | marginType: 'ISOLATED', 474 | }) 475 | const deliveryPositionMargin = client.deliveryPositionMargin({ 476 | symbol: 'BTCUSD_PERP', 477 | positionSide: 'BOTH', 478 | amount: '1', 479 | type: 1, 480 | }) 481 | const deliveryMarginHistory = client.deliveryMarginHistory({ symbol: 'BTCUSD_PERP' }) 482 | const deliveryIncome = client.deliveryIncome({ symbol: 'BTCUSD_PERP' }) 483 | 484 | // Test PAPI endpoints 485 | const papiPing = client.papiPing() 486 | const papiUmOrder = client.papiUmOrder({ 487 | symbol: 'BTCUSDT', 488 | side: OrderSide.BUY, 489 | type: OrderType.LIMIT, 490 | quantity: '1', 491 | price: '50000', 492 | }) 493 | const papiUmConditionalOrder = client.papiUmConditionalOrder({ 494 | symbol: 'BTCUSDT', 495 | side: OrderSide.BUY, 496 | type: OrderType.LIMIT, 497 | quantity: '1', 498 | price: '50000', 499 | stopPrice: '51000', 500 | }) 501 | const papiCmOrder = client.papiCmOrder({ 502 | symbol: 'BTCUSD_PERP', 503 | side: OrderSide.BUY, 504 | type: OrderType.LIMIT, 505 | quantity: '1', 506 | price: '50000', 507 | }) 508 | const papiCmConditionalOrder = client.papiCmConditionalOrder({ 509 | symbol: 'BTCUSD_PERP', 510 | side: OrderSide.BUY, 511 | type: OrderType.LIMIT, 512 | quantity: '1', 513 | price: '50000', 514 | stopPrice: '51000', 515 | }) 516 | const papiMarginOrder = client.papiMarginOrder({ 517 | symbol: 'BTCUSDT', 518 | side: OrderSide.BUY, 519 | type: OrderType.LIMIT, 520 | quantity: '1', 521 | price: '50000', 522 | }) 523 | const papiMarginLoan = client.papiMarginLoan({ asset: 'BTC', amount: '1' }) 524 | const papiRepayLoan = client.papiRepayLoan({ asset: 'BTC', amount: '1' }) 525 | const papiMarginOrderOco = client.papiMarginOrderOco({ 526 | symbol: 'BTCUSDT', 527 | side: OrderSide.BUY, 528 | quantity: '1', 529 | price: '50000', 530 | stopPrice: '51000', 531 | }) 532 | const papiUmCancelOrder = client.papiUmCancelOrder({ symbol: 'BTCUSDT', orderId: 12345 }) 533 | const papiUmCancelAllOpenOrders = client.papiUmCancelAllOpenOrders({ symbol: 'BTCUSDT' }) 534 | const papiUmCancelConditionalOrder = client.papiUmCancelConditionalOrder({ 535 | symbol: 'BTCUSDT', 536 | orderId: 12345, 537 | }) 538 | const papiUmCancelConditionalAllOpenOrders = client.papiUmCancelConditionalAllOpenOrders({ 539 | symbol: 'BTCUSDT', 540 | }) 541 | const papiCmCancelOrder = client.papiCmCancelOrder({ symbol: 'BTCUSD_PERP', orderId: 12345 }) 542 | const papiCmCancelAllOpenOrders = client.papiCmCancelAllOpenOrders({ symbol: 'BTCUSD_PERP' }) 543 | const papiCmCancelConditionalOrder = client.papiCmCancelConditionalOrder({ 544 | symbol: 'BTCUSD_PERP', 545 | orderId: 12345, 546 | }) 547 | const papiCmCancelConditionalAllOpenOrders = client.papiCmCancelConditionalAllOpenOrders({ 548 | symbol: 'BTCUSD_PERP', 549 | }) 550 | 551 | // Test margin endpoints 552 | const marginOrder = client.marginOrder({ 553 | symbol: 'BTCUSDT', 554 | side: OrderSide.BUY, 555 | type: OrderType.LIMIT, 556 | quantity: '1', 557 | price: '50000', 558 | }) 559 | const marginOrderOco = client.marginOrderOco({ 560 | symbol: 'BTCUSDT', 561 | side: OrderSide.BUY, 562 | quantity: '1', 563 | price: '50000', 564 | stopPrice: '51000', 565 | }) 566 | const marginGetOrder = client.marginGetOrder({ symbol: 'BTCUSDT', orderId: '12345' }) 567 | const marginGetOrderOco = client.marginGetOrderOco({ symbol: 'BTCUSDT', orderListId: 12345 }) 568 | const marginCancelOrder = client.marginCancelOrder({ symbol: 'BTCUSDT', orderId: 12345 }) 569 | const marginOpenOrders = client.marginOpenOrders({ symbol: 'BTCUSDT' }) 570 | const marginCancelOpenOrders = client.marginCancelOpenOrders({ symbol: 'BTCUSDT' }) 571 | const marginAccountInfo = client.marginAccountInfo() 572 | const marginRepay = client.marginRepay({ asset: 'BTC', amount: '1' }) 573 | const marginLoan = client.marginLoan({ asset: 'BTC', amount: '1' }) 574 | const marginIsolatedAccount = client.marginIsolatedAccount({ symbols: 'BTCUSDT' }) 575 | const marginMaxBorrow = client.marginMaxBorrow({ asset: 'BTC' }) 576 | const marginCreateIsolated = client.marginCreateIsolated({ base: 'BTC', quote: 'USDT' }) 577 | const marginIsolatedTransfer = client.marginIsolatedTransfer({ 578 | asset: 'BTC', 579 | symbol: 'BTCUSDT', 580 | transFrom: 'SPOT', 581 | transTo: 'ISOLATED_MARGIN', 582 | amount: '1', 583 | }) 584 | const marginIsolatedTransferHistory = client.marginIsolatedTransferHistory({ symbol: 'BTCUSDT' }) 585 | const disableMarginAccount = client.disableMarginAccount({ symbol: 'BTCUSDT' }) 586 | const enableMarginAccount = client.enableMarginAccount({ symbol: 'BTCUSDT' }) 587 | const marginAccount = client.marginAccount() 588 | 589 | // Test portfolio margin endpoints 590 | const portfolioMarginAccountInfo = client.portfolioMarginAccountInfo() 591 | const portfolioMarginCollateralRate = client.portfolioMarginCollateralRate() 592 | const portfolioMarginLoan = client.portfolioMarginLoan({ asset: 'BTC', amount: '1' }) 593 | const portfolioMarginLoanRepay = client.portfolioMarginLoanRepay({ asset: 'BTC', amount: '1' }) 594 | const portfolioMarginInterestHistory = client.portfolioMarginInterestHistory({ asset: 'BTC' }) 595 | 596 | // Test savings endpoints 597 | const savingsProducts = client.savingsProducts({ type: 'ACTIVITY' }) 598 | const savingsPurchase = client.savingsPurchase({ productId: '123', amount: '1' }) 599 | const savingsRedeem = client.savingsRedeem({ productId: '123', amount: '1', type: 'FAST' }) 600 | const savingsRedemptionQuota = client.savingsRedemptionQuota({ productId: '123', type: 'FAST' }) 601 | const savingsAccount = client.savingsAccount() 602 | 603 | // Test mining endpoints 604 | const miningHashrateResaleRequest = client.miningHashrateResaleRequest({ 605 | userName: 'user', 606 | coinName: 'BTC', 607 | algo: 'sha256', 608 | startDate: 1234567890, 609 | endDate: 1234567890, 610 | pageIndex: 1, 611 | pageSize: 10, 612 | }) 613 | const miningHashrateResaleCancel = client.miningHashrateResaleCancel({ 614 | configId: 123, 615 | userName: 'user', 616 | }) 617 | const miningStatistics = client.miningStatistics({ userName: 'user', algo: 'sha256' }) 618 | 619 | // Test utility endpoints 620 | const privateRequest = client.privateRequest('GET', '/api/v3/account', {}) 621 | const publicRequest = client.publicRequest('GET', '/api/v3/ticker/price', {}) 622 | }) 623 | -------------------------------------------------------------------------------- /test/utils.js: -------------------------------------------------------------------------------- 1 | import http from 'http' 2 | 3 | export const checkFields = (t, object, fields) => { 4 | fields.forEach(field => { 5 | t.truthy(object[field]) 6 | }) 7 | } 8 | 9 | const generatePort = (() => { 10 | let portNum = 9000 11 | return () => portNum++ 12 | })() 13 | 14 | export const createHttpServer = requestHandler => { 15 | const server = http.createServer(requestHandler) 16 | const port = generatePort() 17 | return { 18 | url: `http://127.0.0.1:${port}`, 19 | start: () => 20 | new Promise((resolve, reject) => server.listen(port, err => (err ? reject(err) : resolve()))), 21 | stop: () => 22 | new Promise((resolve, reject) => server.close(err => (err ? reject(err) : resolve()))), 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2018", 4 | "module": "commonjs", 5 | "lib": ["es2018", "dom"], 6 | "declaration": true, 7 | "strict": true, 8 | "noImplicitAny": true, 9 | "strictNullChecks": true, 10 | "noImplicitThis": true, 11 | "alwaysStrict": true, 12 | "noUnusedLocals": false, 13 | "noUnusedParameters": false, 14 | "noImplicitReturns": true, 15 | "noFallthroughCasesInSwitch": false, 16 | "inlineSourceMap": true, 17 | "inlineSources": true, 18 | "experimentalDecorators": true, 19 | "strictPropertyInitialization": false, 20 | "esModuleInterop": true, 21 | "skipLibCheck": true, 22 | "forceConsistentCasingInFileNames": true, 23 | "moduleResolution": "node", 24 | "resolveJsonModule": true, 25 | "isolatedModules": true, 26 | "jsx": "preserve", 27 | "baseUrl": ".", 28 | "paths": { 29 | "*": ["node_modules/*"] 30 | } 31 | }, 32 | "include": ["src/**/*", "test/**/*", "index.d.ts"], 33 | "exclude": ["node_modules", "dist"] 34 | } -------------------------------------------------------------------------------- /types/account.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | 3 | export interface Account { 4 | accountType: TradingType.MARGIN | TradingType.SPOT; 5 | balances: AssetBalance[]; 6 | buyerCommission: number; 7 | canDeposit: boolean; 8 | canTrade: boolean; 9 | canWithdraw: boolean; 10 | makerCommission: number; 11 | permissions: TradingType_LT[]; 12 | sellerCommission: number; 13 | takerCommission: number; 14 | updateTime: number; 15 | } 16 | 17 | export interface AssetBalance { 18 | asset: string; 19 | free: string; 20 | locked: string; 21 | } 22 | 23 | export interface TradeFee { 24 | symbol: string; 25 | makerCommission: number; 26 | takerCommission: number; 27 | } 28 | 29 | export interface DepositAddress { 30 | address: string; 31 | tag: string; 32 | coin: string; 33 | url: string; 34 | } 35 | 36 | export interface WithdrawResponse { 37 | id: string; 38 | } 39 | 40 | export type DepositStatus_LT = 0 | 1; 41 | 42 | export const enum DepositStatus { 43 | PENDING = 0, 44 | SUCCESS = 1, 45 | } 46 | 47 | export interface UserAssetDribbletDetails { 48 | transId: number; 49 | serviceChargeAmount: string; 50 | amount: string; 51 | operateTime: number; 52 | transferedAmount: string; 53 | fromAsset: string; 54 | } 55 | 56 | export interface UserAssetDribblets { 57 | operateTime: number; 58 | totalTransferedAmount: string; 59 | totalServiceChargeAmount: string; 60 | transId: number; 61 | userAssetDribbletDetails: UserAssetDribbletDetails[]; 62 | } 63 | 64 | export interface DustLog { 65 | total: number; 66 | userAssetDribblets: UserAssetDribblets[]; 67 | } 68 | 69 | export interface DustTransferResult { 70 | amount: string; 71 | fromAsset: string; 72 | operateTime: number; 73 | serviceChargeAmount: string; 74 | tranId: number; 75 | transferedAmount: string; 76 | } 77 | 78 | export interface DustTransfer { 79 | totalServiceCharge: string; 80 | totalTransfered: string; 81 | transferResult: DustTransferResult[]; 82 | } 83 | 84 | export interface DepositHistoryResponse { 85 | [index: number]: { 86 | insertTime: number; 87 | amount: string; 88 | coin: string; 89 | network: string; 90 | address: string; 91 | txId: string; 92 | status: DepositStatus_LT; 93 | addressTag?: string; 94 | transferType?: number; 95 | confirmTimes?: string; 96 | }; 97 | } 98 | 99 | export type WithdrawStatus_LT = 0 | 1 | 2 | 3 | 4 | 5 | 6; 100 | 101 | export const enum WithdrawStatus { 102 | EMAIL_SENT = 0, 103 | CANCELLED = 1, 104 | AWAITING_APPROVAL = 2, 105 | REJECTED = 3, 106 | PROCESSING = 4, 107 | FAILURE = 5, 108 | COMPLETED = 6, 109 | } 110 | 111 | export interface WithdrawHistoryResponse { 112 | [index: number]: { 113 | id: string; 114 | amount: string; 115 | transactionFee: string; 116 | address: string; 117 | coin: string; 118 | txId: string; 119 | applyTime: number; 120 | status: WithdrawStatus_LT; 121 | network: string; 122 | transferType?: number; 123 | withdrawOrderId?: string; 124 | }; 125 | } 126 | 127 | export interface AccountEndpoints extends BinanceRestClient { 128 | accountInfo(): Promise; 129 | myTrades(payload: { symbol: string; startTime?: number; endTime?: number; fromId?: number; limit?: number }): Promise; 130 | withdraw(payload: { coin: string; address: string; amount: string; network?: string; addressTag?: string; name?: string }): Promise<{ 131 | id: string; 132 | msg: string; 133 | amount: string; 134 | address: string; 135 | network: string; 136 | addressTag: string; 137 | transactionFee: string; 138 | transactionId: string; 139 | applyTime: string; 140 | status: number; 141 | }>; 142 | withdrawHistory(payload?: { coin?: string; status?: number; startTime?: number; endTime?: number; offset?: number; limit?: number }): Promise; 143 | depositHistory(payload?: { coin?: string; status?: number; startTime?: number; endTime?: number; offset?: number; limit?: number }): Promise; 144 | depositAddress(payload: { coin: string; network?: string }): Promise; 145 | tradeFee(payload?: { symbol?: string }): Promise; 146 | assetDetail(payload?: { asset?: string }): Promise<{ 147 | [key: string]: { 148 | minWithdrawAmount: string; 149 | depositStatus: boolean; 150 | withdrawFee: number; 151 | withdrawStatus: boolean; 152 | depositTip?: string; 153 | }; 154 | }>; 155 | accountSnapshot(payload: { type: string; startTime?: number; endTime?: number; limit?: number }): Promise<{ 156 | code: number; 157 | msg: string; 158 | snapshotVos: Array<{ 159 | data: { 160 | totalAssetOfBtc: string; 161 | balances: Array<{ 162 | asset: string; 163 | free: string; 164 | locked: string; 165 | }>; 166 | }; 167 | type: string; 168 | updateTime: number; 169 | }>; 170 | }>; 171 | universalTransfer(payload: { type: string; asset: string; amount: string; fromSymbol?: string; toSymbol?: string }): Promise<{ 172 | tranId: number; 173 | status: string; 174 | type: string; 175 | asset: string; 176 | amount: string; 177 | timestamp: number; 178 | }>; 179 | universalTransferHistory(payload: { type: string; startTime?: number; endTime?: number; current?: number; size?: number; fromSymbol?: string; toSymbol?: string }): Promise<{ 180 | total: number; 181 | rows: Array<{ 182 | asset: string; 183 | amount: string; 184 | type: string; 185 | status: string; 186 | timestamp: number; 187 | tranId: number; 188 | fromSymbol: string; 189 | toSymbol: string; 190 | }>; 191 | }>; 192 | dustLog(payload?: { startTime?: number; endTime?: number }): Promise; 193 | dustTransfer(payload: { asset: string[] }): Promise; 194 | accountCoins(): Promise; 222 | storage: string; 223 | trading: boolean; 224 | withdrawAllEnable: boolean; 225 | withdrawing: string; 226 | }>>; 227 | getBnbBurn(): Promise<{ 228 | msg: string; 229 | code: number; 230 | data: { 231 | spotBNBBurn: boolean; 232 | interestBNBBurn: boolean; 233 | }; 234 | }>; 235 | setBnbBurn(payload: { spotBNBBurn?: boolean; interestBNBBurn?: boolean }): Promise<{ 236 | msg: string; 237 | code: number; 238 | data: { 239 | spotBNBBurn: boolean; 240 | interestBNBBurn: boolean; 241 | }; 242 | }>; 243 | } -------------------------------------------------------------------------------- /types/base.d.ts: -------------------------------------------------------------------------------- 1 | export interface BinanceRestOptions { 2 | apiKey?: string; 3 | apiSecret?: string; 4 | 5 | httpBase?: string; 6 | httpFutures?: string; 7 | httpDelivery?: string; 8 | httpPortfolioMargin?: string; 9 | 10 | wsBase?: string; 11 | wsFutures?: string; 12 | wsDelivery?: string; 13 | 14 | timeout?: number; 15 | testnet?: boolean; 16 | proxy?: string; 17 | getTime?: () => number; 18 | } 19 | 20 | export enum RateLimitType { 21 | REQUEST_WEIGHT = 'REQUEST_WEIGHT', 22 | ORDERS = 'ORDERS', 23 | RAW_REQUESTS = 'RAW_REQUESTS' 24 | } 25 | 26 | export enum RateLimitInterval { 27 | SECOND = 'SECOND', 28 | MINUTE = 'MINUTE', 29 | HOUR = 'HOUR', 30 | DAY = 'DAY' 31 | } 32 | 33 | export enum OrderType { 34 | LIMIT = 'LIMIT', 35 | MARKET = 'MARKET', 36 | STOP_LOSS = 'STOP_LOSS', 37 | STOP_LOSS_LIMIT = 'STOP_LOSS_LIMIT', 38 | TAKE_PROFIT = 'TAKE_PROFIT', 39 | TAKE_PROFIT_LIMIT = 'TAKE_PROFIT_LIMIT', 40 | LIMIT_MAKER = 'LIMIT_MAKER', 41 | STOP_MARKET = 'STOP_MARKET', 42 | TAKE_PROFIT_MARKET = 'TAKE_PROFIT_MARKET', 43 | TRAILING_STOP_MARKET = 'TRAILING_STOP_MARKET' 44 | } 45 | 46 | export enum OrderSide { 47 | BUY = 'BUY', 48 | SELL = 'SELL' 49 | } 50 | 51 | export enum TimeInForce { 52 | GTC = 'GTC', // Good Till Cancel 53 | IOC = 'IOC', // Immediate or Cancel 54 | FOK = 'FOK' // Fill or Kill 55 | } 56 | 57 | export enum TradingType { 58 | SPOT = 'SPOT', 59 | MARGIN = 'MARGIN' 60 | } 61 | 62 | export type TradingType_LT = 'SPOT' | 'MARGIN'; 63 | 64 | // Base interface that all endpoint interfaces will extend 65 | export interface BinanceRestClient { 66 | // This interface is now empty as all methods are defined in their respective endpoint interfaces 67 | } -------------------------------------------------------------------------------- /types/delivery.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient, OrderSide, OrderStatus, OrderType, TimeInForce } from './base'; 2 | 3 | export interface DeliveryEndpoints extends BinanceRestClient { 4 | deliveryPing(): Promise; 5 | deliveryTime(): Promise<{ serverTime: number }>; 6 | deliveryExchangeInfo(): Promise; 7 | deliveryBook(payload: { symbol: string; limit?: number }): Promise<{ 8 | lastUpdateId: number; 9 | asks: Array<[string, string]>; 10 | bids: Array<[string, string]>; 11 | }>; 12 | deliveryAggTrades(payload: { symbol: string; fromId?: number; startTime?: number; endTime?: number; limit?: number }): Promise>; 22 | deliveryMarkPrice(payload: { symbol: string }): Promise<{ 23 | symbol: string; 24 | markPrice: string; 25 | lastFundingRate: string; 26 | nextFundingTime: number; 27 | time: number; 28 | }>; 29 | deliveryAllForceOrders(payload?: { symbol?: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 41 | deliveryLongShortRatio(payload: { symbol: string; period?: string; limit?: number; startTime?: number; endTime?: number }): Promise>; 48 | deliveryCandles(payload: { symbol: string; interval: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 61 | deliveryMarkPriceCandles(payload: { symbol: string; interval: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 74 | deliveryIndexPriceCandles(payload: { pair: string; interval: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 87 | deliveryTrades(payload: { symbol: string; limit?: number }): Promise>; 95 | deliveryDailyStats(payload?: { symbol?: string }): Promise>; 114 | deliveryPrices(): Promise<{ 115 | [key: string]: string; 116 | }>; 117 | deliveryAllBookTickers(): Promise<{ 118 | [key: string]: { 119 | symbol: string; 120 | pair: string; 121 | bidPrice: string; 122 | bidQty: string; 123 | askPrice: string; 124 | askQty: string; 125 | time: number; 126 | }; 127 | }>; 128 | deliveryFundingRate(payload: { symbol: string }): Promise<{ 129 | symbol: string; 130 | fundingRate: string; 131 | fundingTime: number; 132 | }>; 133 | deliveryOrder(payload: { 134 | symbol: string; 135 | side: OrderSide; 136 | type: OrderType; 137 | quantity?: string; 138 | quoteOrderQty?: string; 139 | price?: string; 140 | newClientOrderId?: string; 141 | stopPrice?: string; 142 | trailingDelta?: number; 143 | trailingTime?: number; 144 | icebergQty?: string; 145 | newOrderRespType?: string; 146 | timeInForce?: TimeInForce; 147 | }): Promise<{ 148 | symbol: string; 149 | orderId: number; 150 | orderListId: number; 151 | clientOrderId: string; 152 | transactTime: number; 153 | price: string; 154 | origQty: string; 155 | executedQty: string; 156 | cumQuote: string; 157 | status: OrderStatus; 158 | timeInForce: TimeInForce; 159 | type: OrderType; 160 | side: OrderSide; 161 | marginBuyBorrowAmount: string; 162 | marginBuyBorrowAsset: string; 163 | fills: Array<{ 164 | price: string; 165 | qty: string; 166 | commission: string; 167 | commissionAsset: string; 168 | }>; 169 | }>; 170 | deliveryBatchOrders(payload: { batchOrders: Array<{ 171 | symbol: string; 172 | side: OrderSide; 173 | type: OrderType; 174 | quantity?: string; 175 | quoteOrderQty?: string; 176 | price?: string; 177 | newClientOrderId?: string; 178 | stopPrice?: string; 179 | trailingDelta?: number; 180 | trailingTime?: number; 181 | icebergQty?: string; 182 | newOrderRespType?: string; 183 | timeInForce?: TimeInForce; 184 | }> }): Promise; 208 | }>>; 209 | deliveryGetOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 210 | symbol: string; 211 | orderId: number; 212 | clientOrderId: string; 213 | transactTime: number; 214 | price: string; 215 | origQty: string; 216 | executedQty: string; 217 | cumQuote: string; 218 | status: OrderStatus; 219 | timeInForce: TimeInForce; 220 | type: OrderType; 221 | side: OrderSide; 222 | marginBuyBorrowAmount: string; 223 | marginBuyBorrowAsset: string; 224 | fills: Array<{ 225 | price: string; 226 | qty: string; 227 | commission: string; 228 | commissionAsset: string; 229 | }>; 230 | }>; 231 | deliveryCancelOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 232 | symbol: string; 233 | origClientOrderId: string; 234 | orderId: number; 235 | orderListId: number; 236 | clientOrderId: string; 237 | transactTime: number; 238 | price: string; 239 | origQty: string; 240 | executedQty: string; 241 | cumQuote: string; 242 | status: OrderStatus; 243 | timeInForce: TimeInForce; 244 | type: OrderType; 245 | side: OrderSide; 246 | }>; 247 | deliveryCancelAllOpenOrders(payload: { symbol: string }): Promise>; 263 | deliveryCancelBatchOrders(payload: { symbol: string; orderIdList: number[] }): Promise>; 280 | deliveryOpenOrders(payload?: { symbol?: string }): Promise; 302 | }>>; 303 | deliveryAllOrders(payload: { symbol: string; orderId?: number; startTime?: number; endTime?: number; limit?: number }): Promise; 325 | }>>; 326 | deliveryPositionRisk(payload?: { symbol?: string }): Promise>; 345 | deliveryLeverageBracket(payload: { symbol: string }): Promise; 355 | }>>; 356 | deliveryAccountBalance(): Promise>; 366 | deliveryAccountInfo(): Promise<{ 367 | assets: Array<{ 368 | asset: string; 369 | walletBalance: string; 370 | unrealizedProfit: string; 371 | marginBalance: string; 372 | initialMargin: string; 373 | positionInitialMargin: string; 374 | openOrderInitialMargin: string; 375 | maxWithdrawAmount: string; 376 | crossUnPnl: string; 377 | crossWalletBalance: string; 378 | crossMarginBalance: string; 379 | availableBalance: string; 380 | marginAvailable: boolean; 381 | updateTime: number; 382 | }>; 383 | positions: Array<{ 384 | symbol: string; 385 | positionAmt: string; 386 | entryPrice: string; 387 | markPrice: string; 388 | unRealizedProfit: string; 389 | liquidationPrice: string; 390 | leverage: string; 391 | maxNotionalValue: string; 392 | marginType: string; 393 | isolatedMargin: string; 394 | isolatedWallet: string; 395 | isolatedUnrealizedProfit: string; 396 | isolatedMarginLevel: string; 397 | isolatedMaintMargin: string; 398 | isolatedMaxNotionalValue: string; 399 | notional: string; 400 | unrealizedPnl: string; 401 | marginLevel: string; 402 | }>; 403 | canDeposit: boolean; 404 | canTrade: boolean; 405 | canWithdraw: boolean; 406 | feeTier: number; 407 | updateTime: number; 408 | totalInitialMargin: string; 409 | totalMaintMargin: string; 410 | totalWalletBalance: string; 411 | totalUnrealizedProfit: string; 412 | totalMarginBalance: string; 413 | totalPositionInitialMargin: string; 414 | totalOpenOrderInitialMargin: string; 415 | totalCrossWalletBalance: string; 416 | totalCrossUnPnl: string; 417 | availableBalance: string; 418 | maxWithdrawAmount: string; 419 | }>; 420 | deliveryUserTrades(payload: { symbol: string; startTime?: number; endTime?: number; fromId?: number; limit?: number }): Promise>; 437 | deliveryPositionMode(payload: { dualSidePosition: boolean }): Promise<{ 438 | code: number; 439 | msg: string; 440 | }>; 441 | deliveryPositionModeChange(payload: { dualSidePosition: boolean }): Promise<{ 442 | code: number; 443 | msg: string; 444 | }>; 445 | deliveryLeverage(payload: { symbol: string; leverage: number }): Promise<{ 446 | leverage: number; 447 | maxNotionalValue: string; 448 | symbol: string; 449 | }>; 450 | deliveryMarginType(payload: { symbol: string; marginType: string }): Promise<{ 451 | code: number; 452 | msg: string; 453 | }>; 454 | deliveryPositionMargin(payload: { symbol: string; positionSide: string; amount: string; type: number }): Promise<{ 455 | code: number; 456 | msg: string; 457 | }>; 458 | deliveryMarginHistory(payload: { symbol: string }): Promise>; 466 | deliveryIncome(payload?: { symbol?: string; incomeType?: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 476 | } -------------------------------------------------------------------------------- /types/futures.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient, OrderSide, OrderStatus, OrderType, TimeInForce } from './base'; 2 | 3 | export interface FuturesEndpoints extends BinanceRestClient { 4 | futuresPing(): Promise; 5 | futuresTime(): Promise<{ 6 | serverTime: number; 7 | }>; 8 | futuresExchangeInfo(): Promise; 9 | futuresBook(payload: { symbol: string; limit?: number }): Promise<{ 10 | lastUpdateId: number; 11 | asks: Array<[string, string]>; 12 | bids: Array<[string, string]>; 13 | }>; 14 | futuresAggTrades(payload: { symbol: string; fromId?: number; startTime?: number; endTime?: number; limit?: number }): Promise>; 25 | futuresMarkPrice(payload: { symbol: string }): Promise<{ 26 | symbol: string; 27 | markPrice: string; 28 | lastFundingRate: string; 29 | nextFundingTime: number; 30 | time: number; 31 | }>; 32 | futuresAllForceOrders(payload?: { symbol?: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 55 | futuresLongShortRatio(payload: { symbol: string; period?: string; limit?: number; startTime?: number; endTime?: number }): Promise>; 62 | futuresCandles(payload: { symbol: string; interval: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 75 | futuresMarkPriceCandles(payload: { symbol: string; interval: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 88 | futuresIndexPriceCandles(payload: { pair: string; interval: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 101 | futuresTrades(payload: { symbol: string; limit?: number }): Promise>; 110 | futuresDailyStats(payload?: { symbol?: string }): Promise>; 132 | futuresPrices(payload?: { symbol?: string }): Promise<{ 133 | [key: string]: string; 134 | }>; 135 | futuresAllBookTickers(): Promise<{ 136 | [key: string]: { 137 | symbol: string; 138 | bidPrice: string; 139 | bidQty: string; 140 | askPrice: string; 141 | askQty: string; 142 | }; 143 | }>; 144 | futuresFundingRate(payload: { symbol: string }): Promise<{ 145 | symbol: string; 146 | fundingRate: string; 147 | fundingTime: number; 148 | }>; 149 | futuresOrder(payload: { 150 | symbol: string; 151 | side: OrderSide; 152 | type: OrderType; 153 | quantity?: string; 154 | quoteOrderQty?: string; 155 | price?: string; 156 | newClientOrderId?: string; 157 | stopPrice?: string; 158 | trailingDelta?: number; 159 | trailingTime?: number; 160 | icebergQty?: string; 161 | newOrderRespType?: string; 162 | timeInForce?: TimeInForce; 163 | }): Promise<{ 164 | symbol: string; 165 | orderId: number; 166 | orderListId: number; 167 | clientOrderId: string; 168 | transactTime: number; 169 | price: string; 170 | origQty: string; 171 | executedQty: string; 172 | cumQuote: string; 173 | status: OrderStatus; 174 | timeInForce: TimeInForce; 175 | type: OrderType; 176 | side: OrderSide; 177 | marginBuyBorrowAmount: string; 178 | marginBuyBorrowAsset: string; 179 | fills: Array<{ 180 | price: string; 181 | qty: string; 182 | commission: string; 183 | commissionAsset: string; 184 | }>; 185 | }>; 186 | futuresBatchOrders(payload: { batchOrders: Array<{ 187 | symbol: string; 188 | side: OrderSide; 189 | type: OrderType; 190 | quantity?: string; 191 | quoteOrderQty?: string; 192 | price?: string; 193 | newClientOrderId?: string; 194 | stopPrice?: string; 195 | trailingDelta?: number; 196 | trailingTime?: number; 197 | icebergQty?: string; 198 | newOrderRespType?: string; 199 | timeInForce?: TimeInForce; 200 | }> }): Promise; 224 | }>>; 225 | futuresGetOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 226 | symbol: string; 227 | orderId: number; 228 | clientOrderId: string; 229 | transactTime: number; 230 | price: string; 231 | origQty: string; 232 | executedQty: string; 233 | cumQuote: string; 234 | status: OrderStatus; 235 | timeInForce: TimeInForce; 236 | type: OrderType; 237 | side: OrderSide; 238 | marginBuyBorrowAmount: string; 239 | marginBuyBorrowAsset: string; 240 | fills: Array<{ 241 | price: string; 242 | qty: string; 243 | commission: string; 244 | commissionAsset: string; 245 | }>; 246 | }>; 247 | futuresCancelOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 248 | symbol: string; 249 | origClientOrderId: string; 250 | orderId: number; 251 | orderListId: number; 252 | clientOrderId: string; 253 | transactTime: number; 254 | price: string; 255 | origQty: string; 256 | executedQty: string; 257 | cumQuote: string; 258 | status: OrderStatus; 259 | timeInForce: TimeInForce; 260 | type: OrderType; 261 | side: OrderSide; 262 | }>; 263 | futuresCancelAllOpenOrders(payload: { symbol: string }): Promise>; 279 | futuresCancelBatchOrders(payload: { symbol: string; orderIdList: number[] }): Promise>; 296 | futuresOpenOrders(payload?: { symbol?: string }): Promise; 318 | }>>; 319 | futuresAllOrders(payload: { symbol: string; orderId?: number; startTime?: number; endTime?: number; limit?: number }): Promise; 341 | }>>; 342 | futuresPositionRisk(payload?: { symbol?: string }): Promise>; 361 | futuresLeverageBracket(payload: { symbol: string }): Promise; 371 | }>>; 372 | futuresAccountBalance(): Promise>; 389 | futuresAccountInfo(): Promise<{ 390 | assets: Array<{ 391 | asset: string; 392 | walletBalance: string; 393 | unrealizedProfit: string; 394 | marginBalance: string; 395 | initialMargin: string; 396 | positionInitialMargin: string; 397 | openOrderInitialMargin: string; 398 | maxWithdrawAmount: string; 399 | crossUnPnl: string; 400 | crossWalletBalance: string; 401 | crossMarginBalance: string; 402 | availableBalance: string; 403 | marginAvailable: boolean; 404 | updateTime: number; 405 | }>; 406 | positions: Array<{ 407 | symbol: string; 408 | positionAmt: string; 409 | entryPrice: string; 410 | markPrice: string; 411 | unRealizedProfit: string; 412 | liquidationPrice: string; 413 | leverage: string; 414 | maxNotionalValue: string; 415 | marginType: string; 416 | isolatedMargin: string; 417 | isolatedWallet: string; 418 | isolatedUnrealizedProfit: string; 419 | isolatedMarginLevel: string; 420 | isolatedMaintMargin: string; 421 | isolatedMaxNotionalValue: string; 422 | notional: string; 423 | unrealizedPnl: string; 424 | marginLevel: string; 425 | }>; 426 | canDeposit: boolean; 427 | canTrade: boolean; 428 | canWithdraw: boolean; 429 | feeTier: number; 430 | updateTime: number; 431 | totalInitialMargin: string; 432 | totalMaintMargin: string; 433 | totalWalletBalance: string; 434 | totalUnrealizedProfit: string; 435 | totalMarginBalance: string; 436 | totalPositionInitialMargin: string; 437 | totalOpenOrderInitialMargin: string; 438 | totalCrossWalletBalance: string; 439 | totalCrossUnPnl: string; 440 | availableBalance: string; 441 | maxWithdrawAmount: string; 442 | }>; 443 | futuresUserTrades(payload: { symbol: string; startTime?: number; endTime?: number; fromId?: number; limit?: number }): Promise>; 460 | futuresPositionMode(payload: { dualSidePosition: boolean }): Promise<{ 461 | code: number; 462 | msg: string; 463 | }>; 464 | futuresPositionModeChange(payload: { dualSidePosition: boolean }): Promise<{ 465 | code: number; 466 | msg: string; 467 | }>; 468 | futuresLeverage(payload: { symbol: string; leverage: number }): Promise<{ 469 | leverage: number; 470 | maxNotionalValue: string; 471 | symbol: string; 472 | }>; 473 | futuresMarginType(payload: { symbol: string; marginType: string }): Promise<{ 474 | code: number; 475 | msg: string; 476 | }>; 477 | futuresPositionMargin(payload: { symbol: string; positionSide: string; amount: string; type: number }): Promise<{ 478 | code: number; 479 | msg: string; 480 | }>; 481 | futuresMarginHistory(payload: { symbol: string }): Promise>; 489 | futuresIncome(payload?: { symbol?: string; incomeType?: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 499 | getMultiAssetsMargin(payload: { multiAssetsMargin: boolean }): Promise<{ 500 | code: number; 501 | msg: string; 502 | }>; 503 | setMultiAssetsMargin(payload: { multiAssetsMargin: boolean }): Promise<{ 504 | code: number; 505 | msg: string; 506 | }>; 507 | } -------------------------------------------------------------------------------- /types/generic.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient, RateLimitType, RateLimitInterval } from './base'; 2 | 3 | export interface GenericEndpoints extends BinanceRestClient { 4 | getInfo(): Promise<{ 5 | timezone: string; 6 | serverTime: number; 7 | rateLimits: Array<{ 8 | rateLimitType: RateLimitType; 9 | interval: RateLimitInterval; 10 | intervalNum: number; 11 | limit: number; 12 | }>; 13 | exchangeFilters: any[]; 14 | symbols: Array<{ 15 | symbol: string; 16 | status: string; 17 | baseAsset: string; 18 | quoteAsset: string; 19 | orderTypes: string[]; 20 | icebergAllowed: boolean; 21 | ocoAllowed: boolean; 22 | isSpotTradingAllowed: boolean; 23 | isMarginTradingAllowed: boolean; 24 | filters: any[]; 25 | permissions: string[]; 26 | }>; 27 | }>; 28 | ping(): Promise; 29 | time(): Promise<{ serverTime: number }>; 30 | exchangeInfo(): Promise; 31 | privateRequest(method: string, url: string, payload: any): Promise; 32 | publicRequest(method: string, url: string, payload: any): Promise; 33 | } -------------------------------------------------------------------------------- /types/margin.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | import { OrderType, OrderSide, TimeInForce } from './base'; 3 | 4 | export interface MarginAsset { 5 | asset: string; 6 | borrowed: string; 7 | free: string; 8 | interest: string; 9 | locked: string; 10 | netAsset: string; 11 | } 12 | 13 | export interface MarginAccountInfo { 14 | borrowEnabled: boolean; 15 | marginLevel: string; 16 | totalAssetOfBtc: string; 17 | totalLiabilityOfBtc: string; 18 | totalNetAssetOfBtc: string; 19 | tradeEnabled: boolean; 20 | transferEnabled: boolean; 21 | userAssets: MarginAsset[]; 22 | } 23 | 24 | export interface MarginIsolatedAsset { 25 | asset: string; 26 | borrowEnabled: boolean; 27 | borrowed: string; 28 | free: string; 29 | interest: string; 30 | locked: string; 31 | netAsset: string; 32 | netAssetOfBtc: string; 33 | repayEnabled: boolean; 34 | totalAsset: string; 35 | } 36 | 37 | export interface MarginIsolatedSymbol { 38 | baseAsset: MarginIsolatedAsset; 39 | quoteAsset: MarginIsolatedAsset; 40 | symbol: string; 41 | isolatedCreated: boolean; 42 | marginLevel: string; 43 | marginLevelStatus: 'EXCESSIVE' | 'NORMAL' | 'MARGIN_CALL' | 'PRE_LIQUIDATION' | 'FORCE_LIQUIDATION'; 44 | marginRatio: string; 45 | indexPrice: string; 46 | liquidatePrice: string; 47 | liquidateRate: string; 48 | tradeEnabled: boolean; 49 | } 50 | 51 | export interface MarginIsolatedAccount { 52 | assets: MarginIsolatedSymbol[]; 53 | totalAssetOfBtc: string; 54 | totalLiabilityOfBtc: string; 55 | totalNetAssetOfBtc: string; 56 | } 57 | 58 | export interface MarginMaxBorrow { 59 | amount: string; 60 | borrowLimit: string; 61 | } 62 | 63 | export interface MarginOrderParams { 64 | symbol: string; 65 | isIsolated?: 'TRUE' | 'FALSE'; 66 | side: OrderSide; 67 | type: OrderType; 68 | quantity?: string; 69 | quoteOrderQty?: string; 70 | price?: string; 71 | stopPrice?: string; 72 | newClientOrderId?: string; 73 | icebergQty?: string; 74 | newOrderRespType?: 'ACK' | 'RESULT' | 'FULL'; 75 | sideEffectType?: 'NO_SIDE_EFFECT' | 'MARGIN_BUY' | 'AUTO_REPAY'; 76 | timeInForce?: TimeInForce; 77 | recvWindow?: number; 78 | } 79 | 80 | export interface MarginOrderOcoParams extends Omit { 81 | stopLimitPrice?: string; 82 | stopLimitTimeInForce?: TimeInForce; 83 | takeProfitPrice?: string; 84 | takeProfitLimitPrice?: string; 85 | takeProfitLimitTimeInForce?: TimeInForce; 86 | takeProfitIcebergQty?: string; 87 | stopLossPrice?: string; 88 | stopLossLimitPrice?: string; 89 | stopLossLimitTimeInForce?: TimeInForce; 90 | stopLossIcebergQty?: string; 91 | stopIcebergQty?: string; 92 | limitIcebergQty?: string; 93 | limitTimeInForce?: TimeInForce; 94 | } 95 | 96 | export interface MarginEndpoints extends BinanceRestClient { 97 | // Account endpoints 98 | marginAccountInfo(): Promise; 99 | marginIsolatedAccount(params: { symbols: string }): Promise; 100 | marginMaxBorrow(params: { asset: string; isolatedSymbol?: string }): Promise; 101 | marginCreateIsolated(params: { base: string; quote: string }): Promise<{ success: boolean; symbol: string }>; 102 | marginIsolatedTransfer(params: { 103 | asset: string; 104 | symbol: string; 105 | transFrom: 'SPOT' | 'ISOLATED_MARGIN'; 106 | transTo: 'SPOT' | 'ISOLATED_MARGIN'; 107 | amount: string; 108 | }): Promise<{ tranId: number }>; 109 | marginIsolatedTransferHistory(params: { 110 | symbol: string; 111 | asset?: string; 112 | transFrom?: 'SPOT' | 'ISOLATED_MARGIN'; 113 | transTo?: 'SPOT' | 'ISOLATED_MARGIN'; 114 | startTime?: number; 115 | endTime?: number; 116 | current?: number; 117 | size?: number; 118 | }): Promise<{ 119 | rows: Array<{ 120 | amount: string; 121 | asset: string; 122 | status: string; 123 | timestamp: number; 124 | txId: number; 125 | transFrom: string; 126 | transTo: string; 127 | }>; 128 | total: number; 129 | }>; 130 | disableMarginAccount(params: { symbol: string }): Promise<{ success: boolean; symbol: string }>; 131 | enableMarginAccount(params: { symbol: string }): Promise<{ success: boolean; symbol: string }>; 132 | marginAccount(): Promise; 133 | 134 | // Order endpoints 135 | marginOrder(params: MarginOrderParams): Promise; 136 | marginOrderOco(params: MarginOrderOcoParams): Promise; 137 | marginCancelOrder(params: { 138 | symbol: string; 139 | orderId?: number; 140 | origClientOrderId?: string; 141 | newClientOrderId?: string; 142 | }): Promise; 143 | marginOpenOrders(params?: { symbol?: string; isIsolated?: string }): Promise; 144 | marginCancelOpenOrders(params: { symbol: string; isIsolated?: string }): Promise; 145 | marginGetOrder(params: { 146 | symbol: string; 147 | isIsolated?: string; 148 | orderId?: string; 149 | origClientOrderId?: string; 150 | }): Promise; 151 | marginGetOrderOco(params: { 152 | orderListId?: number; 153 | symbol?: string; 154 | isIsolated?: boolean; 155 | listClientOrderId?: string; 156 | }): Promise; 157 | 158 | // Loan endpoints 159 | marginLoan(params: { asset: string; amount: string }): Promise<{ tranId: number }>; 160 | marginRepay(params: { asset: string; amount: string }): Promise<{ tranId: number }>; 161 | } -------------------------------------------------------------------------------- /types/market.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | 3 | export interface Trade { 4 | eventType: string; 5 | eventTime: number; 6 | symbol: string; 7 | price: string; 8 | quantity: string; 9 | maker: boolean; 10 | isBuyerMaker: boolean; 11 | tradeId: number; 12 | } 13 | 14 | export interface Ticker { 15 | eventType: string; 16 | eventTime: number; 17 | symbol: string; 18 | priceChange: string; 19 | priceChangePercent: string; 20 | weightedAvg: string; 21 | prevDayClose: string; 22 | curDayClose: string; 23 | closeTradeQuantity: string; 24 | bestBid: string; 25 | bestBidQnt: string; 26 | bestAsk: string; 27 | bestAskQnt: string; 28 | open: string; 29 | high: string; 30 | low: string; 31 | volume: string; 32 | volumeQuote: string; 33 | openTime: number; 34 | closeTime: number; 35 | firstTradeId: number; 36 | lastTradeId: number; 37 | totalTrades: number; 38 | } 39 | 40 | export interface BookTicker { 41 | symbol: string; 42 | bidPrice: string; 43 | bidQty: string; 44 | askPrice: string; 45 | askQty: string; 46 | } 47 | 48 | export interface CandleChartResult { 49 | openTime: number; 50 | open: string; 51 | high: string; 52 | low: string; 53 | close: string; 54 | volume: string; 55 | closeTime: number; 56 | quoteVolume: string; 57 | trades: number; 58 | baseAssetVolume: string; 59 | quoteAssetVolume: string; 60 | } 61 | 62 | export interface AggregatedTrade { 63 | aggId: number; 64 | symbol: string; 65 | price: string; 66 | quantity: string; 67 | firstId: number; 68 | lastId: number; 69 | timestamp: number; 70 | isBuyerMaker: boolean; 71 | wasBestPrice: boolean; 72 | } 73 | 74 | export interface MarketEndpoints extends BinanceRestClient { 75 | book(payload: { symbol: string; limit?: number }): Promise<{ 76 | lastUpdateId: number; 77 | asks: [string, string][]; 78 | bids: [string, string][]; 79 | }>; 80 | aggTrades(payload: { 81 | symbol: string; 82 | fromId?: number; 83 | startTime?: number; 84 | endTime?: number; 85 | limit?: number; 86 | }): Promise; 87 | candles(payload: { 88 | symbol: string; 89 | interval: string; 90 | startTime?: number; 91 | endTime?: number; 92 | limit?: number; 93 | }): Promise; 94 | trades(payload: { symbol: string; limit?: number }): Promise; 95 | tradesHistory(payload: { symbol: string; limit?: number }): Promise; 96 | dailyStats(payload: { symbol: string }): Promise; 97 | prices(): Promise>; 98 | avgPrice(payload: { symbol: string }): Promise<{ 99 | mins: number; 100 | price: string; 101 | }>; 102 | allBookTickers(): Promise; 103 | ticker24hr(payload: { symbol: string }): Promise; 104 | tickerPrice(payload: { symbol: string }): Promise<{ 105 | symbol: string; 106 | price: string; 107 | }>; 108 | bookTicker(payload: { symbol: string }): Promise; 109 | } -------------------------------------------------------------------------------- /types/mining.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | 3 | export interface MiningEndpoints extends BinanceRestClient { 4 | miningAlgorithms(): Promise>; 10 | miningCoinName(): Promise>; 22 | miningDetails(payload: { algo: string; userName: string; coinName: string; startDate: number; endDate: number }): Promise>; 39 | miningEarnings(payload: { algo: string; userName: string; coinName: string; startDate: number; endDate: number }): Promise>; 63 | miningExtraBonusList(payload: { algo: string; userName: string; coinName: string; startDate: number; endDate: number }): Promise>; 86 | miningHashrateResaleRequest(payload: { userName: string; coinName: string; algo: string; startDate: number; endDate: number; pageIndex: number; pageSize: number }): Promise<{ 87 | code: number; 88 | msg: string; 89 | data: { 90 | totalNum: number; 91 | pageSize: number; 92 | pageNum: number; 93 | totalPageNum: number; 94 | configDetails: Array<{ 95 | poolUsername: string; 96 | toPoolUsername: string; 97 | algoName: string; 98 | hashRate: string; 99 | startDay: number; 100 | endDay: number; 101 | status: number; 102 | configName: string; 103 | configId: number; 104 | }>; 105 | }; 106 | }>; 107 | miningHashrateResaleDetails(payload: { configId: number; pageIndex: number; pageSize: number }): Promise<{ 108 | code: number; 109 | msg: string; 110 | data: { 111 | totalNum: number; 112 | pageSize: number; 113 | pageNum: number; 114 | totalPageNum: number; 115 | profitTransferDetails: Array<{ 116 | poolUsername: string; 117 | toPoolUsername: string; 118 | algoName: string; 119 | hashRate: string; 120 | day: number; 121 | amount: number; 122 | coinName: string; 123 | }>; 124 | }; 125 | }>; 126 | miningHashrateResaleList(payload: { pageIndex: number; pageSize: number }): Promise<{ 127 | code: number; 128 | msg: string; 129 | data: { 130 | totalNum: number; 131 | pageSize: number; 132 | pageNum: number; 133 | totalPageNum: number; 134 | configDetails: Array<{ 135 | poolUsername: string; 136 | toPoolUsername: string; 137 | algoName: string; 138 | hashRate: string; 139 | startDay: number; 140 | endDay: number; 141 | status: number; 142 | configName: string; 143 | configId: number; 144 | }>; 145 | }; 146 | }>; 147 | miningHashrateResaleRequest(payload: { userName: string; coinName: string; algo: string; startDate: number; endDate: number; toPoolUsername: string; hashRate: string }): Promise<{ 148 | code: number; 149 | msg: string; 150 | data: number; 151 | }>; 152 | miningHashrateResaleCancel(payload: { configId: number; userName: string }): Promise<{ 153 | code: number; 154 | msg: string; 155 | data: boolean; 156 | }>; 157 | miningStatistics(payload: { algo: string; userName: string }): Promise>; 168 | miningAccountList(payload: { algo: string; userName: string }): Promise; 176 | }>>; 177 | miningWorkerList(payload: { algo: string; userName: string }): Promise>; 195 | miningPaymentList(payload: { algo: string; userName: string; coinName: string; startDate: number; endDate: number }): Promise>; 218 | miningHashrateTransfer(payload: { algo: string; userName: string; coinName: string; startDate: number; endDate: number }): Promise>; 241 | miningHashrateTransferDetails(payload: { configId: number; pageIndex: number; pageSize: number }): Promise<{ 242 | code: number; 243 | msg: string; 244 | data: { 245 | totalNum: number; 246 | pageSize: number; 247 | pageNum: number; 248 | totalPageNum: number; 249 | profitTransferDetails: Array<{ 250 | poolUsername: string; 251 | toPoolUsername: string; 252 | algoName: string; 253 | hashRate: string; 254 | day: number; 255 | amount: number; 256 | coinName: string; 257 | }>; 258 | }; 259 | }>; 260 | miningHashrateTransferList(payload: { pageIndex: number; pageSize: number }): Promise<{ 261 | code: number; 262 | msg: string; 263 | data: { 264 | totalNum: number; 265 | pageSize: number; 266 | pageNum: number; 267 | totalPageNum: number; 268 | configDetails: Array<{ 269 | poolUsername: string; 270 | toPoolUsername: string; 271 | algoName: string; 272 | hashRate: string; 273 | startDay: number; 274 | endDay: number; 275 | status: number; 276 | configName: string; 277 | configId: number; 278 | }>; 279 | }; 280 | }>; 281 | miningHashrateTransferRequest(payload: { userName: string; coinName: string; algo: string; startDate: number; endDate: number; toPoolUsername: string; hashRate: string }): Promise<{ 282 | code: number; 283 | msg: string; 284 | data: number; 285 | }>; 286 | miningHashrateTransferCancel(payload: { configId: number; userName: string }): Promise<{ 287 | code: number; 288 | msg: string; 289 | data: boolean; 290 | }>; 291 | } -------------------------------------------------------------------------------- /types/order.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient, OrderSide, OrderStatus, OrderType, TimeInForce } from './base'; 2 | 3 | export interface OrderEndpoints extends BinanceRestClient { 4 | order(payload: { 5 | symbol: string; 6 | side: OrderSide; 7 | type: OrderType; 8 | quantity?: string; 9 | quoteOrderQty?: string; 10 | price?: string; 11 | newClientOrderId?: string; 12 | stopPrice?: string; 13 | trailingDelta?: number; 14 | trailingTime?: number; 15 | icebergQty?: string; 16 | newOrderRespType?: string; 17 | timeInForce?: TimeInForce; 18 | }): Promise<{ 19 | symbol: string; 20 | orderId: number; 21 | orderListId: number; 22 | clientOrderId: string; 23 | transactTime: number; 24 | price: string; 25 | origQty: string; 26 | executedQty: string; 27 | cummulativeQuoteQty: string; 28 | status: OrderStatus; 29 | timeInForce: TimeInForce; 30 | type: OrderType; 31 | side: OrderSide; 32 | marginBuyBorrowAmount: string; 33 | marginBuyBorrowAsset: string; 34 | fills: Array<{ 35 | price: string; 36 | qty: string; 37 | commission: string; 38 | commissionAsset: string; 39 | }>; 40 | }>; 41 | orderOco(payload: { 42 | symbol: string; 43 | side: OrderSide; 44 | quantity: string; 45 | price: string; 46 | stopPrice: string; 47 | stopLimitPrice?: string; 48 | stopLimitTimeInForce?: TimeInForce; 49 | takeProfitPrice?: string; 50 | takeProfitLimitPrice?: string; 51 | takeProfitLimitTimeInForce?: TimeInForce; 52 | trailingDelta?: number; 53 | trailingTime?: number; 54 | icebergQty?: string; 55 | newOrderRespType?: string; 56 | }): Promise<{ 57 | orderListId: number; 58 | contingencyType: string; 59 | listStatusType: string; 60 | listOrderStatus: string; 61 | listClientOrderId: string; 62 | transactTime: number; 63 | symbol: string; 64 | orders: Array<{ 65 | symbol: string; 66 | orderId: number; 67 | clientOrderId: string; 68 | }>; 69 | orderReports: Array<{ 70 | symbol: string; 71 | orderId: number; 72 | orderListId: number; 73 | clientOrderId: string; 74 | transactTime: number; 75 | price: string; 76 | origQty: string; 77 | executedQty: string; 78 | cummulativeQuoteQty: string; 79 | status: OrderStatus; 80 | timeInForce: TimeInForce; 81 | type: OrderType; 82 | side: OrderSide; 83 | stopPrice: string; 84 | workingTime: number; 85 | selfTradePreventionMode: string; 86 | fills: Array<{ 87 | price: string; 88 | qty: string; 89 | commission: string; 90 | commissionAsset: string; 91 | }>; 92 | }>; 93 | }>; 94 | orderTest(payload: { 95 | symbol: string; 96 | side: OrderSide; 97 | type: OrderType; 98 | quantity?: string; 99 | quoteOrderQty?: string; 100 | price?: string; 101 | newClientOrderId?: string; 102 | stopPrice?: string; 103 | trailingDelta?: number; 104 | trailingTime?: number; 105 | icebergQty?: string; 106 | newOrderRespType?: string; 107 | timeInForce?: TimeInForce; 108 | }): Promise<{ 109 | symbol: string; 110 | orderId: number; 111 | orderListId: number; 112 | clientOrderId: string; 113 | transactTime: number; 114 | price: string; 115 | origQty: string; 116 | executedQty: string; 117 | cummulativeQuoteQty: string; 118 | status: OrderStatus; 119 | timeInForce: TimeInForce; 120 | type: OrderType; 121 | side: OrderSide; 122 | marginBuyBorrowAmount: string; 123 | marginBuyBorrowAsset: string; 124 | fills: Array<{ 125 | price: string; 126 | qty: string; 127 | commission: string; 128 | commissionAsset: string; 129 | }>; 130 | }>; 131 | getOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 132 | symbol: string; 133 | orderId: number; 134 | orderListId: number; 135 | clientOrderId: string; 136 | transactTime: number; 137 | price: string; 138 | origQty: string; 139 | executedQty: string; 140 | cummulativeQuoteQty: string; 141 | status: OrderStatus; 142 | timeInForce: TimeInForce; 143 | type: OrderType; 144 | side: OrderSide; 145 | marginBuyBorrowAmount: string; 146 | marginBuyBorrowAsset: string; 147 | fills: Array<{ 148 | price: string; 149 | qty: string; 150 | commission: string; 151 | commissionAsset: string; 152 | }>; 153 | }>; 154 | getOrderOco(payload: { orderListId?: number; origClientOrderId?: string }): Promise<{ 155 | orderListId: number; 156 | contingencyType: string; 157 | listStatusType: string; 158 | listOrderStatus: string; 159 | listClientOrderId: string; 160 | transactTime: number; 161 | symbol: string; 162 | orders: Array<{ 163 | symbol: string; 164 | orderId: number; 165 | clientOrderId: string; 166 | }>; 167 | orderReports: Array<{ 168 | symbol: string; 169 | orderId: number; 170 | orderListId: number; 171 | clientOrderId: string; 172 | transactTime: number; 173 | price: string; 174 | origQty: string; 175 | executedQty: string; 176 | cummulativeQuoteQty: string; 177 | status: OrderStatus; 178 | timeInForce: TimeInForce; 179 | type: OrderType; 180 | side: OrderSide; 181 | stopPrice: string; 182 | workingTime: number; 183 | selfTradePreventionMode: string; 184 | fills: Array<{ 185 | price: string; 186 | qty: string; 187 | commission: string; 188 | commissionAsset: string; 189 | }>; 190 | }>; 191 | }>; 192 | cancelOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string; newClientOrderId?: string }): Promise<{ 193 | symbol: string; 194 | origClientOrderId: string; 195 | orderId: number; 196 | orderListId: number; 197 | clientOrderId: string; 198 | transactTime: number; 199 | price: string; 200 | origQty: string; 201 | executedQty: string; 202 | cummulativeQuoteQty: string; 203 | status: OrderStatus; 204 | timeInForce: TimeInForce; 205 | type: OrderType; 206 | side: OrderSide; 207 | }>; 208 | cancelOrderOco(payload: { symbol: string; orderListId?: number; listClientOrderId?: string; newClientOrderId?: string }): Promise<{ 209 | orderListId: number; 210 | contingencyType: string; 211 | listStatusType: string; 212 | listOrderStatus: string; 213 | listClientOrderId: string; 214 | transactTime: number; 215 | symbol: string; 216 | orders: Array<{ 217 | symbol: string; 218 | orderId: number; 219 | clientOrderId: string; 220 | }>; 221 | orderReports: Array<{ 222 | symbol: string; 223 | orderId: number; 224 | orderListId: number; 225 | clientOrderId: string; 226 | transactTime: number; 227 | price: string; 228 | origQty: string; 229 | executedQty: string; 230 | cummulativeQuoteQty: string; 231 | status: OrderStatus; 232 | timeInForce: TimeInForce; 233 | type: OrderType; 234 | side: OrderSide; 235 | stopPrice: string; 236 | workingTime: number; 237 | selfTradePreventionMode: string; 238 | fills: Array<{ 239 | price: string; 240 | qty: string; 241 | commission: string; 242 | commissionAsset: string; 243 | }>; 244 | }>; 245 | }>; 246 | cancelOpenOrders(payload: { symbol: string }): Promise>; 262 | openOrders(payload?: { symbol?: string }): Promise; 284 | }>>; 285 | allOrders(payload: { symbol: string; orderId?: number; startTime?: number; endTime?: number; limit?: number }): Promise; 307 | }>>; 308 | allOrdersOCO(payload: { fromId?: number; startTime?: number; endTime?: number; limit?: number }): Promise; 321 | orderReports: Array<{ 322 | symbol: string; 323 | orderId: number; 324 | orderListId: number; 325 | clientOrderId: string; 326 | transactTime: number; 327 | price: string; 328 | origQty: string; 329 | executedQty: string; 330 | cummulativeQuoteQty: string; 331 | status: OrderStatus; 332 | timeInForce: TimeInForce; 333 | type: OrderType; 334 | side: OrderSide; 335 | stopPrice: string; 336 | workingTime: number; 337 | selfTradePreventionMode: string; 338 | fills: Array<{ 339 | price: string; 340 | qty: string; 341 | commission: string; 342 | commissionAsset: string; 343 | }>; 344 | }>; 345 | }>>; 346 | } -------------------------------------------------------------------------------- /types/papi.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient, OrderSide, OrderStatus, OrderType, TimeInForce } from './base'; 2 | 3 | export interface PAPIEndpoints extends BinanceRestClient { 4 | papiPing(): Promise; 5 | papiUmOrder(payload: { 6 | symbol: string; 7 | side: OrderSide; 8 | type: OrderType; 9 | quantity?: string; 10 | quoteOrderQty?: string; 11 | price?: string; 12 | newClientOrderId?: string; 13 | stopPrice?: string; 14 | trailingDelta?: number; 15 | trailingTime?: number; 16 | icebergQty?: string; 17 | newOrderRespType?: string; 18 | timeInForce?: TimeInForce; 19 | }): Promise<{ 20 | symbol: string; 21 | orderId: number; 22 | orderListId: number; 23 | clientOrderId: string; 24 | transactTime: number; 25 | price: string; 26 | origQty: string; 27 | executedQty: string; 28 | cumQuote: string; 29 | status: OrderStatus; 30 | timeInForce: TimeInForce; 31 | type: OrderType; 32 | side: OrderSide; 33 | marginBuyBorrowAmount: string; 34 | marginBuyBorrowAsset: string; 35 | fills: Array<{ 36 | price: string; 37 | qty: string; 38 | commission: string; 39 | commissionAsset: string; 40 | }>; 41 | }>; 42 | papiUmConditionalOrder(payload: { 43 | symbol: string; 44 | side: OrderSide; 45 | type: OrderType; 46 | quantity?: string; 47 | quoteOrderQty?: string; 48 | price?: string; 49 | newClientOrderId?: string; 50 | stopPrice?: string; 51 | trailingDelta?: number; 52 | trailingTime?: number; 53 | icebergQty?: string; 54 | newOrderRespType?: string; 55 | timeInForce?: TimeInForce; 56 | }): Promise<{ 57 | symbol: string; 58 | orderId: number; 59 | orderListId: number; 60 | clientOrderId: string; 61 | transactTime: number; 62 | price: string; 63 | origQty: string; 64 | executedQty: string; 65 | cumQuote: string; 66 | status: OrderStatus; 67 | timeInForce: TimeInForce; 68 | type: OrderType; 69 | side: OrderSide; 70 | marginBuyBorrowAmount: string; 71 | marginBuyBorrowAsset: string; 72 | fills: Array<{ 73 | price: string; 74 | qty: string; 75 | commission: string; 76 | commissionAsset: string; 77 | }>; 78 | }>; 79 | papiCmOrder(payload: { 80 | symbol: string; 81 | side: OrderSide; 82 | type: OrderType; 83 | quantity?: string; 84 | quoteOrderQty?: string; 85 | price?: string; 86 | newClientOrderId?: string; 87 | stopPrice?: string; 88 | trailingDelta?: number; 89 | trailingTime?: number; 90 | icebergQty?: string; 91 | newOrderRespType?: string; 92 | timeInForce?: TimeInForce; 93 | }): Promise<{ 94 | symbol: string; 95 | orderId: number; 96 | orderListId: number; 97 | clientOrderId: string; 98 | transactTime: number; 99 | price: string; 100 | origQty: string; 101 | executedQty: string; 102 | cumQuote: string; 103 | status: OrderStatus; 104 | timeInForce: TimeInForce; 105 | type: OrderType; 106 | side: OrderSide; 107 | marginBuyBorrowAmount: string; 108 | marginBuyBorrowAsset: string; 109 | fills: Array<{ 110 | price: string; 111 | qty: string; 112 | commission: string; 113 | commissionAsset: string; 114 | }>; 115 | }>; 116 | papiCmConditionalOrder(payload: { 117 | symbol: string; 118 | side: OrderSide; 119 | type: OrderType; 120 | quantity?: string; 121 | quoteOrderQty?: string; 122 | price?: string; 123 | newClientOrderId?: string; 124 | stopPrice?: string; 125 | trailingDelta?: number; 126 | trailingTime?: number; 127 | icebergQty?: string; 128 | newOrderRespType?: string; 129 | timeInForce?: TimeInForce; 130 | }): Promise<{ 131 | symbol: string; 132 | orderId: number; 133 | orderListId: number; 134 | clientOrderId: string; 135 | transactTime: number; 136 | price: string; 137 | origQty: string; 138 | executedQty: string; 139 | cumQuote: string; 140 | status: OrderStatus; 141 | timeInForce: TimeInForce; 142 | type: OrderType; 143 | side: OrderSide; 144 | marginBuyBorrowAmount: string; 145 | marginBuyBorrowAsset: string; 146 | fills: Array<{ 147 | price: string; 148 | qty: string; 149 | commission: string; 150 | commissionAsset: string; 151 | }>; 152 | }>; 153 | papiMarginOrder(payload: { 154 | symbol: string; 155 | side: OrderSide; 156 | type: OrderType; 157 | quantity?: string; 158 | quoteOrderQty?: string; 159 | price?: string; 160 | newClientOrderId?: string; 161 | stopPrice?: string; 162 | trailingDelta?: number; 163 | trailingTime?: number; 164 | icebergQty?: string; 165 | newOrderRespType?: string; 166 | timeInForce?: TimeInForce; 167 | }): Promise<{ 168 | symbol: string; 169 | orderId: number; 170 | orderListId: number; 171 | clientOrderId: string; 172 | transactTime: number; 173 | price: string; 174 | origQty: string; 175 | executedQty: string; 176 | cumQuote: string; 177 | status: OrderStatus; 178 | timeInForce: TimeInForce; 179 | type: OrderType; 180 | side: OrderSide; 181 | marginBuyBorrowAmount: string; 182 | marginBuyBorrowAsset: string; 183 | fills: Array<{ 184 | price: string; 185 | qty: string; 186 | commission: string; 187 | commissionAsset: string; 188 | }>; 189 | }>; 190 | papiMarginLoan(payload: { 191 | asset: string; 192 | amount: string; 193 | isIsolated?: boolean; 194 | symbol?: string; 195 | }): Promise<{ 196 | tranId: number; 197 | }>; 198 | papiRepayLoan(payload: { 199 | asset: string; 200 | amount: string; 201 | isIsolated?: boolean; 202 | symbol?: string; 203 | }): Promise<{ 204 | tranId: number; 205 | }>; 206 | papiMarginOrderOco(payload: { 207 | symbol: string; 208 | side: OrderSide; 209 | quantity: string; 210 | price: string; 211 | stopPrice: string; 212 | stopLimitPrice?: string; 213 | stopLimitTimeInForce?: TimeInForce; 214 | takeProfitPrice?: string; 215 | takeProfitLimitPrice?: string; 216 | takeProfitLimitTimeInForce?: TimeInForce; 217 | trailingDelta?: number; 218 | trailingTime?: number; 219 | icebergQty?: string; 220 | newOrderRespType?: string; 221 | }): Promise<{ 222 | orderListId: number; 223 | contingencyType: string; 224 | listStatusType: string; 225 | listOrderStatus: string; 226 | listClientOrderId: string; 227 | transactTime: number; 228 | symbol: string; 229 | orders: Array<{ 230 | symbol: string; 231 | orderId: number; 232 | clientOrderId: string; 233 | }>; 234 | orderReports: Array<{ 235 | symbol: string; 236 | orderId: number; 237 | orderListId: number; 238 | clientOrderId: string; 239 | transactTime: number; 240 | price: string; 241 | origQty: string; 242 | executedQty: string; 243 | cumQuote: string; 244 | status: OrderStatus; 245 | timeInForce: TimeInForce; 246 | type: OrderType; 247 | side: OrderSide; 248 | stopPrice: string; 249 | workingType: string; 250 | priceProtect: boolean; 251 | origType: string; 252 | }>; 253 | }>; 254 | papiUmCancelOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 255 | symbol: string; 256 | origClientOrderId: string; 257 | orderId: number; 258 | orderListId: number; 259 | clientOrderId: string; 260 | transactTime: number; 261 | price: string; 262 | origQty: string; 263 | executedQty: string; 264 | cumQuote: string; 265 | status: OrderStatus; 266 | timeInForce: TimeInForce; 267 | type: OrderType; 268 | side: OrderSide; 269 | }>; 270 | papiUmCancelAllOpenOrders(payload: { symbol: string }): Promise>; 286 | papiUmCancelConditionalOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 287 | symbol: string; 288 | origClientOrderId: string; 289 | orderId: number; 290 | orderListId: number; 291 | clientOrderId: string; 292 | transactTime: number; 293 | price: string; 294 | origQty: string; 295 | executedQty: string; 296 | cumQuote: string; 297 | status: OrderStatus; 298 | timeInForce: TimeInForce; 299 | type: OrderType; 300 | side: OrderSide; 301 | }>; 302 | papiUmCancelConditionalAllOpenOrders(payload: { symbol: string }): Promise>; 318 | papiCmCancelOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 319 | symbol: string; 320 | origClientOrderId: string; 321 | orderId: number; 322 | orderListId: number; 323 | clientOrderId: string; 324 | transactTime: number; 325 | price: string; 326 | origQty: string; 327 | executedQty: string; 328 | cumQuote: string; 329 | status: OrderStatus; 330 | timeInForce: TimeInForce; 331 | type: OrderType; 332 | side: OrderSide; 333 | }>; 334 | papiCmCancelAllOpenOrders(payload: { symbol: string }): Promise>; 350 | papiCmCancelConditionalOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 351 | symbol: string; 352 | origClientOrderId: string; 353 | orderId: number; 354 | orderListId: number; 355 | clientOrderId: string; 356 | transactTime: number; 357 | price: string; 358 | origQty: string; 359 | executedQty: string; 360 | cumQuote: string; 361 | status: OrderStatus; 362 | timeInForce: TimeInForce; 363 | type: OrderType; 364 | side: OrderSide; 365 | }>; 366 | papiCmCancelConditionalAllOpenOrders(payload: { symbol: string }): Promise>; 382 | papiMarginCancelOrder(payload: { symbol: string; orderId?: number; origClientOrderId?: string }): Promise<{ 383 | symbol: string; 384 | origClientOrderId: string; 385 | orderId: number; 386 | orderListId: number; 387 | clientOrderId: string; 388 | transactTime: number; 389 | price: string; 390 | origQty: string; 391 | executedQty: string; 392 | cumQuote: string; 393 | status: OrderStatus; 394 | timeInForce: TimeInForce; 395 | type: OrderType; 396 | side: OrderSide; 397 | }>; 398 | } -------------------------------------------------------------------------------- /types/portfolio-margin.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | 3 | export interface PortfolioMarginEndpoints extends BinanceRestClient { 4 | portfolioMarginAccountInfo(): Promise<{ 5 | totalInitialMargin: string; 6 | totalMaintMargin: string; 7 | totalWalletBalance: string; 8 | totalUnrealizedProfit: string; 9 | totalMarginBalance: string; 10 | totalPositionInitialMargin: string; 11 | totalOpenOrderInitialMargin: string; 12 | totalCrossWalletBalance: string; 13 | totalCrossUnPnl: string; 14 | availableBalance: string; 15 | maxWithdrawAmount: string; 16 | assets: Array<{ 17 | asset: string; 18 | walletBalance: string; 19 | unrealizedProfit: string; 20 | marginBalance: string; 21 | initialMargin: string; 22 | positionInitialMargin: string; 23 | openOrderInitialMargin: string; 24 | maxWithdrawAmount: string; 25 | crossWalletBalance: string; 26 | crossUnPnl: string; 27 | availableBalance: string; 28 | marginAvailable: boolean; 29 | updateTime: number; 30 | }>; 31 | positions: Array<{ 32 | symbol: string; 33 | positionAmt: string; 34 | entryPrice: string; 35 | markPrice: string; 36 | unRealizedProfit: string; 37 | liquidationPrice: string; 38 | leverage: string; 39 | maxNotionalValue: string; 40 | marginType: string; 41 | isolatedMargin: string; 42 | isolatedWallet: string; 43 | isolatedUnrealizedProfit: string; 44 | isolatedMarginLevel: string; 45 | isolatedMaintMargin: string; 46 | isolatedMaxNotionalValue: string; 47 | notional: string; 48 | unrealizedPnl: string; 49 | marginLevel: string; 50 | }>; 51 | }>; 52 | portfolioMarginCollateralRate(): Promise>; 56 | portfolioMarginLoan(payload: { asset: string; amount: string }): Promise; 57 | portfolioMarginLoanRepay(payload: { asset: string; amount: string }): Promise; 58 | portfolioMarginInterestHistory(payload: { asset: string }): Promise; 59 | } -------------------------------------------------------------------------------- /types/savings.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | 3 | export interface SavingsEndpoints extends BinanceRestClient { 4 | savingsProducts(payload: { type: 'ACTIVITY' | 'CUSTOMIZED_FIXED' }): Promise; 43 | }>>; 44 | savingsPurchase(payload: { productId: string; amount: string }): Promise<{ 45 | purchaseId: number; 46 | }>; 47 | savingsRedeem(payload: { productId: string; amount: string; type: 'FAST' | 'NORMAL' }): Promise<{ 48 | redeemId: number; 49 | }>; 50 | savingsRedemptionQuota(payload: { productId: string; type: 'FAST' | 'NORMAL' }): Promise<{ 51 | asset: string; 52 | productId: string; 53 | leftQuota: string; 54 | minAmount: string; 55 | maxAmount: string; 56 | leftAmount: string; 57 | redeemAmount: string; 58 | apy: string; 59 | }>; 60 | savingsProjectPosition(payload: { asset: string }): Promise>; 74 | savingsAccount(): Promise<{ 75 | totalAssetInBtc: string; 76 | totalAssetInUsdt: string; 77 | totalFixedAmountAssetInBtc: string; 78 | totalFixedAmountAssetInUsdt: string; 79 | totalLendingAmountInBtc: string; 80 | totalLendingAmountInUsdt: string; 81 | totalAvailableAssetInBtc: string; 82 | totalAvailableAssetInUsdt: string; 83 | totalAmountInBtc: string; 84 | totalAmountInUsdt: string; 85 | totalFlexibleAmountInBtc: string; 86 | totalFlexibleAmountInUsdt: string; 87 | }>; 88 | savingsTransfer(payload: { projectId: string; asset: string; amount: number; type: 'IN' | 'OUT' }): Promise<{ 89 | transferId: number; 90 | }>; 91 | savingsTransferQuota(payload: { projectId: string; asset: string }): Promise<{ 92 | asset: string; 93 | projectId: string; 94 | leftQuota: string; 95 | minAmount: string; 96 | maxAmount: string; 97 | leftAmount: string; 98 | transferAmount: string; 99 | apy: string; 100 | }>; 101 | savingsInterestHistory(payload: { asset: string; startTime?: number; endTime?: number; limit?: number }): Promise>; 111 | savingsPosition(payload: { asset: string }): Promise>; 124 | } -------------------------------------------------------------------------------- /types/shared.d.ts: -------------------------------------------------------------------------------- 1 | export const enum ErrorCodes { 2 | UNKNOWN = -1000, 3 | DISCONNECTED = -1001, 4 | UNAUTHORIZED = -1002, 5 | TOO_MANY_REQUESTS = -1003, 6 | UNEXPECTED_RESP = -1006, 7 | TIMEOUT = -1007, 8 | INVALID_MESSAGE = -1013, 9 | UNKNOWN_ORDER_COMPOSITION = -1014, 10 | TOO_MANY_ORDERS = -1015, 11 | SERVICE_SHUTTING_DOWN = -1016, 12 | UNSUPPORTED_OPERATION = -1020, 13 | INVALID_TIMESTAMP = -1021, 14 | INVALID_SIGNATURE = -1022, 15 | ILLEGAL_CHARS = -1100, 16 | TOO_MANY_PARAMETERS = -1101, 17 | MANDATORY_PARAM_EMPTY_OR_MALFORMED = -1102, 18 | UNKNOWN_PARAM = -1103, 19 | UNREAD_PARAMETERS = -1104, 20 | PARAM_EMPTY = -1105, 21 | PARAM_NOT_REQUIRED = -1106, 22 | NO_DEPTH = -1112, 23 | TIF_NOT_REQUIRED = -1114, 24 | INVALID_TIF = -1115, 25 | INVALID_ORDER_TYPE = -1116, 26 | INVALID_SIDE = -1117, 27 | EMPTY_NEW_CL_ORD_ID = -1118, 28 | EMPTY_ORG_CL_ORD_ID = -1119, 29 | BAD_INTERVAL = -1120, 30 | BAD_SYMBOL = -1121, 31 | INVALID_LISTEN_KEY = -1125, 32 | MORE_THAN_XX_HOURS = -1127, 33 | OPTIONAL_PARAMS_BAD_COMBO = -1128, 34 | INVALID_PARAMETER = -1130, 35 | BAD_API_ID = -2008, 36 | DUPLICATE_API_KEY_DESC = -2009, 37 | INSUFFICIENT_BALANCE = -2010, 38 | CANCEL_ALL_FAIL = -2012, 39 | NO_SUCH_ORDER = -2013, 40 | BAD_API_KEY_FMT = -2014, 41 | REJECTED_MBX_KEY = -2015, 42 | } 43 | 44 | export enum HttpMethod { 45 | GET = 'GET', 46 | HEAD = 'HEAD', 47 | POST = 'POST', 48 | PUT = 'PUT', 49 | DELETE = 'DELETE', 50 | CONNECT = 'CONNECT', 51 | OPTIONS = 'OPTIONS', 52 | TRACE = 'TRACE', 53 | PATCH = 'PATCH', 54 | } 55 | 56 | export type booleanString = 'true' | 'false' -------------------------------------------------------------------------------- /types/stream.d.ts: -------------------------------------------------------------------------------- 1 | import { BinanceRestClient } from './base'; 2 | 3 | export interface StreamEndpoints extends BinanceRestClient { 4 | getDataStream(): Promise<{ 5 | listenKey: string; 6 | }>; 7 | keepDataStream(payload: { listenKey: string }): Promise<{ 8 | listenKey: string; 9 | code: number; 10 | msg: string; 11 | }>; 12 | closeDataStream(payload: { listenKey: string }): Promise<{ 13 | listenKey: string; 14 | code: number; 15 | msg: string; 16 | }>; 17 | marginGetDataStream(): Promise<{ 18 | listenKey: string; 19 | }>; 20 | marginKeepDataStream(payload: { listenKey: string }): Promise<{ 21 | listenKey: string; 22 | code: number; 23 | msg: string; 24 | }>; 25 | marginCloseDataStream(payload: { listenKey: string }): Promise<{ 26 | listenKey: string; 27 | code: number; 28 | msg: string; 29 | }>; 30 | futuresGetDataStream(): Promise<{ 31 | listenKey: string; 32 | }>; 33 | futuresKeepDataStream(payload: { listenKey: string }): Promise<{ 34 | listenKey: string; 35 | code: number; 36 | msg: string; 37 | }>; 38 | futuresCloseDataStream(payload: { listenKey: string }): Promise<{ 39 | listenKey: string; 40 | code: number; 41 | msg: string; 42 | }>; 43 | deliveryGetDataStream(): Promise<{ 44 | listenKey: string; 45 | }>; 46 | deliveryKeepDataStream(payload: { listenKey: string }): Promise<{ 47 | listenKey: string; 48 | code: number; 49 | msg: string; 50 | }>; 51 | deliveryCloseDataStream(payload: { listenKey: string }): Promise<{ 52 | listenKey: string; 53 | code: number; 54 | msg: string; 55 | }>; 56 | } -------------------------------------------------------------------------------- /types/utility.d.ts: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------