ton-provider-system 0.2.4 → 0.3.0

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.js CHANGED
@@ -1035,6 +1035,238 @@ function createProvider(provider) {
1035
1035
  }
1036
1036
  }
1037
1037
 
1038
+ // src/utils/endpoint.ts
1039
+ function normalizeV2Endpoint(endpoint, provider) {
1040
+ if (provider) {
1041
+ const providerImpl = createProvider(provider);
1042
+ return providerImpl.normalizeEndpoint(endpoint);
1043
+ }
1044
+ return normalizeV2EndpointFallback(endpoint);
1045
+ }
1046
+ function normalizeV2EndpointFallback(endpoint) {
1047
+ let normalized = endpoint.trim();
1048
+ if (normalized.endsWith("/")) {
1049
+ normalized = normalized.slice(0, -1);
1050
+ }
1051
+ if (normalized.toLowerCase().endsWith("/jsonrpc")) {
1052
+ return normalized;
1053
+ }
1054
+ if (normalized.includes("gateway.tatum.io")) {
1055
+ try {
1056
+ const url = new URL(normalized);
1057
+ if (!url.pathname || url.pathname === "/") {
1058
+ return normalized + "/jsonRPC";
1059
+ }
1060
+ if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
1061
+ return normalized + "/jsonRPC";
1062
+ }
1063
+ } catch {
1064
+ return normalized + "/jsonRPC";
1065
+ }
1066
+ }
1067
+ if (normalized.includes("onfinality.io")) {
1068
+ try {
1069
+ const url = new URL(normalized);
1070
+ const baseUrl = normalized.split("?")[0];
1071
+ if (!url.pathname || url.pathname === "/") {
1072
+ const apikey = url.searchParams.get("apikey");
1073
+ if (apikey && apikey !== "{key}" && apikey.length > 0) {
1074
+ return baseUrl.replace(/\/?$/, "/rpc");
1075
+ }
1076
+ return baseUrl.replace(/\/?$/, "/public");
1077
+ }
1078
+ if (url.pathname === "/rpc" || url.pathname === "/public") {
1079
+ return baseUrl;
1080
+ }
1081
+ return baseUrl;
1082
+ } catch {
1083
+ if (normalized.includes("{key}")) {
1084
+ return normalized.split("?")[0].replace(/\/?$/, "/public");
1085
+ }
1086
+ if (!normalized.includes("/rpc") && !normalized.includes("/public")) {
1087
+ return normalized.split("?")[0] + "/public";
1088
+ }
1089
+ return normalized.split("?")[0];
1090
+ }
1091
+ }
1092
+ if (normalized.endsWith("/api/v2")) {
1093
+ return normalized + "/jsonRPC";
1094
+ }
1095
+ if (normalized.endsWith("/api/v3")) {
1096
+ return normalized.replace("/api/v3", "/api/v2/jsonRPC");
1097
+ }
1098
+ if (normalized.includes("quiknode.pro") || normalized.includes("getblock.io")) {
1099
+ try {
1100
+ const url = new URL(normalized);
1101
+ if (!url.pathname || url.pathname === "/") {
1102
+ return normalized + "/jsonRPC";
1103
+ }
1104
+ if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
1105
+ return normalized + "/jsonRPC";
1106
+ }
1107
+ } catch {
1108
+ return normalized + "/jsonRPC";
1109
+ }
1110
+ }
1111
+ try {
1112
+ const url = new URL(normalized);
1113
+ if (!url.pathname || url.pathname === "/") {
1114
+ return normalized + "/jsonRPC";
1115
+ }
1116
+ } catch {
1117
+ }
1118
+ return normalized;
1119
+ }
1120
+ function toV2Base(endpoint) {
1121
+ let normalized = endpoint.trim();
1122
+ if (normalized.endsWith("/")) {
1123
+ normalized = normalized.slice(0, -1);
1124
+ }
1125
+ if (normalized.toLowerCase().endsWith("/jsonrpc")) {
1126
+ normalized = normalized.slice(0, -8);
1127
+ }
1128
+ normalized = normalized.replace(/\/api\/v3\b/, "/api/v2");
1129
+ if (!normalized.endsWith("/api/v2")) {
1130
+ if (normalized.includes("/api/v2")) {
1131
+ const idx = normalized.indexOf("/api/v2");
1132
+ normalized = normalized.slice(0, idx + 7);
1133
+ }
1134
+ }
1135
+ return normalized;
1136
+ }
1137
+ function toV3Base(endpoint) {
1138
+ const normalized = toV2Base(endpoint);
1139
+ return normalized.replace("/api/v2", "/api/v3");
1140
+ }
1141
+ function getBaseUrl(endpoint) {
1142
+ try {
1143
+ const url = new URL(endpoint);
1144
+ return `${url.protocol}//${url.host}`;
1145
+ } catch {
1146
+ return endpoint;
1147
+ }
1148
+ }
1149
+ function isChainstackUrl(url) {
1150
+ try {
1151
+ const parsed = new URL(url.trim());
1152
+ return parsed.hostname.includes("chainstack.com");
1153
+ } catch {
1154
+ return false;
1155
+ }
1156
+ }
1157
+ function isQuickNodeUrl(url) {
1158
+ try {
1159
+ const parsed = new URL(url.trim());
1160
+ return parsed.hostname.includes("quiknode.pro");
1161
+ } catch {
1162
+ return false;
1163
+ }
1164
+ }
1165
+ function isTonCenterUrl(url) {
1166
+ try {
1167
+ const parsed = new URL(url.trim());
1168
+ return parsed.hostname.includes("toncenter.com");
1169
+ } catch {
1170
+ return false;
1171
+ }
1172
+ }
1173
+ function isOrbsUrl(url) {
1174
+ try {
1175
+ const parsed = new URL(url.trim());
1176
+ return parsed.hostname.includes("orbs.network") || parsed.hostname.includes("ton-access");
1177
+ } catch {
1178
+ return false;
1179
+ }
1180
+ }
1181
+ function buildRestUrl(baseEndpoint, method) {
1182
+ const base = toV2Base(baseEndpoint);
1183
+ return `${base}/${method}`;
1184
+ }
1185
+ function buildGetAddressStateUrl(baseEndpoint, address) {
1186
+ const base = toV2Base(baseEndpoint);
1187
+ return `${base}/getAddressState?address=${encodeURIComponent(address)}`;
1188
+ }
1189
+ function buildGetAddressBalanceUrl(baseEndpoint, address) {
1190
+ const base = toV2Base(baseEndpoint);
1191
+ return `${base}/getAddressBalance?address=${encodeURIComponent(address)}`;
1192
+ }
1193
+ function buildGetAddressInfoUrl(baseEndpoint, address) {
1194
+ const base = toV2Base(baseEndpoint);
1195
+ return `${base}/getAddressInformation?address=${encodeURIComponent(address)}`;
1196
+ }
1197
+ function detectNetworkFromEndpoint(endpoint) {
1198
+ const lower = endpoint.toLowerCase();
1199
+ if (lower.includes("testnet") || lower.includes("test") || lower.includes("sandbox")) {
1200
+ return "testnet";
1201
+ }
1202
+ if (lower.includes("mainnet") || lower.includes("main") || // TonCenter mainnet doesn't have 'mainnet' in URL
1203
+ lower.includes("toncenter.com") && !lower.includes("testnet")) {
1204
+ return "mainnet";
1205
+ }
1206
+ return null;
1207
+ }
1208
+ function isValidHttpUrl(str) {
1209
+ try {
1210
+ const url = new URL(str);
1211
+ return url.protocol === "http:" || url.protocol === "https:";
1212
+ } catch {
1213
+ return false;
1214
+ }
1215
+ }
1216
+ function isValidWsUrl(str) {
1217
+ try {
1218
+ const url = new URL(str);
1219
+ return url.protocol === "ws:" || url.protocol === "wss:";
1220
+ } catch {
1221
+ return false;
1222
+ }
1223
+ }
1224
+ function isCredentialLike(segment) {
1225
+ return /^[0-9a-f]{16,}$/i.test(segment) || // hex API keys (e.g. Chainstack/GetBlock)
1226
+ /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(segment) || // UUID
1227
+ /^[A-Za-z0-9_-]{20,}$/.test(segment);
1228
+ }
1229
+ function redactUrl(url) {
1230
+ const MASK = "***";
1231
+ const SENSITIVE_PARAM = /^(apikey|api[-_]?key|key|token|secret|password)$/i;
1232
+ const STRUCTURAL = /* @__PURE__ */ new Set([
1233
+ "api",
1234
+ "v1",
1235
+ "v2",
1236
+ "v3",
1237
+ "v4",
1238
+ "jsonrpc",
1239
+ "rpc",
1240
+ "public",
1241
+ "ws",
1242
+ "testnet",
1243
+ "mainnet",
1244
+ "toncenter-api-v2"
1245
+ ]);
1246
+ try {
1247
+ const u = new URL(url);
1248
+ for (const name of Array.from(u.searchParams.keys())) {
1249
+ if (SENSITIVE_PARAM.test(name)) {
1250
+ u.searchParams.set(name, MASK);
1251
+ }
1252
+ }
1253
+ u.pathname = u.pathname.split("/").map(
1254
+ (seg) => seg && !STRUCTURAL.has(seg.toLowerCase()) && isCredentialLike(seg) ? MASK : seg
1255
+ ).join("/");
1256
+ const hostParts = u.hostname.split(".");
1257
+ if (hostParts.length > 2 && isCredentialLike(hostParts[0])) {
1258
+ hostParts[0] = MASK;
1259
+ u.hostname = hostParts.join(".");
1260
+ }
1261
+ return u.toString();
1262
+ } catch {
1263
+ return url.replace(
1264
+ /\b(apikey|api[-_]?key|key|token|secret|password)=[^&\s]+/gi,
1265
+ `$1=${MASK}`
1266
+ );
1267
+ }
1268
+ }
1269
+
1038
1270
  // src/core/healthChecker.ts
