From 695391c18bef39cfd338c7c7420d60695ccd2fcb Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Mon, 21 Apr 2025 19:38:46 +0200 Subject: [PATCH 1/3] fix(client): margin endpoints --- examples/class-example.mts | 14 +++++++++++--- tests/binance-class-static.test.ts | 21 +++++++++++++++++++++ 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/examples/class-example.mts b/examples/class-example.mts index 32fb831c..3e648c83 100644 --- a/examples/class-example.mts +++ b/examples/class-example.mts @@ -7,9 +7,17 @@ async function main() { APISECRET: 'x8gLihunpNq0d46F2q0TWJmeCDahX5LMXSlv3lSFNbMI3rujSOpTDKdhbcmPSf2i', test: true }); - const order = await binance.marketBuy("LTCUSDT", 0.1); - console.log( order ); - console.log( 'Hello, World!' ); + + // const callback = (e) => console.log(e); + // const url = binance.futuresAggTradeStream('BTCUSDT', callback); + // console.log('WebSocket URL:', url); + // await new Promise(r => setTimeout(r, 5000)); + // console.log('after sleep') + // binance.futuresTerminate(url); + + binance.websockets.depthCache( [ 'BTCUSDT', 'ETHUSDT' ], ( a_symbol, a_depth ) => { + console.log( a_symbol, a_depth ); + } ); } main() \ No newline at end of file diff --git a/tests/binance-class-static.test.ts b/tests/binance-class-static.test.ts index 1ef4a078..c64f6205 100644 --- a/tests/binance-class-static.test.ts +++ b/tests/binance-class-static.test.ts @@ -266,6 +266,27 @@ describe( 'Static tests', async function () { assert(obj.newClientOrderId.startsWith(SPOT_PREFIX)) }) + it( 'spot open orders', async function ( ) { + await binance.openOrders( 'LTCUSDT') + assert.isTrue( interceptedUrl.startsWith('https://api.binance.com/api/v3/openOrders' )) + }) + + it( 'margin open orders', async function ( ) { + await binance.mgOpenOrders( 'LTCUSDT') + assert.isTrue( interceptedUrl.startsWith('https://api.binance.com/sapi/v1/margin/openOrders' )) + }) + + it( 'Margin MarketBuy order', async function ( ) { + await binance.mgMarketBuy( 'LTCUSDT', 0.5) + assert.equal( interceptedUrl, 'https://api.binance.com/sapi/v1/margin/order' ) + const obj = urlToObject( interceptedBody ) + assert.equal( obj.symbol, 'LTCUSDT' ) + assert.equal( obj.side, 'BUY' ) + assert.equal( obj.type, 'MARKET' ) + assert.equal( obj.quantity, 0.5 ) + assert(obj.newClientOrderId.startsWith(SPOT_PREFIX)) + }) + it( 'spot order with custom clientorderId', async function ( ) { await binance.order( 'LIMIT', 'BUY', 'LTCUSDT', 0.5, 100, {'newClientOrderId': 'myid'}) assert.equal( interceptedUrl, 'https://api.binance.com/api/v3/order' ) From 950402d59134eeb4440175e7895cefc6955ff083 Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:47:54 +0100 Subject: [PATCH 2/3] add sapi --- src/node-binance-api.ts | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/node-binance-api.ts b/src/node-binance-api.ts index 5fc44497..a7d74ce5 100644 --- a/src/node-binance-api.ts +++ b/src/node-binance-api.ts @@ -237,6 +237,10 @@ export default class Binance { return this.base; } + getSapiUrl(){ + return this.sapi; + } + getFapiUrl() { if (this.Options.test) return this.fapiTest; return this.fapi; @@ -623,7 +627,7 @@ export default class Binance { } /** - * Create a signed spot/margin request + * Create a signed spot request * @param {string} path - url path * @param {object} data - The data to send * @param {string} method - the http method @@ -634,6 +638,10 @@ export default class Binance { return await this.signedRequest/**/(this.getSpotUrl() + path, data, method, noDataInSignature); } + async privateSapiRequest(path: string, data: Dict = {}, method: HttpMethod = 'GET', noDataInSignature = false) { + return await this.signedRequest/**/(this.getSapiUrl() + path, data, method, noDataInSignature); + } + /** * Create a signed http request * @param {string} url - The http endpoint @@ -1029,7 +1037,7 @@ export default class Binance { request.stopPrice = params.stopPrice; if (request.type === 'LIMIT') throw Error('stopPrice: Must set "type" to one of the following: STOP_LOSS, STOP_LOSS_LIMIT, TAKE_PROFIT, TAKE_PROFIT_LIMIT'); } - return await this.privateSpotRequest(endpoint, this.extend(request, params), 'POST'); + return await this.privateSapiRequest(endpoint, this.extend(request, params), 'POST'); } // Futures internal functions @@ -4820,7 +4828,7 @@ export default class Binance { * @return {undefined} */ async mgCancel(symbol: string, orderid: number | string, isIsolated = 'FALSE'): Promise { - return await this.privateSpotRequest('v1/margin/order', { symbol: symbol, orderId: orderid, isIsolated }, 'DELETE'); + return await this.privateSapiRequest('v1/margin/order', { symbol: symbol, orderId: orderid, isIsolated }, 'DELETE'); } /** @@ -4831,7 +4839,7 @@ export default class Binance { */ async mgAllOrders(symbol: string, params: Dict = {}): Promise { const parameters = Object.assign({ symbol: symbol }, params); - return await this.privateSpotRequest('v1/margin/allOrders', parameters); + return await this.privateSapiRequest('v1/margin/allOrders', parameters); } /** @@ -4843,7 +4851,7 @@ export default class Binance { */ async mgOrderStatus(symbol: string, orderid: number | string, flags = {}): Promise { const parameters = Object.assign({ symbol: symbol, orderId: orderid }, flags); - return await this.privateSpotRequest('v1/margin/order', parameters); + return await this.privateSapiRequest('v1/margin/order', parameters); } /** @@ -4853,7 +4861,7 @@ export default class Binance { */ async mgOpenOrders(symbol?: string, params: Dict = {}): Promise { if (symbol) params.symbol = symbol; - return await this.privateSpotRequest('v1/margin/openOrders', params); + return await this.privateSapiRequest('v1/margin/openOrders', params); } /** @@ -4874,7 +4882,7 @@ export default class Binance { // }, 'DELETE'); // } // }); // to do check this - return await this.privateSpotRequest('v1/margin/openOrders', this.extend({ symbol: symbol }, params), 'DELETE'); + return await this.privateSapiRequest('v1/margin/openOrders', this.extend({ symbol: symbol }, params), 'DELETE'); } /** @@ -4886,7 +4894,7 @@ export default class Binance { */ async mgTransferMainToMargin(asset: string, amount: number, params: Dict = {}) { params = this.extend({ asset: asset, amount: amount, type: 1 }, params); - return await this.privateSpotRequest('v1/margin/transfer', params, 'POST'); + return await this.privateSapiRequest('v1/margin/transfer', params, 'POST'); } /** @@ -4897,7 +4905,7 @@ export default class Binance { */ async mgTransferMarginToMain(asset: string, amount: number, params: Dict = {}) { const parameters = Object.assign({ asset: asset, amount: amount, type: 2 }); - return await this.privateSpotRequest('v1/margin/transfer', this.extend(parameters, params), 'POST'); + return await this.privateSapiRequest('v1/margin/transfer', this.extend(parameters, params), 'POST'); } // /** // * Universal Transfer requires API permissions enabled @@ -4918,7 +4926,7 @@ export default class Binance { */ async mgTrades(symbol: string, params: Dict = {}): Promise { const parameters = Object.assign({ symbol: symbol }, params); - return await this.privateSpotRequest('v1/margin/myTrades', parameters); + return await this.privateSapiRequest('v1/margin/myTrades', parameters); } /** @@ -4989,7 +4997,7 @@ export default class Binance { isIsolated, symbol } : {}; - return await this.privateSpotRequest('v1/margin/loan', this.extend({ ...parameters, ...isolatedObj }, params), 'POST'); + return await this.privateSapiRequest('v1/margin/loan', this.extend({ ...parameters, ...isolatedObj }, params), 'POST'); } /** @@ -5000,7 +5008,7 @@ export default class Binance { */ async mgQueryLoan(asset: string, options) { const parameters = Object.assign({ asset: asset }, options); - return await this.privateSpotRequest('v1/margin/loan', { ...parameters }, 'GET'); + return await this.privateSapiRequest('v1/margin/loan', { ...parameters }, 'GET'); } /** @@ -5011,7 +5019,7 @@ export default class Binance { */ async mgQueryRepay(asset: string, params: Dict = {}) { const parameters = Object.assign({ asset: asset }, params); - return await this.privateSpotRequest('v1/margin/repay', { ...parameters }, 'GET'); + return await this.privateSapiRequest('v1/margin/repay', { ...parameters }, 'GET'); } /** @@ -5029,7 +5037,7 @@ export default class Binance { isIsolated, symbol } : {}; - return await this.privateSpotRequest('v1/margin/repay', this.extend({ ...parameters, ...isolatedObj }, params), 'POST'); + return await this.privateSapiRequest('v1/margin/repay', this.extend({ ...parameters, ...isolatedObj }, params), 'POST'); } /** @@ -5040,7 +5048,7 @@ export default class Binance { async mgAccount(isIsolated = false, params: Dict = {}) { let endpoint = 'v1/margin'; endpoint += (isIsolated) ? '/isolated' : '' + '/account'; - return await this.privateSpotRequest(endpoint, params); + return await this.privateSapiRequest(endpoint, params); } /** * Get maximum borrow amount of an asset @@ -5049,7 +5057,7 @@ export default class Binance { */ async maxBorrowable(asset: string, params: Dict = {}) { params.asset = asset; - return await this.privateSpotRequest('v1/margin/maxBorrowable', params); + return await this.privateSapiRequest('v1/margin/maxBorrowable', params); } // // Futures WebSocket Functions: From c9b68dee6148d29790e3c6a9f77360595bd3d620 Mon Sep 17 00:00:00 2001 From: carlosmiei <43336371+carlosmiei@users.noreply.github.com> Date: Tue, 22 Apr 2025 11:49:02 +0100 Subject: [PATCH 3/3] revbert --- examples/class-example.mts | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/examples/class-example.mts b/examples/class-example.mts index 3e648c83..32fb831c 100644 --- a/examples/class-example.mts +++ b/examples/class-example.mts @@ -7,17 +7,9 @@ async function main() { APISECRET: 'x8gLihunpNq0d46F2q0TWJmeCDahX5LMXSlv3lSFNbMI3rujSOpTDKdhbcmPSf2i', test: true }); - - // const callback = (e) => console.log(e); - // const url = binance.futuresAggTradeStream('BTCUSDT', callback); - // console.log('WebSocket URL:', url); - // await new Promise(r => setTimeout(r, 5000)); - // console.log('after sleep') - // binance.futuresTerminate(url); - - binance.websockets.depthCache( [ 'BTCUSDT', 'ETHUSDT' ], ( a_symbol, a_depth ) => { - console.log( a_symbol, a_depth ); - } ); + const order = await binance.marketBuy("LTCUSDT", 0.1); + console.log( order ); + console.log( 'Hello, World!' ); } main() \ No newline at end of file