ton-provider-system 0.1.10 → 0.1.12

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.d.cts CHANGED
@@ -59,6 +59,8 @@ interface ProviderConfig {
59
59
  enabled: boolean;
60
60
  /** Whether this provider requires dynamic endpoint discovery (e.g., Orbs) */
61
61
  isDynamic?: boolean;
62
+ /** Whether this provider is compatible with browser environments (default: true) */
63
+ browserCompatible?: boolean;
62
64
  /** Optional description or notes */
63
65
  description?: string;
64
66
  }
@@ -114,6 +116,8 @@ interface ResolvedProvider {
114
116
  priority: number;
115
117
  /** Whether dynamic discovery is needed */
116
118
  isDynamic: boolean;
119
+ /** Whether this provider is compatible with browser environments */
120
+ browserCompatible: boolean;
117
121
  }
118
122
  /**
119
123
  * Provider health check result
@@ -139,6 +143,8 @@ interface ProviderHealthResult {
139
143
  cachedEndpoint?: string;
140
144
  /** Error message if failed */
141
145
  error?: string;
146
+ /** Whether this provider is compatible with browser environments */
147
+ browserCompatible: boolean;
142
148
  }
143
149
  /**
144
150
  * Provider state for runtime tracking
@@ -357,6 +363,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
357
363
  priority: z.ZodDefault<z.ZodNumber>;
358
364
  enabled: z.ZodDefault<z.ZodBoolean>;
359
365
  isDynamic: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
366
+ browserCompatible: z.ZodOptional<z.ZodBoolean>;
360
367
  description: z.ZodOptional<z.ZodString>;
361
368
  }, "strip", z.ZodTypeAny, {
362
369
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -374,6 +381,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
374
381
  isDynamic: boolean;
375
382
  keyEnvVar?: string | undefined;
376
383
  apiKeyEnvVar?: string | undefined;
384
+ browserCompatible?: boolean | undefined;
377
385
  description?: string | undefined;
378
386
  }, {
379
387
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -391,6 +399,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
391
399
  priority?: number | undefined;
392
400
  enabled?: boolean | undefined;
393
401
  isDynamic?: boolean | undefined;
402
+ browserCompatible?: boolean | undefined;
394
403
  description?: string | undefined;
395
404
  }>;
396
405
  /**
@@ -435,6 +444,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
435
444
  priority: z.ZodDefault<z.ZodNumber>;
436
445
  enabled: z.ZodDefault<z.ZodBoolean>;
437
446
  isDynamic: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
447
+ browserCompatible: z.ZodOptional<z.ZodBoolean>;
438
448
  description: z.ZodOptional<z.ZodString>;
439
449
  }, "strip", z.ZodTypeAny, {
440
450
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -452,6 +462,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
452
462
  isDynamic: boolean;
453
463
  keyEnvVar?: string | undefined;
454
464
  apiKeyEnvVar?: string | undefined;
465
+ browserCompatible?: boolean | undefined;
455
466
  description?: string | undefined;
456
467
  }, {
457
468
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -469,6 +480,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
469
480
  priority?: number | undefined;
470
481
  enabled?: boolean | undefined;
471
482
  isDynamic?: boolean | undefined;
483
+ browserCompatible?: boolean | undefined;
472
484
  description?: string | undefined;
473
485
  }>>;
474
486
  defaults: z.ZodObject<{
@@ -499,6 +511,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
499
511
  isDynamic: boolean;
500
512
  keyEnvVar?: string | undefined;
501
513
  apiKeyEnvVar?: string | undefined;
514
+ browserCompatible?: boolean | undefined;
502
515
  description?: string | undefined;
503
516
  }>;
504
517
  defaults: {
@@ -523,6 +536,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
523
536
  priority?: number | undefined;
524
537
  enabled?: boolean | undefined;
525
538
  isDynamic?: boolean | undefined;
539
+ browserCompatible?: boolean | undefined;
526
540
  description?: string | undefined;
527
541
  }>;
528
542
  defaults: {
@@ -549,6 +563,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
549
563
  isDynamic: boolean;
550
564
  keyEnvVar?: string | undefined;
551
565
  apiKeyEnvVar?: string | undefined;
566
+ browserCompatible?: boolean | undefined;
552
567
  description?: string | undefined;
553
568
  }>;
554
569
  defaults: {
@@ -573,6 +588,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
573
588
  priority?: number | undefined;
574
589
  enabled?: boolean | undefined;
575
590
  isDynamic?: boolean | undefined;
591
+ browserCompatible?: boolean | undefined;
576
592
  description?: string | undefined;
577
593
  }>;
578
594
  defaults: {
@@ -1039,6 +1055,15 @@ declare class HealthChecker {
1039
1055
  */