1039
1271
  var consoleLogger2 = {
1040
1272
  debug: (msg, data) => console.debug(`[HealthChecker] ${msg}`, data || ""),
@@ -1051,6 +1283,8 @@ var HealthChecker = class {
1051
1283
  constructor(config, logger, rateLimiter) {
1052
1284
  this.results = /* @__PURE__ */ new Map();
1053
1285
  this.highestSeqno = /* @__PURE__ */ new Map();
1286
+ /** Rolling window of recent valid seqnos per network (for outlier-robust blocksBehind). */
1287
+ this.seqnoSamples = /* @__PURE__ */ new Map();
1054
1288
  this.rateLimiter = null;
1055
1289
  this.config = { ...DEFAULT_CONFIG, ...config };
1056
1290
  this.logger = logger || consoleLogger2;
@@ -1096,22 +1330,36 @@ var HealthChecker = class {
1096
1330
  if (!validation.valid) {
1097
1331
  throw new Error(validation.error || "Provider configuration invalid");
1098
1332
  }
1099
- const normalizedEndpoint = providerImpl.normalizeEndpoint(endpoint);
1333
+ let normalizedEndpoint = providerImpl.normalizeEndpoint(endpoint);
1100
1334
  if (provider.type === "onfinality") {
1101
- this.logger.debug(`OnFinality endpoint: ${endpoint} -> ${normalizedEndpoint}, API key: ${provider.apiKey ? "set" : "not set"}`);
1335
+ this.logger.debug(`OnFinality endpoint: ${redactUrl(endpoint)} -> ${redactUrl(normalizedEndpoint)}, API key: ${provider.apiKey ? "set" : "not set"}`);
1102
1336
  }
1337
+ const orbsRetries = provider.isDynamic && provider.type === "orbs" ? 2 : 0;
1103
1338
  let info;
1104
- try {
1105
- info = await this.callGetMasterchainInfo(normalizedEndpoint, provider, providerImpl);
1106
- } catch (error) {
1107
- if (provider.type === "onfinality" && normalizedEndpoint.includes("/rpc") && provider.apiKey && error.message?.includes("backend error")) {
1108
- this.logger.debug(`OnFinality /rpc failed, retrying with /public endpoint`);
1109
- const baseUrl = normalizedEndpoint.split("?")[0];
1110
- const publicEndpoint = baseUrl.replace("/rpc", "/public");
1111
- const publicProvider = { ...provider, apiKey: void 0 };
1112
- const publicProviderImpl = createProvider(publicProvider);
1113
- info = await this.callGetMasterchainInfo(publicEndpoint, publicProvider, publicProviderImpl);
1114
- } else {
1339
+ for (let attempt = 0; ; attempt++) {
1340
+ try {
1341
+ info = await this.callGetMasterchainInfo(normalizedEndpoint, provider, providerImpl);
1342
+ break;
1343
+ } catch (error) {
1344
+ if (provider.type === "onfinality" && normalizedEndpoint.includes("/rpc") && provider.apiKey && error.message?.includes("backend error")) {
1345
+ this.logger.debug(`OnFinality /rpc failed, retrying with /public endpoint`);
1346
+ const baseUrl = normalizedEndpoint.split("?")[0];
1347
+ const publicEndpoint = baseUrl.replace("/rpc", "/public");
1348
+ const publicProvider = { ...provider, apiKey: void 0 };
1349
+ const publicProviderImpl = createProvider(publicProvider);
1350
+ info = await this.callGetMasterchainInfo(publicEndpoint, publicProvider, publicProviderImpl);
1351
+ break;
1352
+ }
1353
+ if (attempt < orbsRetries && this.isNonJsonResponseError(error)) {
1354
+ this.logger.debug(
1355
+ `Orbs gateway returned a non-JSON response; re-discovering endpoint (retry ${attempt + 1}/${orbsRetries})`
1356
+ );
1357
+ const freshEndpoint = await this.getEndpoint(provider);
1358
+ if (freshEndpoint) {
1359
+ normalizedEndpoint = providerImpl.normalizeEndpoint(freshEndpoint);
1360
+ continue;
1361
+ }
1362
+ }
1115
1363
  throw error;
1116
1364
  }
1117
1365
  }
@@ -1126,7 +1374,8 @@ var HealthChecker = class {
1126
1374
  if (seqno > currentHighest) {
1127
1375
  this.highestSeqno.set(provider.network, seqno);
1128
1376
  }
1129
- const blocksBehind = Math.max(0, (this.highestSeqno.get(provider.network) || seqno) - seqno);
1377
+ const baselineSeqno = this.recordSeqnoAndGetBaseline(provider.network, seqno);
1378
+ const blocksBehind = Math.max(0, baselineSeqno - seqno);
1130
1379
  let status = "available";
1131
1380
  if (blocksBehind > this.config.maxBlocksBehind) {
1132
1381
  status = "stale";
@@ -1270,6 +1519,7 @@ var HealthChecker = class {
1270
1519
  clearResults() {
1271
1520
  this.results.clear();
1272
1521
  this.highestSeqno.clear();
1522
+ this.seqnoSamples.clear();
1273
1523
  }
1274
1524
  /**
1275
1525
  * Mark a provider as degraded (e.g., on 429 error)
@@ -1339,6 +1589,31 @@ var HealthChecker = class {
1339
1589
  getResultKey(providerId, network) {
1340
1590
  return `${providerId}-${network}`;
1341
1591
  }
1592
+ /**
1593
+ * Record a valid seqno sample and return an outlier-robust freshness baseline
1594
+ * (median of recent samples for the network). Using the median instead of the
1595
+ * raw maximum prevents a single provider that reports an inflated seqno from
1596
+ * poisoning `blocksBehind` for every other (healthy) provider. See P2-2.
1597
+ */
1598
+ recordSeqnoAndGetBaseline(network, seqno) {
1599
+ const samples = this.seqnoSamples.get(network) ?? [];
1600
+ samples.push(seqno);
1601
+ if (samples.length > 20) {
1602
+ samples.shift();
1603
+ }
1604
+ this.seqnoSamples.set(network, samples);
1605
+ const sorted = [...samples].sort((a, b) => a - b);
1606
+ const mid = Math.floor((sorted.length - 1) / 2);
1607
+ return sorted[mid];
1608
+ }
1609
+ /**
1610
+ * Detect a "non-JSON response" error (e.g. an HTML error page returned by a
1611
+ * misbehaving gateway), used to decide whether to re-discover an Orbs endpoint.
1612
+ */
1613
+ isNonJsonResponseError(error) {
1614
+ const msg = (error?.message || String(error) || "").toLowerCase();
1615
+ return msg.includes("invalid response type") || msg.includes("expected json") || msg.includes("got text/html");
1616
+ }
1342
1617
  /**
1343
1618
  * Get endpoint URL for a provider (handles dynamic providers like Orbs)
1344
1619
  */
@@ -2180,7 +2455,7 @@ var ProviderSelector = class {
2180
2455
  */
2181
2456
  setCustomEndpoint(endpoint) {
2182
2457
  this.customEndpoint = endpoint?.trim() || null;
2183
- this.logger.info(`Custom endpoint: ${this.customEndpoint || "(none)"}`);
2458
+ this.logger.info(`Custom endpoint: ${this.customEndpoint ? redactUrl(this.customEndpoint) : "(none)"}`);
2184
2459
  }
2185
2460
  /**
2186
2461
  * Get custom endpoint
@@ -2324,193 +2599,6 @@ function createSelector(registry, healthChecker, config, logger, adapter = "node
2324
2599
  return new ProviderSelector(registry, healthChecker, config, logger, adapter);
2325
2600
  }
2326
2601
 
2327
- // src/utils/endpoint.ts
2328
- function normalizeV2Endpoint(endpoint, provider) {
2329
- if (provider) {
2330
- const providerImpl = createProvider(provider);
2331
- return providerImpl.normalizeEndpoint(endpoint);
2332
- }
2333
- return normalizeV2EndpointFallback(endpoint);
2334
- }
2335
- function normalizeV2EndpointFallback(endpoint) {
2336
- let normalized = endpoint.trim();
2337
- if (normalized.endsWith("/")) {
2338
- normalized = normalized.slice(0, -1);
2339
- }
2340
- if (normalized.toLowerCase().endsWith("/jsonrpc")) {
2341
- return normalized;
2342
- }
2343
- if (normalized.includes("gateway.tatum.io")) {
2344
- try {
2345
- const url = new URL(normalized);
2346
- if (!url.pathname || url.pathname === "/") {
2347
- return normalized + "/jsonRPC";
2348
- }
2349
- if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
2350
- return normalized + "/jsonRPC";
2351
- }
2352
- } catch {
2353
- return normalized + "/jsonRPC";
2354
- }
2355
- }
2356
- if (normalized.includes("onfinality.io")) {
2357
- try {
2358
- const url = new URL(normalized);
2359
- const baseUrl = normalized.split("?")[0];
2360
- if (!url.pathname || url.pathname === "/") {
2361
- const apikey = url.searchParams.get("apikey");
2362
- if (apikey && apikey !== "{key}" && apikey.length > 0) {
2363
- return baseUrl.replace(/\/?$/, "/rpc");
2364
- }
2365
- return baseUrl.replace(/\/?$/, "/public");
2366
- }
2367
- if (url.pathname === "/rpc" || url.pathname === "/public") {
2368
- return baseUrl;
2369
- }
2370
- return baseUrl;
2371
- } catch {
2372
- if (normalized.includes("{key}")) {
2373
- return normalized.split("?")[0].replace(/\/?$/, "/public");
2374
- }
2375
- if (!normalized.includes("/rpc") && !normalized.includes("/public")) {
2376
- return normalized.split("?")[0] + "/public";
2377
- }
2378
- return normalized.split("?")[0];
2379
- }
2380
- }
2381
- if (normalized.endsWith("/api/v2")) {
2382
- return normalized + "/jsonRPC";
2383
- }
2384
- if (normalized.endsWith("/api/v3")) {
2385
- return normalized.replace("/api/v3", "/api/v2/jsonRPC");
2386
- }
2387
- if (normalized.includes("quiknode.pro") || normalized.includes("getblock.io")) {
2388
- try {
2389
- const url = new URL(normalized);
2390
- if (!url.pathname || url.pathname === "/") {
2391
- return normalized + "/jsonRPC";
2392
- }
2393
- if (!url.pathname.toLowerCase().endsWith("/jsonrpc")) {
2394
- return normalized + "/jsonRPC";
2395
- }
2396
- } catch {
2397
- return normalized + "/jsonRPC";
2398
- }
2399
- }
2400
- try {
2401
- const url = new URL(normalized);
2402
- if (!url.pathname || url.pathname === "/") {
2403
- return normalized + "/jsonRPC";
2404
- }
2405
- } catch {
2406
- }
2407
- return normalized;
2408
- }
2409
- function toV2Base(endpoint) {
2410
- let normalized = endpoint.trim();
2411
- if (normalized.endsWith("/")) {
2412
- normalized = normalized.slice(0, -1);
2413
- }
2414
- if (normalized.toLowerCase().endsWith("/jsonrpc")) {
2415
- normalized = normalized.slice(0, -8);
2416
- }
2417
- normalized = normalized.replace(/\/api\/v3\b/, "/api/v2");
2418
- if (!normalized.endsWith("/api/v2")) {
2419
- if (normalized.includes("/api/v2")) {
2420
- const idx = normalized.indexOf("/api/v2");
2421
- normalized = normalized.slice(0, idx + 7);
2422
- }
2423
- }
2424
- return normalized;
2425
- }
2426
- function toV3Base(endpoint) {
2427
- const normalized = toV2Base(endpoint);
2428
- return normalized.replace("/api/v2", "/api/v3");
2429
- }
2430
- function getBaseUrl(endpoint) {
2431
- try {
2432
- const url = new URL(endpoint);
2433
- return `${url.protocol}//${url.host}`;
2434
- } catch {
2435
- return endpoint;
2436
- }
2437
- }
2438
- function isChainstackUrl(url) {
2439
- try {
2440
- const parsed = new URL(url.trim());
2441
- return parsed.hostname.includes("chainstack.com");
2442
- } catch {
2443
- return false;
2444
- }
2445
- }
2446
- function isQuickNodeUrl(url) {
2447
- try {
2448
- const parsed = new URL(url.trim());
2449
- return parsed.hostname.includes("quiknode.pro");
2450
- } catch {
2451
- return false;
2452
- }
2453
- }
2454
- function isTonCenterUrl(url) {
2455
- try {
2456
- const parsed = new URL(url.trim());
2457
- return parsed.hostname.includes("toncenter.com");
2458
- } catch {
2459
- return false;
2460
- }
2461
- }
2462
- function isOrbsUrl(url) {
2463
- try {
2464
- const parsed = new URL(url.trim());
2465
- return parsed.hostname.includes("orbs.network") || parsed.hostname.includes("ton-access");
2466
- } catch {
2467
- return false;
2468
- }
2469
- }
2470
- function buildRestUrl(baseEndpoint, method) {
2471
- const base = toV2Base(baseEndpoint);
2472
- return `${base}/${method}`;
2473
- }
2474
- function buildGetAddressStateUrl(baseEndpoint, address) {
2475
- const base = toV2Base(baseEndpoint);
2476
- return `${base}/getAddressState?address=${encodeURIComponent(address)}`;
2477
- }
2478
- function buildGetAddressBalanceUrl(baseEndpoint, address) {
2479
- const base = toV2Base(baseEndpoint);
2480
- return `${base}/getAddressBalance?address=${encodeURIComponent(address)}`;
2481
- }
2482
- function buildGetAddressInfoUrl(baseEndpoint, address) {
2483
- const base = toV2Base(baseEndpoint);
2484
- return `${base}/getAddressInformation?address=${encodeURIComponent(address)}`;
2485
- }
2486
- function detectNetworkFromEndpoint(endpoint) {
2487
- const lower = endpoint.toLowerCase();
2488
- if (lower.includes("testnet") || lower.includes("test") || lower.includes("sandbox")) {
2489
- return "testnet";
2490
- }
2491
- if (lower.includes("mainnet") || lower.includes("main") || // TonCenter mainnet doesn't have 'mainnet' in URL
2492
- lower.includes("toncenter.com") && !lower.includes("testnet")) {
2493
- return "mainnet";
2494
- }
2495
- return null;
2496
- }
2497
- function isValidHttpUrl(str) {
2498
- try {
2499
- const url = new URL(str);
2500
- return url.protocol === "http:" || url.protocol === "https:";
2501
- } catch {
2502
- return false;
2503
- }
2504
- }
2505
- function isValidWsUrl(str) {
2506
- try {
2507
- const url = new URL(str);
2508
- return url.protocol === "ws:" || url.protocol === "wss:";
2509
- } catch {
2510
- return false;
2511
- }
2512
- }
2513
-
2514
2602
  // src/core/manager.ts
2515
2603
  var consoleLogger5 = {
2516
2604
  debug: (msg, data) => console.debug(`[ProviderManager] ${msg}`, data || ""),
@@ -3110,7 +3198,7 @@ var NodeAdapter = class {
3110
3198
  network,
3111
3199
  createdAt: Date.now()
3112
3200
  };
3113
- this.logger.debug(`Created TonClient for ${network}`, { endpoint });
3201
+ this.logger.debug(`Created TonClient for ${network}`, { endpoint: redactUrl(endpoint) });
3114
3202
  return client;
3115
3203
  }
3116
3204
  /**
@@ -3647,6 +3735,6 @@ async function createBrowserAdapterForNetwork(network, configPath, logger) {
3647
3735
  return new BrowserAdapter(manager, logger);
3648
3736
  }
3649
3737
 
3650
- export { ApiVersionSchema, BaseProvider, BrowserAdapter, CHAINSTACK_RATE_LIMIT, ChainstackProvider, ConfigError, DEFAULT_CONTRACT_TIMEOUT_MS, DEFAULT_HEALTH_CHECK_TIMEOUT_MS, DEFAULT_PROVIDERS, DEFAULT_PROVIDER_TIMEOUT_MS, DEFAULT_RATE_LIMIT, GenericProvider, GetBlockProvider, HealthChecker, NetworkSchema, NodeAdapter, ORBS_RATE_LIMIT, OnFinalityProvider, OrbsProvider, ProviderConfigSchema, ProviderError, ProviderManager, ProviderRegistry, ProviderSelector, ProviderTypeSchema, QUICKNODE_RATE_LIMIT, QuickNodeProvider, RateLimitError, RateLimiterManager, RpcConfigSchema, TatumProvider, TimeoutError, TokenBucketRateLimiter, TonCenterProvider, buildGetAddressBalanceUrl, buildGetAddressInfoUrl, buildGetAddressStateUrl, buildRestUrl, createBrowserAdapter, createBrowserAdapterForNetwork, createDefaultConfig, createDefaultRegistry, createEmptyConfig, createHealthChecker, createNodeAdapter, createProvider, createProviderManager, createRateLimiter, createRateLimiterManager, createRegistry, createRegistryFromData, createRegistryFromFile, createSelector, createTimeoutController, detectNetworkFromEndpoint, fetchWithTimeout, getBaseUrl, getDefaultProvidersForNetwork, getEnvVar, getProviderManager, getProvidersForNetwork, getRateLimitForType, getTonClient, getTonClientForNetwork, getTonClientWithRateLimit, isApiVersion, isChainstackUrl, isNetwork, isOrbsUrl, isProviderType, isQuickNodeUrl, isRateLimitError, isTimeoutError, isTonCenterUrl, isValidHttpUrl, isValidWsUrl, loadBuiltinConfig, loadConfig, loadConfigFromData, loadConfigFromUrl, mergeConfigs, mergeWithDefaults, normalizeV2Endpoint, parseProviderConfig, parseRpcConfig, resetNodeAdapter, resolveAllProviders, resolveEndpoints, resolveKeyPlaceholder, resolveProvider, sleep, toV2Base, toV3Base, withRetry, withTimeout, withTimeoutAndRetry, withTimeoutFn };
3738
+ export { ApiVersionSchema, BaseProvider, BrowserAdapter, CHAINSTACK_RATE_LIMIT, ChainstackProvider, ConfigError, DEFAULT_CONTRACT_TIMEOUT_MS, DEFAULT_HEALTH_CHECK_TIMEOUT_MS, DEFAULT_PROVIDERS, DEFAULT_PROVIDER_TIMEOUT_MS, DEFAULT_RATE_LIMIT, GenericProvider, GetBlockProvider, HealthChecker, NetworkSchema, NodeAdapter, ORBS_RATE_LIMIT, OnFinalityProvider, OrbsProvider, ProviderConfigSchema, ProviderError, ProviderManager, ProviderRegistry, ProviderSelector, ProviderTypeSchema, QUICKNODE_RATE_LIMIT, QuickNodeProvider, RateLimitError, RateLimiterManager, RpcConfigSchema, TatumProvider, TimeoutError, TokenBucketRateLimiter, TonCenterProvider, buildGetAddressBalanceUrl, buildGetAddressInfoUrl, buildGetAddressStateUrl, buildRestUrl, createBrowserAdapter, createBrowserAdapterForNetwork, createDefaultConfig, createDefaultRegistry, createEmptyConfig, createHealthChecker, createNodeAdapter, createProvider, createProviderManager, createRateLimiter, createRateLimiterManager, createRegistry, createRegistryFromData, createRegistryFromFile, createSelector, createTimeoutController, detectNetworkFromEndpoint, fetchWithTimeout, getBaseUrl, getDefaultProvidersForNetwork, getEnvVar, getProviderManager, getProvidersForNetwork, getRateLimitForType, getTonClient, getTonClientForNetwork, getTonClientWithRateLimit, isApiVersion, isChainstackUrl, isNetwork, isOrbsUrl, isProviderType, isQuickNodeUrl, isRateLimitError, isTimeoutError, isTonCenterUrl, isValidHttpUrl, isValidWsUrl, loadBuiltinConfig, loadConfig, loadConfigFromData, loadConfigFromUrl, mergeConfigs, mergeWithDefaults, normalizeV2Endpoint, parseProviderConfig, parseRpcConfig, redactUrl, resetNodeAdapter, resolveAllProviders, resolveEndpoints, resolveKeyPlaceholder, resolveProvider, sleep, toV2Base, toV3Base, withRetry, withTimeout, withTimeoutAndRetry, withTimeoutFn };
3651
3739
  //# sourceMappingURL=index.js.map
3652
3740
  //# sourceMappingURL=index.js.map