@riocrypto/common-server 1.0.2747 → 1.0.2749

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,6 +18,7 @@ function buildAxiosWithLogging() {
18
18
  "private",
19
19
  "credential",
20
20
  "passphrase",
21
+ "signature",
21
22
  "csrf",
22
23
  ];
23
24
  function maskHeaderValue(value) {
@@ -34,6 +35,25 @@ function buildAxiosWithLogging() {
34
35
  });
35
36
  return maskedHeaders;
36
37
  }
38
+ function maskUrl(url) {
39
+ if (!url)
40
+ return "unknown";
41
+ try {
42
+ const parsed = new URL(url);
43
+ const params = new URLSearchParams(parsed.search);
44
+ params.forEach((value, key) => {
45
+ const lower = key.toLowerCase();
46
+ if (sensitiveSubstrings.some((sub) => lower.includes(sub))) {
47
+ params.set(key, maskHeaderValue(value));
48
+ }
49
+ });
50
+ parsed.search = params.toString();
51
+ return parsed.toString();
52
+ }
53
+ catch (_a) {
54
+ return url;
55
+ }
56
+ }
37
57
  // Request Interceptor
38
58
  axiosWithLogging.interceptors.request.use((config) => {
39
59
  var _a;
@@ -43,7 +63,7 @@ function buildAxiosWithLogging() {
43
63
  // Mask sensitive headers in the configuration
44
64
  const maskedHeaders = maskHeaders(customConfig.headers);
45
65
  // Combine and log the full request configuration with masked headers
46
- const logMessage = `Request: method=${customConfig.method}, url=${customConfig.url}, headers=${JSON.stringify(maskedHeaders)}, data=${JSON.stringify(customConfig.data)}`;
66
+ const logMessage = `Request: method=${customConfig.method}, url=${maskUrl(customConfig.url)}, headers=${JSON.stringify(maskedHeaders)}, data=${JSON.stringify(customConfig.data)}`;
47
67
  ((_a = logger_1.default.getLogger()) === null || _a === void 0 ? void 0 : _a.info(logMessage)) || console.log(logMessage);
48
68
  }
49
69
  return config;
@@ -61,21 +81,21 @@ function buildAxiosWithLogging() {
61
81
  // Check if logging is disabled for this request
62
82
  if (!customConfig.skipLogging) {
63
83
  // Combine and log the full response details
64
- const logMessage = `Response: url=${customConfig.url}, status=${response.status}, data=${JSON.stringify(response.data)}`;
84
+ const logMessage = `Response: url=${maskUrl(customConfig.url)}, status=${response.status}, data=${JSON.stringify(response.data)}`;
65
85
  ((_a = logger_1.default.getLogger()) === null || _a === void 0 ? void 0 : _a.info(logMessage)) || console.log(logMessage);
66
86
  }
67
87
  return response;
68
88
  }, (error) => {
69
- var _a, _b;
89
+ var _a, _b, _c;
70
90
  // Combine and log the response error details without headers
71
- let logMessage = `Response Error: url=${error.config ? error.config.url : "unknown"}, message=${error.message}`;
91
+ let logMessage = `Response Error: url=${maskUrl((_a = error.config) === null || _a === void 0 ? void 0 : _a.url)}, message=${error.message}`;
72
92
  if (error.response) {
73
93
  logMessage += `, status=${error.response.status}, data=${JSON.stringify(error.response.data)}`;
74
94
  }
75
- ((_a = logger_1.default.getLogger()) === null || _a === void 0 ? void 0 : _a.info(logMessage)) || console.log(logMessage);
95
+ ((_b = logger_1.default.getLogger()) === null || _b === void 0 ? void 0 : _b.info(logMessage)) || console.log(logMessage);
76
96
  return Promise.reject({
77
97
  message: logMessage,
78
- status: (_b = error.response) === null || _b === void 0 ? void 0 : _b.status,
98
+ status: (_c = error.response) === null || _c === void 0 ? void 0 : _c.status,
79
99
  });
80
100
  });
81
101
  return axiosWithLogging;
@@ -0,0 +1,206 @@
1
+ import { Crypto } from "@riocrypto/common";
2
+ export interface BinanceBalance {
3
+ asset: string;
4
+ free: string;
5
+ locked: string;
6
+ }
7
+ export interface BinanceAccountInfo {
8
+ balances: BinanceBalance[];
9
+ }
10
+ export interface BinanceDepositAddress {
11
+ address: string;
12
+ coin: string;
13
+ tag: string;
14
+ url: string;
15
+ }
16
+ export interface BinanceOrderResponse {
17
+ symbol: string;
18
+ orderId: number;
19
+ orderListId: number;
20
+ clientOrderId: string;
21
+ transactTime?: number;
22
+ price: string;
23
+ origQty: string;
24
+ executedQty: string;
25
+ cummulativeQuoteQty: string;
26
+ status: string;
27
+ timeInForce: string;
28
+ type: string;
29
+ side: string;
30
+ fills?: Array<{
31
+ price: string;
32
+ qty: string;
33
+ commission: string;
34
+ commissionAsset: string;
35
+ }>;
36
+ }
37
+ export interface BinanceWithdrawHistoryItem {
38
+ id: string;
39
+ amount: string;
40
+ transactionFee: string;
41
+ coin: string;
42
+ status: number;
43
+ address: string;
44
+ txId: string;
45
+ applyTime: string;
46
+ network: string;
47
+ transferType: number;
48
+ withdrawOrderId?: string;
49
+ info: string;
50
+ confirmNo: number;
51
+ }
52
+ export interface BinanceDepositHistoryItem {
53
+ id: string;
54
+ amount: string;
55
+ coin: string;
56
+ network: string;
57
+ status: number;
58
+ address: string;
59
+ addressTag: string;
60
+ txId: string;
61
+ insertTime: number;
62
+ transferType: number;
63
+ confirmTimes: string;
64
+ unlockConfirm: number;
65
+ walletType: number;
66
+ }
67
+ export interface BinanceTradeItem {
68
+ id: number;
69
+ price: string;
70
+ qty: string;
71
+ quoteQty: string;
72
+ time: number;
73
+ isBuyerMaker: boolean;
74
+ isBestMatch: boolean;
75
+ }
76
+ export interface BinanceOrderBook {
77
+ lastUpdateId: number;
78
+ bids: [string, string][];
79
+ asks: [string, string][];
80
+ }
81
+ export interface BinanceExchangeInfo {
82
+ timezone: string;
83
+ serverTime: number;
84
+ symbols: any[];
85
+ }
86
+ export interface BinanceFiatWithdrawResponse {
87
+ code: string;
88
+ message: string;
89
+ data: {
90
+ orderId: string;
91
+ };
92
+ }
93
+ export interface BinanceFiatOrderDetail {
94
+ code: string;
95
+ message: string;
96
+ data: {
97
+ orderId: string;
98
+ orderStatus: string;
99
+ amount: string;
100
+ fee: string;
101
+ fiatCurrency: string;
102
+ errorCode: string;
103
+ errorMessage: string;
104
+ ext: Record<string, any>;
105
+ };
106
+ }
107
+ export declare enum BinanceOrderStatus {
108
+ NEW = "NEW",
109
+ PARTIALLY_FILLED = "PARTIALLY_FILLED",
110
+ FILLED = "FILLED",
111
+ CANCELED = "CANCELED",
112
+ PENDING_CANCEL = "PENDING_CANCEL",
113
+ REJECTED = "REJECTED",
114
+ EXPIRED = "EXPIRED",
115
+ EXPIRED_IN_MATCH = "EXPIRED_IN_MATCH"
116
+ }
117
+ declare class BinanceClient {
118
+ private apiKey;
119
+ private apiSecret;
120
+ private baseUrl;
121
+ private axiosClient;
122
+ constructor(apiKey: string, apiSecret: string, env: "Production" | "Staging");
123
+ private buildQueryString;
124
+ private sign;
125
+ private signedGet;
126
+ private signedPost;
127
+ private signedPostWithBody;
128
+ private signedDelete;
129
+ private publicGet;
130
+ getAccountInformation(skipLogging?: boolean): Promise<BinanceAccountInfo>;
131
+ getBalance(asset: string): Promise<number>;
132
+ getAllBalances(assets?: string[]): Promise<Record<string, number>>;
133
+ newOrder(params: {
134
+ symbol: string;
135
+ side: string;
136
+ type: string;
137
+ timeInForce?: string;
138
+ quantity?: number;
139
+ quoteOrderQty?: number;
140
+ price?: string | number;
141
+ }): Promise<BinanceOrderResponse>;
142
+ getOrder(symbol: string, orderId: number): Promise<BinanceOrderResponse>;
143
+ cancelOrder(symbol: string, orderId: number): Promise<any>;
144
+ getOpenOrders(symbol: string): Promise<BinanceOrderResponse[]>;
145
+ getAllOrders(symbol: string): Promise<BinanceOrderResponse[]>;
146
+ getMyTrades(symbol: string, orderId?: number): Promise<any[]>;
147
+ getRecentTrades(symbol: string, limit?: number): Promise<BinanceTradeItem[]>;
148
+ getExchangeInfo(): Promise<BinanceExchangeInfo>;
149
+ getOrderBook(symbol: string, limit?: number): Promise<BinanceOrderBook>;
150
+ getDepositAddress(coin: string, network?: string): Promise<BinanceDepositAddress>;
151
+ withdraw(params: {
152
+ coin: string;
153
+ address: string;
154
+ amount: number;
155
+ network?: string;
156
+ withdrawOrderId?: string;
157
+ addressTag?: string;
158
+ }): Promise<{
159
+ id: string;
160
+ }>;
161
+ getWithdrawHistory(params?: {
162
+ coin?: string;
163
+ withdrawOrderId?: string;
164
+ status?: number;
165
+ offset?: number;
166
+ limit?: number;
167
+ startTime?: number;
168
+ endTime?: number;
169
+ }): Promise<BinanceWithdrawHistoryItem[]>;
170
+ getDepositHistory(params?: {
171
+ coin?: string;
172
+ status?: number;
173
+ startTime?: number;
174
+ endTime?: number;
175
+ offset?: number;
176
+ limit?: number;
177
+ txId?: string;
178
+ }): Promise<BinanceDepositHistoryItem[]>;
179
+ withdrawFiat(params: {
180
+ currency: string;
181
+ apiPaymentMethod: string;
182
+ amount: number;
183
+ accountInfo: {
184
+ accountNumber: string;
185
+ [key: string]: any;
186
+ };
187
+ ext?: Record<string, any>;
188
+ }): Promise<BinanceFiatWithdrawResponse>;
189
+ getFiatOrderDetail(orderNo: string): Promise<BinanceFiatOrderDetail>;
190
+ private convertCryptoToBinanceDescriptor;
191
+ getDepositAddressForCrypto(cryptoAsset: Crypto): Promise<{
192
+ address: string;
193
+ memo?: string;
194
+ }>;
195
+ withdrawCrypto(cryptoAsset: Crypto, amount: number, address: string, memo?: string): Promise<string>;
196
+ withdrawMXN(amount: number, clabe: string): Promise<string>;
197
+ getWithdrawalHistoryByOrderId(withdrawalId: string): Promise<BinanceWithdrawHistoryItem[]>;
198
+ getDepositByTxHash(hash: string): Promise<BinanceDepositHistoryItem | undefined>;
199
+ createMarketOrder(symbol: string, amount: number, side: "BUY" | "SELL"): Promise<BinanceOrderResponse>;
200
+ createLimitOrder(symbol: string, side: "BUY" | "SELL", quantity: number, price: string | number, timeInForce?: string): Promise<BinanceOrderResponse>;
201
+ getLatestTradedPrice(symbol: string): Promise<number>;
202
+ getLowestAsk(symbol: string, limit?: number): Promise<number>;
203
+ getHighestBid(symbol: string, limit?: number): Promise<number>;
204
+ }
205
+ export declare const buildBinanceClient: () => Promise<BinanceClient>;
206
+ export {};
@@ -0,0 +1,398 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.buildBinanceClient = exports.BinanceOrderStatus = void 0;
16
+ const crypto_1 = __importDefault(require("crypto"));
17
+ const common_1 = require("@riocrypto/common");
18
+ const axios_with_logging_1 = require("./axios-with-logging");
19
+ const secret_manager_client_1 = require("./secret-manager-client");
20
+ const mongoose_1 = __importDefault(require("mongoose"));
21
+ var BinanceOrderStatus;
22
+ (function (BinanceOrderStatus) {
23
+ BinanceOrderStatus["NEW"] = "NEW";
24
+ BinanceOrderStatus["PARTIALLY_FILLED"] = "PARTIALLY_FILLED";
25
+ BinanceOrderStatus["FILLED"] = "FILLED";
26
+ BinanceOrderStatus["CANCELED"] = "CANCELED";
27
+ BinanceOrderStatus["PENDING_CANCEL"] = "PENDING_CANCEL";
28
+ BinanceOrderStatus["REJECTED"] = "REJECTED";
29
+ BinanceOrderStatus["EXPIRED"] = "EXPIRED";
30
+ BinanceOrderStatus["EXPIRED_IN_MATCH"] = "EXPIRED_IN_MATCH";
31
+ })(BinanceOrderStatus = exports.BinanceOrderStatus || (exports.BinanceOrderStatus = {}));
32
+ class BinanceClient {
33
+ constructor(apiKey, apiSecret, env) {
34
+ this.apiKey = apiKey;
35
+ this.apiSecret = apiSecret;
36
+ this.baseUrl =
37
+ env === "Production"
38
+ ? "https://api.binance.com"
39
+ : "https://testnet.binance.vision";
40
+ this.axiosClient = (0, axios_with_logging_1.buildAxiosWithLogging)();
41
+ }
42
+ buildQueryString(params) {
43
+ const filtered = {};
44
+ for (const [key, value] of Object.entries(params)) {
45
+ if (value !== undefined && value !== null) {
46
+ filtered[key] = String(value);
47
+ }
48
+ }
49
+ return new URLSearchParams(filtered).toString();
50
+ }
51
+ sign(queryString) {
52
+ return crypto_1.default
53
+ .createHmac("sha256", this.apiSecret)
54
+ .update(queryString)
55
+ .digest("hex");
56
+ }
57
+ signedGet(path, params = {}, skipLogging = false) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ const allParams = Object.assign(Object.assign({}, params), { timestamp: Date.now() });
60
+ const queryString = this.buildQueryString(allParams);
61
+ const signature = this.sign(queryString);
62
+ const response = yield this.axiosClient.get(`${this.baseUrl}${path}?${queryString}&signature=${signature}`, { headers: { "X-MBX-APIKEY": this.apiKey }, skipLogging });
63
+ return response.data;
64
+ });
65
+ }
66
+ signedPost(path, params = {}) {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const allParams = Object.assign(Object.assign({}, params), { timestamp: Date.now() });
69
+ const queryString = this.buildQueryString(allParams);
70
+ const signature = this.sign(queryString);
71
+ const response = yield this.axiosClient.post(`${this.baseUrl}${path}?${queryString}&signature=${signature}`, null, { headers: { "X-MBX-APIKEY": this.apiKey } });
72
+ return response.data;
73
+ });
74
+ }
75
+ signedPostWithBody(path, body, queryParams = {}) {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ const allQueryParams = Object.assign(Object.assign({}, queryParams), { timestamp: Date.now() });
78
+ const queryString = this.buildQueryString(allQueryParams);
79
+ const bodyString = JSON.stringify(body);
80
+ const signature = this.sign(queryString + bodyString);
81
+ const response = yield this.axiosClient.post(`${this.baseUrl}${path}?${queryString}&signature=${signature}`, body, {
82
+ headers: {
83
+ "X-MBX-APIKEY": this.apiKey,
84
+ "Content-Type": "application/json",
85
+ },
86
+ });
87
+ return response.data;
88
+ });
89
+ }
90
+ signedDelete(path, params = {}) {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ const allParams = Object.assign(Object.assign({}, params), { timestamp: Date.now() });
93
+ const queryString = this.buildQueryString(allParams);
94
+ const signature = this.sign(queryString);
95
+ const response = yield this.axiosClient.delete(`${this.baseUrl}${path}?${queryString}&signature=${signature}`, { headers: { "X-MBX-APIKEY": this.apiKey } });
96
+ return response.data;
97
+ });
98
+ }
99
+ publicGet(path, params = {}) {
100
+ return __awaiter(this, void 0, void 0, function* () {
101
+ const filtered = {};
102
+ for (const [key, value] of Object.entries(params)) {
103
+ if (value !== undefined && value !== null) {
104
+ filtered[key] = String(value);
105
+ }
106
+ }
107
+ const response = yield this.axiosClient.get(`${this.baseUrl}${path}`, {
108
+ params: filtered,
109
+ headers: { "X-MBX-APIKEY": this.apiKey },
110
+ });
111
+ return response.data;
112
+ });
113
+ }
114
+ // Account
115
+ getAccountInformation(skipLogging = false) {
116
+ return __awaiter(this, void 0, void 0, function* () {
117
+ return this.signedGet("/api/v3/account", {}, skipLogging);
118
+ });
119
+ }
120
+ getBalance(asset) {
121
+ return __awaiter(this, void 0, void 0, function* () {
122
+ const info = yield this.getAccountInformation();
123
+ const balance = info.balances.find((b) => b.asset === asset);
124
+ return (balance === null || balance === void 0 ? void 0 : balance.free) ? parseFloat(balance.free) : 0;
125
+ });
126
+ }
127
+ getAllBalances(assets) {
128
+ return __awaiter(this, void 0, void 0, function* () {
129
+ const info = yield this.getAccountInformation(true);
130
+ const result = {};
131
+ if (assets) {
132
+ const assetSet = new Set(assets);
133
+ info.balances
134
+ .filter((b) => assetSet.has(b.asset))
135
+ .forEach((b) => {
136
+ result[b.asset] = parseFloat(b.free) || 0;
137
+ });
138
+ }
139
+ else {
140
+ info.balances.forEach((b) => {
141
+ result[b.asset] = parseFloat(b.free) || 0;
142
+ });
143
+ }
144
+ console.log("Binance balances:", JSON.stringify(result));
145
+ return result;
146
+ });
147
+ }
148
+ // Trading
149
+ newOrder(params) {
150
+ return __awaiter(this, void 0, void 0, function* () {
151
+ return this.signedPost("/api/v3/order", params);
152
+ });
153
+ }
154
+ getOrder(symbol, orderId) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ return this.signedGet("/api/v3/order", { symbol, orderId });
157
+ });
158
+ }
159
+ cancelOrder(symbol, orderId) {
160
+ return __awaiter(this, void 0, void 0, function* () {
161
+ return this.signedDelete("/api/v3/order", { symbol, orderId });
162
+ });
163
+ }
164
+ getOpenOrders(symbol) {
165
+ return __awaiter(this, void 0, void 0, function* () {
166
+ return this.signedGet("/api/v3/openOrders", { symbol });
167
+ });
168
+ }
169
+ getAllOrders(symbol) {
170
+ return __awaiter(this, void 0, void 0, function* () {
171
+ return this.signedGet("/api/v3/allOrders", { symbol });
172
+ });
173
+ }
174
+ getMyTrades(symbol, orderId) {
175
+ return __awaiter(this, void 0, void 0, function* () {
176
+ return this.signedGet("/api/v3/myTrades", { symbol, orderId });
177
+ });
178
+ }
179
+ // Market data
180
+ getRecentTrades(symbol, limit) {
181
+ return __awaiter(this, void 0, void 0, function* () {
182
+ return this.publicGet("/api/v3/trades", { symbol, limit });
183
+ });
184
+ }
185
+ getExchangeInfo() {
186
+ return __awaiter(this, void 0, void 0, function* () {
187
+ return this.publicGet("/api/v3/exchangeInfo");
188
+ });
189
+ }
190
+ getOrderBook(symbol, limit) {
191
+ return __awaiter(this, void 0, void 0, function* () {
192
+ return this.publicGet("/api/v3/depth", { symbol, limit });
193
+ });
194
+ }
195
+ // Wallet
196
+ getDepositAddress(coin, network) {
197
+ return __awaiter(this, void 0, void 0, function* () {
198
+ return this.signedGet("/sapi/v1/capital/deposit/address", {
199
+ coin,
200
+ network,
201
+ });
202
+ });
203
+ }
204
+ withdraw(params) {
205
+ return __awaiter(this, void 0, void 0, function* () {
206
+ return this.signedPost("/sapi/v1/capital/withdraw/apply", params);
207
+ });
208
+ }
209
+ getWithdrawHistory(params) {
210
+ return __awaiter(this, void 0, void 0, function* () {
211
+ return this.signedGet("/sapi/v1/capital/withdraw/history", params || {});
212
+ });
213
+ }
214
+ getDepositHistory(params) {
215
+ return __awaiter(this, void 0, void 0, function* () {
216
+ return this.signedGet("/sapi/v1/capital/deposit/hisrec", params || {});
217
+ });
218
+ }
219
+ // Fiat
220
+ withdrawFiat(params) {
221
+ return __awaiter(this, void 0, void 0, function* () {
222
+ return this.signedPostWithBody("/sapi/v2/fiat/withdraw", params);
223
+ });
224
+ }
225
+ getFiatOrderDetail(orderNo) {
226
+ return __awaiter(this, void 0, void 0, function* () {
227
+ return this.signedGet("/sapi/v1/fiat/get-order-detail", { orderNo });
228
+ });
229
+ }
230
+ // Convenience methods
231
+ convertCryptoToBinanceDescriptor(cryptoAsset) {
232
+ switch (cryptoAsset) {
233
+ case common_1.Crypto.USDC:
234
+ return { coin: "USDC", network: "ETH" };
235
+ case common_1.Crypto.USDCPolygon:
236
+ return { coin: "USDC", network: "MATIC" };
237
+ case common_1.Crypto.USDCSolana:
238
+ return { coin: "USDC", network: "SOL" };
239
+ case common_1.Crypto.USDCStellar:
240
+ return { coin: "USDC", network: "XLM" };
241
+ case common_1.Crypto.USDCBase:
242
+ return { coin: "USDC", network: "BASE" };
243
+ case common_1.Crypto.USDTEthereum:
244
+ return { coin: "USDT", network: "ETH" };
245
+ case common_1.Crypto.USDTPolygon:
246
+ return { coin: "USDT", network: "MATIC" };
247
+ case common_1.Crypto.USDTTron:
248
+ return { coin: "USDT", network: "TRX" };
249
+ case common_1.Crypto.ETH:
250
+ return { coin: "ETH", network: "ETH" };
251
+ case common_1.Crypto.TRON:
252
+ return { coin: "TRX", network: "TRX" };
253
+ case common_1.Crypto.SOL:
254
+ return { coin: "SOL", network: "SOL" };
255
+ default:
256
+ return null;
257
+ }
258
+ }
259
+ getDepositAddressForCrypto(cryptoAsset) {
260
+ return __awaiter(this, void 0, void 0, function* () {
261
+ const descriptor = this.convertCryptoToBinanceDescriptor(cryptoAsset);
262
+ if (!descriptor) {
263
+ throw new Error("Unsupported crypto");
264
+ }
265
+ const response = yield this.getDepositAddress(descriptor.coin, descriptor.network);
266
+ return { address: response.address, memo: response.tag };
267
+ });
268
+ }
269
+ withdrawCrypto(cryptoAsset, amount, address, memo) {
270
+ return __awaiter(this, void 0, void 0, function* () {
271
+ if ([common_1.RioEnv.Sandbox, common_1.RioEnv.Local, common_1.RioEnv.Test].includes(process.env.RIO_ENV)) {
272
+ throw new Error("Binance withdraw not allowed in sandbox");
273
+ }
274
+ const descriptor = this.convertCryptoToBinanceDescriptor(cryptoAsset);
275
+ if (!descriptor) {
276
+ throw new Error("Unsupported crypto");
277
+ }
278
+ console.log("Withdrawing from Binance");
279
+ const withdrawOrderId = new mongoose_1.default.Types.ObjectId().toString();
280
+ console.log("Withdraw order id: ", withdrawOrderId);
281
+ try {
282
+ const response = yield this.withdraw({
283
+ coin: descriptor.coin,
284
+ address,
285
+ amount,
286
+ withdrawOrderId,
287
+ network: descriptor.network,
288
+ addressTag: memo,
289
+ });
290
+ console.log("Response: ", response);
291
+ return withdrawOrderId;
292
+ }
293
+ catch (error) {
294
+ console.log("Error withdrawing from Binance");
295
+ console.log("Error: ", error);
296
+ throw error;
297
+ }
298
+ });
299
+ }
300
+ withdrawMXN(amount, clabe) {
301
+ return __awaiter(this, void 0, void 0, function* () {
302
+ if ([common_1.RioEnv.Sandbox, common_1.RioEnv.Local, common_1.RioEnv.Test].includes(process.env.RIO_ENV)) {
303
+ throw new Error("Binance fiat withdraw not allowed in sandbox");
304
+ }
305
+ const response = yield this.withdrawFiat({
306
+ currency: "MXN",
307
+ apiPaymentMethod: "bank_transfer",
308
+ amount,
309
+ accountInfo: { accountNumber: clabe },
310
+ });
311
+ if (response.code !== "000000") {
312
+ throw new Error(`Fiat withdraw failed: ${response.message}`);
313
+ }
314
+ return response.data.orderId;
315
+ });
316
+ }
317
+ getWithdrawalHistoryByOrderId(withdrawalId) {
318
+ return __awaiter(this, void 0, void 0, function* () {
319
+ console.log("Withdrawal id: ", withdrawalId);
320
+ return this.getWithdrawHistory({ withdrawOrderId: withdrawalId });
321
+ });
322
+ }
323
+ getDepositByTxHash(hash) {
324
+ return __awaiter(this, void 0, void 0, function* () {
325
+ const response = yield this.getDepositHistory({ txId: hash });
326
+ return response.find((deposit) => deposit.txId === hash);
327
+ });
328
+ }
329
+ createMarketOrder(symbol, amount, side) {
330
+ return __awaiter(this, void 0, void 0, function* () {
331
+ return this.newOrder({
332
+ symbol,
333
+ side,
334
+ type: "MARKET",
335
+ quantity: side === "SELL" ? amount : undefined,
336
+ quoteOrderQty: side === "BUY" ? amount : undefined,
337
+ });
338
+ });
339
+ }
340
+ createLimitOrder(symbol, side, quantity, price, timeInForce = "GTC") {
341
+ return __awaiter(this, void 0, void 0, function* () {
342
+ return this.newOrder({
343
+ symbol,
344
+ side,
345
+ type: "LIMIT",
346
+ timeInForce,
347
+ quantity,
348
+ price,
349
+ });
350
+ });
351
+ }
352
+ getLatestTradedPrice(symbol) {
353
+ return __awaiter(this, void 0, void 0, function* () {
354
+ const trades = yield this.getRecentTrades(symbol);
355
+ return Number(trades[0].price);
356
+ });
357
+ }
358
+ getLowestAsk(symbol, limit = 5) {
359
+ var _a, _b;
360
+ return __awaiter(this, void 0, void 0, function* () {
361
+ const orderBook = yield this.getOrderBook(symbol, limit);
362
+ const lowestAsk = (_b = (_a = orderBook.asks) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b[0];
363
+ if (!lowestAsk) {
364
+ throw new Error("No lowest ask found");
365
+ }
366
+ return parseFloat(lowestAsk);
367
+ });
368
+ }
369
+ getHighestBid(symbol, limit = 5) {
370
+ var _a, _b;
371
+ return __awaiter(this, void 0, void 0, function* () {
372
+ const orderBook = yield this.getOrderBook(symbol, limit);
373
+ const highestBid = (_b = (_a = orderBook.bids) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b[0];
374
+ if (!highestBid) {
375
+ throw new Error("No highest bid found");
376
+ }
377
+ return parseFloat(highestBid);
378
+ });
379
+ }
380
+ }
381
+ const buildBinanceClient = () => __awaiter(void 0, void 0, void 0, function* () {
382
+ const BINANCE_API_KEY = yield secret_manager_client_1.secretManagerClient.getSecretValue("BINANCE_API_KEY");
383
+ if (!BINANCE_API_KEY) {
384
+ throw new common_1.SecretManagerError();
385
+ }
386
+ const BINANCE_API_SECRET = yield secret_manager_client_1.secretManagerClient.getSecretValue("BINANCE_API_SECRET");
387
+ if (!BINANCE_API_SECRET) {
388
+ throw new common_1.SecretManagerError();
389
+ }
390
+ const env = [
391
+ common_1.RioEnv.Production,
392
+ common_1.RioEnv.Development,
393
+ ].includes(process.env.RIO_ENV)
394
+ ? "Production"
395
+ : "Staging";
396
+ return new BinanceClient(BINANCE_API_KEY, BINANCE_API_SECRET, env);
397
+ });
398
+ exports.buildBinanceClient = buildBinanceClient;
package/build/index.d.ts CHANGED
@@ -137,6 +137,7 @@ export * from "./clients/bitso-client";
137
137
  export * from "./clients/circle-client";
138
138
  export * from "./clients/coincover-client";
139
139
  export * from "./clients/google-sheets-api-client";
140
+ export * from "./clients/binance-client";
140
141
  export * from "./helpers/get-user-helper";
141
142
  export * from "./helpers/get-processor-fees";
142
143
  export * from "./helpers/get-network-fees";
package/build/index.js CHANGED
@@ -153,6 +153,7 @@ __exportStar(require("./clients/bitso-client"), exports);
153
153
  __exportStar(require("./clients/circle-client"), exports);
154
154
  __exportStar(require("./clients/coincover-client"), exports);
155
155
  __exportStar(require("./clients/google-sheets-api-client"), exports);
156
+ __exportStar(require("./clients/binance-client"), exports);
156
157
  __exportStar(require("./helpers/get-user-helper"), exports);
157
158
  __exportStar(require("./helpers/get-processor-fees"), exports);
158
159
  __exportStar(require("./helpers/get-network-fees"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@riocrypto/common-server",
3
- "version": "1.0.2747",
3
+ "version": "1.0.2749",
4
4
  "description": "",
5
5
  "main": "./build/index.js",
6
6
  "types": "./build/index.d.ts",
@@ -28,7 +28,7 @@
28
28
  "@google-cloud/secret-manager": "^5.3.0",
29
29
  "@google-cloud/storage": "^6.9.5",
30
30
  "@hyperdx/node-opentelemetry": "^0.7.0",
31
- "@riocrypto/common": "^1.0.2539",
31
+ "@riocrypto/common": "^1.0.2541",
32
32
  "@slack/web-api": "^7.9.2",
33
33
  "@types/express": "^4.17.13",
34
34
  "axios": "^1.7.4",