1040
1056
  private callGetMasterchainInfo;
1041
1057
  private sleep;
1058
+ /**
1059
+ * Detect CORS errors (browser compatibility issues)
1060
+ *
1061
+ * CORS errors occur when:
1062
+ * - Request header field is not allowed by Access-Control-Allow-Headers
1063
+ * - Specifically, x-ton-client-version header is blocked by some providers
1064
+ * - Error message contains "CORS", "Access-Control", or "x-ton-client-version"
1065
+ */
1066
+ private isCorsError;
1042
1067
  }
1043
1068
  /**
1044
1069
  * Create a health checker with default configuration
@@ -1078,12 +1103,13 @@ declare class ProviderSelector {
1078
1103
  private healthChecker;
1079
1104
  private config;
1080
1105
  private logger;
1106
+ private adapter;
1081
1107
  private selectedProviderId;
1082
1108
  private autoSelect;
1083
1109
  private customEndpoint;
1084
1110
  private bestProviderByNetwork;
1085
1111
  private activeProviderByNetwork;
1086
- constructor(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger);
1112
+ constructor(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger, adapter?: 'node' | 'browser');
1087
1113
  /**
1088
1114
  * Get the best provider for a network
1089
1115
  */
@@ -1166,11 +1192,19 @@ declare class ProviderSelector {
1166
1192
  * Create a pseudo-provider for custom endpoint
1167
1193
  */
1168
1194
  private createCustomProvider;
1195
+ /**
1196
+ * Filter providers to only include browser-compatible ones
1197
+ *
1198
+ * Checks both:
1199
+ * 1. Provider config browserCompatible flag
1200
+ * 2. Health check result browserCompatible flag (if health check was performed)
1201
+ */
1202
+ private filterBrowserCompatible;
1169
1203
  }
1170
1204
  /**
1171
1205
  * Create a provider selector
1172
1206
  */
1173
- declare function createSelector(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger): ProviderSelector;
1207
+ declare function createSelector(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger, adapter?: 'node' | 'browser'): ProviderSelector;
1174
1208
 
1175
1209
  /**
1176
1210
  * Unified Provider System - Provider Manager
package/dist/index.d.ts CHANGED
@@ -59,6 +59,8 @@ interface ProviderConfig {
59
59
  enabled: boolean;
60
60
  /** Whether this provider requires dynamic endpoint discovery (e.g., Orbs) */
61
61
  isDynamic?: boolean;
62
+ /** Whether this provider is compatible with browser environments (default: true) */
63
+ browserCompatible?: boolean;
62
64
  /** Optional description or notes */
63
65
  description?: string;
64
66
  }
@@ -114,6 +116,8 @@ interface ResolvedProvider {
114
116
  priority: number;
115
117
  /** Whether dynamic discovery is needed */
116
118
  isDynamic: boolean;
119
+ /** Whether this provider is compatible with browser environments */
120
+ browserCompatible: boolean;
117
121
  }
