ton-provider-system 0.1.10 → 0.1.11
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.
- package/dist/index.cjs +108 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +26 -2
- package/dist/index.d.ts +26 -2
- package/dist/index.js +108 -19
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/rpc.json +4 -2
package/dist/index.cjs
CHANGED
|
@@ -217,7 +217,8 @@ function resolveProvider(id, config) {
|
|
|
217
217
|
apiKey,
|
|
218
218
|
rps: config.rps,
|
|
219
219
|
priority: config.priority,
|
|
220
|
-
isDynamic: config.isDynamic || false
|
|
220
|
+
isDynamic: config.isDynamic || false,
|
|
221
|
+
browserCompatible: config.browserCompatible !== void 0 ? config.browserCompatible : true
|
|
221
222
|
};
|
|
222
223
|
}
|
|
223
224
|
function resolveAllProviders(config) {
|
|
@@ -776,7 +777,8 @@ var HealthChecker = class {
|
|
|
776
777
|
latencyMs: null,
|
|
777
778
|
seqno: null,
|
|
778
779
|
blocksBehind: 0,
|
|
779
|
-
lastTested: null
|
|
780
|
+
lastTested: null,
|
|
781
|
+
browserCompatible: provider.browserCompatible
|
|
780
782
|
};
|
|
781
783
|
this.results.set(key, testingResult);
|
|
782
784
|
try {
|
|
@@ -836,7 +838,8 @@ var HealthChecker = class {
|
|
|
836
838
|
seqno,
|
|
837
839
|
blocksBehind,
|
|
838
840
|
lastTested: /* @__PURE__ */ new Date(),
|
|
839
|
-
cachedEndpoint: normalizedEndpoint
|
|
841
|
+
cachedEndpoint: normalizedEndpoint,
|
|
842
|
+
browserCompatible: provider.browserCompatible
|
|
840
843
|
};
|
|
841
844
|
this.results.set(key, result);
|
|
842
845
|
this.logger.debug(
|
|
@@ -847,6 +850,7 @@ var HealthChecker = class {
|
|
|
847
850
|
const endTime = performance.now();
|
|
848
851
|
const latencyMs = Math.round(endTime - startTime);
|
|
849
852
|
const errorMsg = error.message || String(error) || "Unknown error";
|
|
853
|
+
const isCorsError = this.isCorsError(error, errorMsg);
|
|
850
854
|
const is429 = errorMsg.includes("429") || errorMsg.toLowerCase().includes("rate limit");
|
|
851
855
|
const is404 = errorMsg.includes("404") || errorMsg.toLowerCase().includes("not found");
|
|
852
856
|
const is503 = errorMsg.includes("503") || errorMsg.toLowerCase().includes("service unavailable");
|
|
@@ -861,6 +865,7 @@ var HealthChecker = class {
|
|
|
861
865
|
} else if (isTimeout) {
|
|
862
866
|
status = "offline";
|
|
863
867
|
}
|
|
868
|
+
const browserCompatible = isCorsError ? false : provider.browserCompatible;
|
|
864
869
|
const result = {
|
|
865
870
|
id: provider.id,
|
|
866
871
|
network: provider.network,
|
|
@@ -870,7 +875,8 @@ var HealthChecker = class {
|
|
|
870
875
|
seqno: null,
|
|
871
876
|
blocksBehind: 0,
|
|
872
877
|
lastTested: /* @__PURE__ */ new Date(),
|
|
873
|
-
error: errorMsg
|
|
878
|
+
error: errorMsg,
|
|
879
|
+
browserCompatible
|
|
874
880
|
};
|
|
875
881
|
this.results.set(key, result);
|
|
876
882
|
this.logger.warn(`Provider ${provider.id} health check failed: ${result.error}`);
|
|
@@ -956,7 +962,8 @@ var HealthChecker = class {
|
|
|
956
962
|
// Degraded providers are still usable, just slower/rate-limited
|
|
957
963
|
status: "degraded",
|
|
958
964
|
error: error || "Marked as degraded",
|
|
959
|
-
lastTested: /* @__PURE__ */ new Date()
|
|
965
|
+
lastTested: /* @__PURE__ */ new Date(),
|
|
966
|
+
browserCompatible: existing.browserCompatible ?? true
|
|
960
967
|
} : {
|
|
961
968
|
id: providerId,
|
|
962
969
|
network,
|
|
@@ -967,7 +974,9 @@ var HealthChecker = class {
|
|
|
967
974
|
seqno: null,
|
|
968
975
|
blocksBehind: 0,
|
|
969
976
|
lastTested: /* @__PURE__ */ new Date(),
|
|
970
|
-
error: error || "Marked as degraded"
|
|
977
|
+
error: error || "Marked as degraded",
|
|
978
|
+
browserCompatible: true
|
|
979
|
+
// Default to compatible if unknown
|
|
971
980
|
};
|
|
972
981
|
this.results.set(key, result);
|
|
973
982
|
}
|
|
@@ -983,7 +992,8 @@ var HealthChecker = class {
|
|
|
983
992
|
success: false,
|
|
984
993
|
// Ensure success is false for offline providers
|
|
985
994
|
error: error || "Marked as offline",
|
|
986
|
-
lastTested: /* @__PURE__ */ new Date()
|
|
995
|
+
lastTested: /* @__PURE__ */ new Date(),
|
|
996
|
+
browserCompatible: existing.browserCompatible ?? true
|
|
987
997
|
} : {
|
|
988
998
|
id: providerId,
|
|
989
999
|
network,
|
|
@@ -993,7 +1003,9 @@ var HealthChecker = class {
|
|
|
993
1003
|
seqno: null,
|
|
994
1004
|
blocksBehind: 0,
|
|
995
1005
|
lastTested: /* @__PURE__ */ new Date(),
|
|
996
|
-
error: error || "Marked as offline"
|
|
1006
|
+
error: error || "Marked as offline",
|
|
1007
|
+
browserCompatible: true
|
|
1008
|
+
// Default to compatible if unknown
|
|
997
1009
|
};
|
|
998
1010
|
this.results.set(key, result);
|
|
999
1011
|
}
|
|
@@ -1125,6 +1137,24 @@ var HealthChecker = class {
|
|
|
1125
1137
|
sleep(ms) {
|
|
1126
1138
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
1127
1139
|
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Detect CORS errors (browser compatibility issues)
|
|
1142
|
+
*
|
|
1143
|
+
* CORS errors occur when:
|
|
1144
|
+
* - Request header field is not allowed by Access-Control-Allow-Headers
|
|
1145
|
+
* - Specifically, x-ton-client-version header is blocked by some providers
|
|
1146
|
+
* - Error message contains "CORS", "Access-Control", or "x-ton-client-version"
|
|
1147
|
+
*/
|
|
1148
|
+
isCorsError(error, errorMsg) {
|
|
1149
|
+
const msg = errorMsg.toLowerCase();
|
|
1150
|
+
if (msg.includes("cors") || msg.includes("access-control") || msg.includes("x-ton-client-version") || msg.includes("not allowed by access-control-allow-headers") || msg.includes("blocked by cors policy")) {
|
|
1151
|
+
return true;
|
|
1152
|
+
}
|
|
1153
|
+
if (error.name === "TypeError" && (msg.includes("failed to fetch") || msg.includes("network error"))) {
|
|
1154
|
+
return false;
|
|
1155
|
+
}
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1128
1158
|
};
|
|
1129
1159
|
function createHealthChecker(config, logger, rateLimiter) {
|
|
1130
1160
|
return new HealthChecker(config, logger, rateLimiter);
|
|
@@ -1569,7 +1599,7 @@ var DEFAULT_CONFIG2 = {
|
|
|
1569
1599
|
minStatus: ["available", "degraded"]
|
|
1570
1600
|
};
|
|
1571
1601
|
var ProviderSelector = class {
|
|
1572
|
-
constructor(registry, healthChecker, config, logger) {
|
|
1602
|
+
constructor(registry, healthChecker, config, logger, adapter = "node") {
|
|
1573
1603
|
// Selection state
|
|
1574
1604
|
this.selectedProviderId = null;
|
|
1575
1605
|
this.autoSelect = true;
|
|
@@ -1581,6 +1611,7 @@ var ProviderSelector = class {
|
|
|
1581
1611
|
this.healthChecker = healthChecker;
|
|
1582
1612
|
this.config = { ...DEFAULT_CONFIG2, ...config };
|
|
1583
1613
|
this.logger = logger || consoleLogger4;
|
|
1614
|
+
this.adapter = adapter;
|
|
1584
1615
|
}
|
|
1585
1616
|
// ========================================================================
|
|
1586
1617
|
// Selection Methods
|
|
@@ -1621,9 +1652,19 @@ var ProviderSelector = class {
|
|
|
1621
1652
|
* Find the best provider for a network (recalculates)
|
|
1622
1653
|
*/
|
|
1623
1654
|
findBestProvider(network) {
|
|
1624
|
-
|
|
1655
|
+
let providers = this.registry.getProvidersForNetwork(network);
|
|
1656
|
+
if (this.adapter === "browser") {
|
|
1657
|
+
const beforeCount = providers.length;
|
|
1658
|
+
providers = this.filterBrowserCompatible(providers, network);
|
|
1659
|
+
const filteredCount = beforeCount - providers.length;
|
|
1660
|
+
if (filteredCount > 0) {
|
|
1661
|
+
this.logger.debug(
|
|
1662
|
+
`Filtered out ${filteredCount} browser-incompatible provider(s) for ${network}`
|
|
1663
|
+
);
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1625
1666
|
if (providers.length === 0) {
|
|
1626
|
-
this.logger.warn(`No providers available for ${network}`);
|
|
1667
|
+
this.logger.warn(`No browser-compatible providers available for ${network}`);
|
|
1627
1668
|
return null;
|
|
1628
1669
|
}
|
|
1629
1670
|
const scored = providers.map((provider) => ({
|
|
@@ -1704,7 +1745,10 @@ var ProviderSelector = class {
|
|
|
1704
1745
|
* Get all available providers for a network, sorted by score
|
|
1705
1746
|
*/
|
|
1706
1747
|
getAvailableProviders(network) {
|
|
1707
|
-
|
|
1748
|
+
let providers = this.registry.getProvidersForNetwork(network);
|
|
1749
|
+
if (this.adapter === "browser") {
|
|
1750
|
+
providers = this.filterBrowserCompatible(providers, network);
|
|
1751
|
+
}
|
|
1708
1752
|
return providers.map((provider) => ({
|
|
1709
1753
|
provider,
|
|
1710
1754
|
score: this.scoreProvider(provider, network)
|
|
@@ -1714,7 +1758,10 @@ var ProviderSelector = class {
|
|
|
1714
1758
|
* Get the next best provider (for failover)
|
|
1715
1759
|
*/
|
|
1716
1760
|
getNextProvider(network, excludeIds) {
|
|
1717
|
-
|
|
1761
|
+
let providers = this.registry.getProvidersForNetwork(network);
|
|
1762
|
+
if (this.adapter === "browser") {
|
|
1763
|
+
providers = this.filterBrowserCompatible(providers, network);
|
|
1764
|
+
}
|
|
1718
1765
|
const available = providers.filter((p) => !excludeIds.includes(p.id)).map((provider) => ({
|
|
1719
1766
|
provider,
|
|
1720
1767
|
score: this.scoreProvider(provider, network)
|
|
@@ -1905,12 +1952,39 @@ var ProviderSelector = class {
|
|
|
1905
1952
|
endpointV2: this.customEndpoint,
|
|
1906
1953
|
rps: 10,
|
|
1907
1954
|
priority: 0,
|
|
1908
|
-
isDynamic: false
|
|
1955
|
+
isDynamic: false,
|
|
1956
|
+
browserCompatible: true
|
|
1957
|
+
// Custom endpoints are assumed compatible
|
|
1909
1958
|
};
|
|
1910
1959
|
}
|
|
1960
|
+
/**
|
|
1961
|
+
* Filter providers to only include browser-compatible ones
|
|
1962
|
+
*
|
|
1963
|
+
* Checks both:
|
|
1964
|
+
* 1. Provider config browserCompatible flag
|
|
1965
|
+
* 2. Health check result browserCompatible flag (if health check was performed)
|
|
1966
|
+
*/
|
|
1967
|
+
filterBrowserCompatible(providers, network) {
|
|
1968
|
+
return providers.filter((provider) => {
|
|
1969
|
+
if (!provider.browserCompatible) {
|
|
1970
|
+
this.logger.debug(
|
|
1971
|
+
`Provider ${provider.id} marked as browser-incompatible in config`
|
|
1972
|
+
);
|
|
1973
|
+
return false;
|
|
1974
|
+
}
|
|
1975
|
+
const health = this.healthChecker.getResult(provider.id, network);
|
|
1976
|
+
if (health && health.browserCompatible === false) {
|
|
1977
|
+
this.logger.debug(
|
|
1978
|
+
`Provider ${provider.id} marked as browser-incompatible by health check (CORS error detected)`
|
|
1979
|
+
);
|
|
1980
|
+
return false;
|
|
1981
|
+
}
|
|
1982
|
+
return true;
|
|
1983
|
+
});
|
|
1984
|
+
}
|
|
1911
1985
|
};
|
|
1912
|
-
function createSelector(registry, healthChecker, config, logger) {
|
|
1913
|
-
return new ProviderSelector(registry, healthChecker, config, logger);
|
|
1986
|
+
function createSelector(registry, healthChecker, config, logger, adapter = "node") {
|
|
1987
|
+
return new ProviderSelector(registry, healthChecker, config, logger, adapter);
|
|
1914
1988
|
}
|
|
1915
1989
|
|
|
1916
1990
|
// src/core/manager.ts
|
|
@@ -2017,7 +2091,8 @@ var _ProviderManager = class _ProviderManager {
|
|
|
2017
2091
|
this.registry,
|
|
2018
2092
|
this.healthChecker,
|
|
2019
2093
|
void 0,
|
|
2020
|
-
this.options.logger
|
|
2094
|
+
this.options.logger,
|
|
2095
|
+
this.options.adapter
|
|
2021
2096
|
);
|
|
2022
2097
|
this.initialized = true;
|
|
2023
2098
|
this.notifyListeners();
|
|
@@ -2284,7 +2359,20 @@ var _ProviderManager = class _ProviderManager {
|
|
|
2284
2359
|
*/
|
|
2285
2360
|
getProviders() {
|
|
2286
2361
|
if (!this.initialized || !this.network) return [];
|
|
2287
|
-
|
|
2362
|
+
let providers = this.registry.getProvidersForNetwork(this.network);
|
|
2363
|
+
if (this.options.adapter === "browser") {
|
|
2364
|
+
providers = providers.filter((provider) => {
|
|
2365
|
+
if (!provider.browserCompatible) {
|
|
2366
|
+
return false;
|
|
2367
|
+
}
|
|
2368
|
+
const health = this.healthChecker.getResult(provider.id, this.network);
|
|
2369
|
+
if (health && health.browserCompatible === false) {
|
|
2370
|
+
return false;
|
|
2371
|
+
}
|
|
2372
|
+
return true;
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
return providers;
|
|
2288
2376
|
}
|
|
2289
2377
|
/**
|
|
2290
2378
|
* Get provider health results for current network
|
|
@@ -2330,7 +2418,8 @@ var _ProviderManager = class _ProviderManager {
|
|
|
2330
2418
|
latencyMs: null,
|
|
2331
2419
|
seqno: null,
|
|
2332
2420
|
blocksBehind: 0,
|
|
2333
|
-
lastTested: null
|
|
2421
|
+
lastTested: null,
|
|
2422
|
+
browserCompatible: provider.browserCompatible
|
|
2334
2423
|
},
|
|
2335
2424
|
rateLimit: rateLimit || {
|
|
2336
2425
|
tokens: 0,
|