Skip to content

Commit 6c6f70a

Browse files
authored
Merge pull request #43 from QuantForgeOrg/dev
Binance provider hotfix for USA users
2 parents dca7d55 + 73cdf8a commit 6c6f70a

File tree

3 files changed

+56
-4
lines changed

3 files changed

+56
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log
22

3+
## [0.7.2] - 2025-12-22 - Pine Script Parser & Build System Modernization
4+
5+
- Hotfix : Binance provider failing for USA users, implemented a fallback logic to use the default binance url and fallback to US local url if the first one fails.
6+
37
## [0.7.0] - 2025-12-20 - Pine Script Parser & Build System Modernization
48

59
### Added

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "pinets",
3-
"version": "0.7.1",
3+
"version": "0.7.2",
44
"description": "",
55
"main": "dist/pinets.min.cjs",
66
"module": "dist/pinets.min.es.js",

src/marketData/Binance/BinanceProvider.class.ts

Lines changed: 51 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// SPDX-License-Identifier: AGPL-3.0-only
22

3-
const BINANCE_API_URL = 'https://api.binance.com/api/v3'; //'https://testnet.binance.vision/api/v3';
3+
const BINANCE_API_URL_DEFAULT = 'https://api.binance.com/api/v3';
4+
const BINANCE_API_URL_US = 'https://api.binance.us/api/v3';
5+
46
const timeframe_to_binance = {
57
'1': '1m', // 1 minute
68
'3': '3m', // 3 minutes
@@ -84,11 +86,55 @@ class CacheManager<T> {
8486

8587
export class BinanceProvider implements IProvider {
8688
private cacheManager: CacheManager<any[]>;
89+
private activeApiUrl: string | null = null; // Persist the working endpoint
8790

8891
constructor() {
8992
this.cacheManager = new CacheManager(5 * 60 * 1000); // 5 minutes cache duration
9093
}
9194

95+
/**
96+
* Resolves the working Binance API endpoint.
97+
* Tries default first, then falls back to US endpoint.
98+
* Caches the working endpoint for future calls.
99+
*/
100+
private async getBaseUrl(): Promise<string> {
101+
if (this.activeApiUrl) {
102+
return this.activeApiUrl;
103+
}
104+
105+
// Try default endpoint
106+
try {
107+
const controller = new AbortController();
108+
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5s timeout
109+
const response = await fetch(`${BINANCE_API_URL_DEFAULT}/ping`, { signal: controller.signal });
110+
clearTimeout(timeoutId);
111+
if (response.ok) {
112+
this.activeApiUrl = BINANCE_API_URL_DEFAULT;
113+
return this.activeApiUrl;
114+
}
115+
} catch (e) {
116+
// Default failed, try US endpoint
117+
// console.warn('Binance default API unreachable, trying US endpoint...');
118+
}
119+
120+
// Try US endpoint
121+
try {
122+
const controller = new AbortController();
123+
const timeoutId = setTimeout(() => controller.abort(), 5000);
124+
const response = await fetch(`${BINANCE_API_URL_US}/ping`, { signal: controller.signal });
125+
clearTimeout(timeoutId);
126+
if (response.ok) {
127+
this.activeApiUrl = BINANCE_API_URL_US;
128+
return this.activeApiUrl;
129+
}
130+
} catch (e) {
131+
// Both failed
132+
}
133+
134+
// Fallback to default if check fails entirely (let actual request fail)
135+
return BINANCE_API_URL_DEFAULT;
136+
}
137+
92138
async getMarketDataInterval(tickerId: string, timeframe: string, sDate: number, eDate: number): Promise<any> {
93139
try {
94140
const interval = timeframe_to_binance[timeframe.toUpperCase()];
@@ -184,7 +230,8 @@ export class BinanceProvider implements IProvider {
184230
}
185231

186232
// Single request for <= 1000 candles
187-
let url = `${BINANCE_API_URL}/klines?symbol=${tickerId}&interval=${interval}`;
233+
const baseUrl = await this.getBaseUrl();
234+
let url = `${baseUrl}/klines?symbol=${tickerId}&interval=${interval}`;
188235

189236
//example https://api.binance.com/api/v3/klines?symbol=BTCUSDT&interval=1m&limit=1000
190237
if (limit) {
@@ -276,7 +323,8 @@ export class BinanceProvider implements IProvider {
276323
// We keep it EXACTLY as is for ticker field (Pine Script includes .P)
277324

278325
let marketType: 'crypto' | 'futures' = 'crypto';
279-
let apiUrl = BINANCE_API_URL; // Default to spot API
326+
const baseUrl = await this.getBaseUrl();
327+
let apiUrl = baseUrl; // Default to resolved spot API
280328
let apiSymbol = tickerId; // Symbol for API call
281329
let contractType = '';
282330

0 commit comments

Comments
 (0)