118
122
  /**
119
123
  * Provider health check result
@@ -139,6 +143,8 @@ interface ProviderHealthResult {
139
143
  cachedEndpoint?: string;
140
144
  /** Error message if failed */
141
145
  error?: string;
146
+ /** Whether this provider is compatible with browser environments */
147
+ browserCompatible: boolean;
142
148
  }
143
149
  /**
144
150
  * Provider state for runtime tracking
@@ -357,6 +363,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
357
363
  priority: z.ZodDefault<z.ZodNumber>;
358
364
  enabled: z.ZodDefault<z.ZodBoolean>;
359
365
  isDynamic: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
366
+ browserCompatible: z.ZodOptional<z.ZodBoolean>;
360
367
  description: z.ZodOptional<z.ZodString>;
361
368
  }, "strip", z.ZodTypeAny, {
362
369
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -374,6 +381,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
374
381
  isDynamic: boolean;
375
382
  keyEnvVar?: string | undefined;
376
383
  apiKeyEnvVar?: string | undefined;
384
+ browserCompatible?: boolean | undefined;
377
385
  description?: string | undefined;
378
386
  }, {
379
387
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -391,6 +399,7 @@ declare const ProviderConfigSchema: z.ZodObject<{
391
399
  priority?: number | undefined;
392
400
  enabled?: boolean | undefined;
393
401
  isDynamic?: boolean | undefined;
402
+ browserCompatible?: boolean | undefined;
394
403
  description?: string | undefined;
395
404
  }>;
396
405
  /**
@@ -435,6 +444,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
435
444
  priority: z.ZodDefault<z.ZodNumber>;
436
445
  enabled: z.ZodDefault<z.ZodBoolean>;
437
446
  isDynamic: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
447
+ browserCompatible: z.ZodOptional<z.ZodBoolean>;
438
448
  description: z.ZodOptional<z.ZodString>;
439
449
  }, "strip", z.ZodTypeAny, {
440
450
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -452,6 +462,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
452
462
  isDynamic: boolean;
453
463
  keyEnvVar?: string | undefined;
454
464
  apiKeyEnvVar?: string | undefined;
465
+ browserCompatible?: boolean | undefined;
455
466
  description?: string | undefined;
456
467
  }, {
457
468
  type: "chainstack" | "quicknode" | "toncenter" | "orbs" | "onfinality" | "ankr" | "getblock" | "tatum" | "tonhub" | "custom";
@@ -469,6 +480,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
469
480
  priority?: number | undefined;
470
481
  enabled?: boolean | undefined;
471
482
  isDynamic?: boolean | undefined;
483
+ browserCompatible?: boolean | undefined;
472
484
  description?: string | undefined;
473
485
  }>>;
474
486
  defaults: z.ZodObject<{
@@ -499,6 +511,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
499
511
  isDynamic: boolean;
500
512
  keyEnvVar?: string | undefined;
501
513
  apiKeyEnvVar?: string | undefined;
514
+ browserCompatible?: boolean | undefined;
502
515
  description?: string | undefined;
503
516
  }>;
504
517
  defaults: {
@@ -523,6 +536,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
523
536
  priority?: number | undefined;
524
537
  enabled?: boolean | undefined;
525
538
  isDynamic?: boolean | undefined;
539
+ browserCompatible?: boolean | undefined;
526
540
  description?: string | undefined;
527
541
  }>;
528
542
  defaults: {
@@ -549,6 +563,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
549
563
  isDynamic: boolean;
550
564
  keyEnvVar?: string | undefined;
551
565
  apiKeyEnvVar?: string | undefined;
566
+ browserCompatible?: boolean | undefined;
552
567
  description?: string | undefined;
553
568
  }>;
554
569
  defaults: {
@@ -573,6 +588,7 @@ declare const RpcConfigSchema: z.ZodEffects<z.ZodObject<{
573
588
  priority?: number | undefined;
574
589
  enabled?: boolean | undefined;
575
590
  isDynamic?: boolean | undefined;
591
+ browserCompatible?: boolean | undefined;
576
592
  description?: string | undefined;
577
593
  }>;
578
594
  defaults: {
@@ -1039,6 +1055,15 @@ declare class HealthChecker {
1039
1055
  */
1040
1056
  private callGetMasterchainInfo;
1041
1057
  private sleep;
1058
+ /**
1059
+ * Detect CORS errors (browser compatibility issues)
1060
+ *
1061
+ * CORS errors occur when:
1062
+ * - Request header field is not allowed by Access-Control-Allow-Headers
1063
+ * - Specifically, x-ton-client-version header is blocked by some providers
1064
+ * - Error message contains "CORS", "Access-Control", or "x-ton-client-version"
1065
+ */
1066
+ private isCorsError;
1042
1067
  }
1043
1068
  /**
1044
1069
  * Create a health checker with default configuration
@@ -1078,12 +1103,13 @@ declare class ProviderSelector {
1078
1103
  private healthChecker;
1079
1104
  private config;
1080
1105
  private logger;
1106
+ private adapter;
1081
1107
  private selectedProviderId;
1082
1108
  private autoSelect;
1083
1109
  private customEndpoint;
1084
1110
  private bestProviderByNetwork;
1085
1111
  private activeProviderByNetwork;
1086
- constructor(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger);
1112
+ constructor(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger, adapter?: 'node' | 'browser');
1087
1113
  /**
1088
1114
  * Get the best provider for a network
1089
1115
  */
@@ -1166,11 +1192,19 @@ declare class ProviderSelector {
1166
1192
  * Create a pseudo-provider for custom endpoint
1167
1193
  */
1168
1194
  private createCustomProvider;
1195
+ /**
1196
+ * Filter providers to only include browser-compatible ones
1197
+ *
1198
+ * Checks both:
1199
+ * 1. Provider config browserCompatible flag
1200
+ * 2. Health check result browserCompatible flag (if health check was performed)
1201
+ */
1202
+ private filterBrowserCompatible;
1169
1203
  }
1170
1204
  /**
1171
1205
  * Create a provider selector
1172
1206
  */
1173
- declare function createSelector(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger): ProviderSelector;
1207
+ declare function createSelector(registry: ProviderRegistry, healthChecker: HealthChecker, config?: Partial<SelectionConfig>, logger?: Logger, adapter?: 'node' | 'browser'): ProviderSelector;
1174
1208
 
1175
1209
  /**
1176
1210
  * Unified Provider System - Provider Manager
package/dist/index.js CHANGED
@@ -67,6 +67,7 @@ var ProviderConfigSchema = z.object({
67
67
  priority: z.number().int().nonnegative().default(10),
68
68
  enabled: z.boolean().default(true),
69
69
  isDynamic: z.boolean().optional().default(false),
70
+ browserCompatible: z.boolean().optional(),
70
71
  description: z.string().optional()
71
72
  });
72
73
  var NetworkDefaultsSchema = z.object({
@@ -214,7 +215,8 @@ function resolveProvider(id, config) {
214
215
  apiKey,
215
216
  rps: config.rps,
216
217
  priority: config.priority,
217
- isDynamic: config.isDynamic || false
218
+ isDynamic: config.isDynamic || false,
219
+ browserCompatible: config.browserCompatible !== void 0 ? config.browserCompatible : true
218
220
  };
219
221
  }
220
222
  function resolveAllProviders(config) {
@@ -773,7 +775,8 @@ var HealthChecker = class {
773
775
  latencyMs: null,
774
776
  seqno: null,
775
777
  blocksBehind: 0,
776
- lastTested: null
778
+ lastTested: null,
779
+ browserCompatible: provider.browserCompatible
777
780
  };
778
781
  this.results.set(key, testingResult);
779
782
  try {
@@ -833,7 +836,8 @@ var HealthChecker = class {
833
836
  seqno,
834
837
  blocksBehind,
835
838
  lastTested: /* @__PURE__ */ new Date(),
836
- cachedEndpoint: normalizedEndpoint
839
+ cachedEndpoint: normalizedEndpoint,
840
+ browserCompatible: provider.browserCompatible
837
841
  };
838
842
  this.results.set(key, result);
839
843
  this.logger.debug(
@@ -844,6 +848,7 @@ var HealthChecker = class {
844
848
  const endTime = performance.now();
845
849
  const latencyMs = Math.round(endTime - startTime);
846
850
  const errorMsg = error.message || String(error) || "Unknown error";
851
+ const isCorsError = this.isCorsError(error, errorMsg);
847
852
  const is429 = errorMsg.includes("429") || errorMsg.toLowerCase().includes("rate limit");
848
853
  const is404 = errorMsg.includes("404") || errorMsg.toLowerCase().includes("not found");
849
854
  const is503 = errorMsg.includes("503") || errorMsg.toLowerCase().includes("service unavailable");
@@ -858,6 +863,7 @@ var HealthChecker = class {
858
863
  } else if (isTimeout) {
859
864
  status = "offline";
860
865
  }
866
+ const browserCompatible = isCorsError ? false : provider.browserCompatible;
861
867
  const result = {
862
868
  id: provider.id,
863
869
  network: provider.network,
@@ -867,7 +873,8 @@ var HealthChecker = class {
867
873
  seqno: null,
868
874
  blocksBehind: 0,
869
875
  lastTested: /* @__PURE__ */ new Date(),
870
- error: errorMsg
876
+ error: errorMsg,
877
+ browserCompatible
871
878
  };
872
879
  this.results.set(key, result);
873
880
  this.logger.warn(`Provider ${provider.id} health check failed: ${result.error}`);
@@ -953,7 +960,8 @@ var HealthChecker = class {
953
960
  // Degraded providers are still usable, just slower/rate-limited
954
961
  status: "degraded",
955
962
  error: error || "Marked as degraded",
956
- lastTested: /* @__PURE__ */ new Date()
963
+ lastTested: /* @__PURE__ */ new Date(),
964
+ browserCompatible: existing.browserCompatible ?? true
957
965
  } : {
958
966
  id: providerId,
959
967
  network,
@@ -964,7 +972,9 @@ var HealthChecker = class {
964
972
  seqno: null,
965
973
  blocksBehind: 0,
966
974
  lastTested: /* @__PURE__ */ new Date(),
967
- error: error || "Marked as degraded"
975
+ error: error || "Marked as degraded",
976
+ browserCompatible: true
977
+ // Default to compatible if unknown
968
978
  };
969
979
  this.results.set(key, result);
970
980
  }
@@ -980,7 +990,8 @@ var HealthChecker = class {
980
990
  success: false,
981
991
  // Ensure success is false for offline providers
982
992
  error: error || "Marked as offline",
983
- lastTested: /* @__PURE__ */ new Date()
993
+ lastTested: /* @__PURE__ */ new Date(),
994
+ browserCompatible: existing.browserCompatible ?? true
984
995
  } : {
985
996
  id: providerId,
986
997
  network,
@@ -990,7 +1001,9 @@ var HealthChecker = class {
990
1001
  seqno: null,
991
1002
  blocksBehind: 0,
992
1003
  lastTested: /* @__PURE__ */ new Date(),
993
- error: error || "Marked as offline"
1004
+ error: error || "Marked as offline",
1005
+ browserCompatible: true
1006
+ // Default to compatible if unknown
994
1007
  };
995
1008
  this.results.set(key, result);
996
1009
  }
@@ -1122,6 +1135,24 @@ var HealthChecker = class {
1122
1135
  sleep(ms) {
1123
1136
  return new Promise((resolve) => setTimeout(resolve, ms));
1124
1137
  }
1138
+ /**
1139
+ * Detect CORS errors (browser compatibility issues)
1140
+ *
1141
+ * CORS errors occur when:
1142
+ * - Request header field is not allowed by Access-Control-Allow-Headers
1143
+ * - Specifically, x-ton-client-version header is blocked by some providers
1144
+ * - Error message contains "CORS", "Access-Control", or "x-ton-client-version"
1145
+ */
1146
+ isCorsError(error, errorMsg) {
1147
+ const msg = errorMsg.toLowerCase();
1148
+ 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")) {
1149
+ return true;
1150
+ }
1151
+ if (error.name === "TypeError" && (msg.includes("failed to fetch") || msg.includes("network error"))) {
1152
+ return false;
1153
+ }
1154
+ return false;
1155
+ }
1125
1156
  };
1126
1157
  function createHealthChecker(config, logger, rateLimiter) {
1127
1158
  return new HealthChecker(config, logger, rateLimiter);
@@ -1566,7 +1597,7 @@ var DEFAULT_CONFIG2 = {
1566
1597
  minStatus: ["available", "degraded"]
1567
1598
  };
1568
1599
  var ProviderSelector = class {
1569
- constructor(registry, healthChecker, config, logger) {
1600
+ constructor(registry, healthChecker, config, logger, adapter = "node") {
1570
1601
  // Selection state
1571
1602
  this.selectedProviderId = null;
1572
1603
  this.autoSelect = true;
@@ -1578,6 +1609,7 @@ var ProviderSelector = class {
1578
1609
  this.healthChecker = healthChecker;
1579
1610
  this.config = { ...DEFAULT_CONFIG2, ...config };
1580
1611
  this.logger = logger || consoleLogger4;
1612
+ this.adapter = adapter;
1581
1613
  }
1582
1614
  // ========================================================================
1583
1615
  // Selection Methods
@@ -1618,9 +1650,19 @@ var ProviderSelector = class {
1618
1650
  * Find the best provider for a network (recalculates)
1619
1651
  */
1620
1652
  findBestProvider(network) {
1621
- const providers = this.registry.getProvidersForNetwork(network);
1653
+ let providers = this.registry.getProvidersForNetwork(network);
1654
+ if (this.adapter === "browser") {
1655
+ const beforeCount = providers.length;
1656
+ providers = this.filterBrowserCompatible(providers, network);
1657
+ const filteredCount = beforeCount - providers.length;
1658
+ if (filteredCount > 0) {
1659
+ this.logger.debug(
1660
+ `Filtered out ${filteredCount} browser-incompatible provider(s) for ${network}`
1661
+ );
1662
+ }
1663
+ }
1622
1664
  if (providers.length === 0) {
1623
- this.logger.warn(`No providers available for ${network}`);
1665
+ this.logger.warn(`No browser-compatible providers available for ${network}`);
1624
1666
  return null;
1625
1667
  }
1626
1668
  const scored = providers.map((provider) => ({
@@ -1701,7 +1743,10 @@ var ProviderSelector = class {
1701
1743
  * Get all available providers for a network, sorted by score
1702
1744
  */
1703
1745
  getAvailableProviders(network) {
1704
- const providers = this.registry.getProvidersForNetwork(network);
1746
+ let providers = this.registry.getProvidersForNetwork(network);
1747
+ if (this.adapter === "browser") {
1748
+ providers = this.filterBrowserCompatible(providers, network);
1749
+ }
1705
1750
  return providers.map((provider) => ({
1706
1751
  provider,
1707
1752
  score: this.scoreProvider(provider, network)
@@ -1711,7 +1756,10 @@ var ProviderSelector = class {
1711
1756
  * Get the next best provider (for failover)
1712
1757
  */
1713
1758
  getNextProvider(network, excludeIds) {
1714
- const providers = this.registry.getProvidersForNetwork(network);
1759
+ let providers = this.registry.getProvidersForNetwork(network);
1760
+ if (this.adapter === "browser") {
1761
+ providers = this.filterBrowserCompatible(providers, network);
1762
+ }
1715
1763
  const available = providers.filter((p) => !excludeIds.includes(p.id)).map((provider) => ({
1716
1764
  provider,
1717
1765
  score: this.scoreProvider(provider, network)
@@ -1902,12 +1950,39 @@ var ProviderSelector = class {
1902
1950
  endpointV2: this.customEndpoint,
1903
1951
  rps: 10,
1904
1952
  priority: 0,
1905
- isDynamic: false
1953
+ isDynamic: false,
1954
+ browserCompatible: true
1955
+ // Custom endpoints are assumed compatible
1906
1956
  };
1907
1957
  }
1958
+ /**
1959
+ * Filter providers to only include browser-compatible ones
1960
+ *
1961
+ * Checks both:
1962
+ * 1. Provider config browserCompatible flag
1963
+ * 2. Health check result browserCompatible flag (if health check was performed)
1964
+ */
1965
+ filterBrowserCompatible(providers, network) {
1966
+ return providers.filter((provider) => {
1967
+ if (!provider.browserCompatible) {
1968
+ this.logger.debug(
1969
+ `Provider ${provider.id} marked as browser-incompatible in config`
1970
+ );
1971
+ return false;
1972
+ }
1973
+ const health = this.healthChecker.getResult(provider.id, network);
1974
+ if (health && health.browserCompatible === false) {
1975
+ this.logger.debug(
1976
+ `Provider ${provider.id} marked as browser-incompatible by health check (CORS error detected)`
1977
+ );
1978
+ return false;
1979
+ }
1980
+ return true;
1981
+ });
1982
+ }
1908
1983
  };
1909
- function createSelector(registry, healthChecker, config, logger) {
1910
- return new ProviderSelector(registry, healthChecker, config, logger);
1984
+ function createSelector(registry, healthChecker, config, logger, adapter = "node") {
1985
+ return new ProviderSelector(registry, healthChecker, config, logger, adapter);
1911
1986
  }
1912
1987
 
1913
1988
  // src/core/manager.ts
@@ -2014,7 +2089,8 @@ var _ProviderManager = class _ProviderManager {
2014
2089
  this.registry,
2015
2090
  this.healthChecker,
2016
2091
  void 0,
2017
- this.options.logger
2092
+ this.options.logger,
2093
+ this.options.adapter
2018
2094
  );
2019
2095
  this.initialized = true;
2020
2096
  this.notifyListeners();
@@ -2281,7 +2357,20 @@ var _ProviderManager = class _ProviderManager {
2281
2357
  */
2282
2358
  getProviders() {
2283
2359
  if (!this.initialized || !this.network) return [];
2284
- return this.registry.getProvidersForNetwork(this.network);
2360
+ let providers = this.registry.getProvidersForNetwork(this.network);
2361
+ if (this.options.adapter === "browser") {
2362
+ providers = providers.filter((provider) => {
2363
+ if (!provider.browserCompatible) {
2364
+ return false;
2365
+ }
2366
+ const health = this.healthChecker.getResult(provider.id, this.network);
2367
+ if (health && health.browserCompatible === false) {
2368
+ return false;
2369
+ }
2370
+ return true;
2371
+ });
2372
+ }
2373
+ return providers;
2285
2374
  }
2286
2375
  /**
2287
2376
  * Get provider health results for current network
@@ -2327,7 +2416,8 @@ var _ProviderManager = class _ProviderManager {
2327
2416
  latencyMs: null,
2328
2417
  seqno: null,
2329
2418
  blocksBehind: 0,
2330
- lastTested: null
2419
+ lastTested: null,
2420
+ browserCompatible: provider.browserCompatible
2331
2421
  },
2332
2422
  rateLimit: rateLimit || {
2333
2423
  tokens: 0,