ton-provider-system 0.4.0 → 0.5.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.cjs +77 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +65 -17
- package/dist/index.d.ts +65 -17
- package/dist/index.js +77 -41
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/rpc-schema.json +5 -0
- package/rpc.json +6 -3
package/dist/index.cjs
CHANGED
|
@@ -72,6 +72,7 @@ var ProviderConfigSchema = zod.z.object({
|
|
|
72
72
|
enabled: zod.z.boolean().default(true),
|
|
73
73
|
isDynamic: zod.z.boolean().optional().default(false),
|
|
74
74
|
browserCompatible: zod.z.boolean().optional(),
|
|
75
|
+
servesGetTransactions: zod.z.boolean().optional(),
|
|
75
76
|
description: zod.z.string().optional()
|
|
76
77
|
});
|
|
77
78
|
var NetworkDefaultsSchema = zod.z.object({
|
|
@@ -220,7 +221,10 @@ function resolveProvider(id, config) {
|
|
|
220
221
|
rps: config.rps,
|
|
221
222
|
priority: config.priority,
|
|
222
223
|
isDynamic: config.isDynamic || false,
|
|
223
|
-
browserCompatible: config.browserCompatible !== void 0 ? config.browserCompatible : true
|
|
224
|
+
browserCompatible: config.browserCompatible !== void 0 ? config.browserCompatible : true,
|
|
225
|
+
// Default true: a provider is assumed to serve getTransactions unless the
|
|
226
|
+
// config explicitly opts out (e.g. Chainstack/Orbs testnet liteserver proxies).
|
|
227
|
+
servesGetTransactions: config.servesGetTransactions !== false
|
|
224
228
|
};
|
|
225
229
|
}
|
|
226
230
|
function resolveAllProviders(config) {
|
|
@@ -2554,8 +2558,10 @@ var ProviderSelector = class {
|
|
|
2554
2558
|
rps: 10,
|
|
2555
2559
|
priority: 0,
|
|
2556
2560
|
isDynamic: false,
|
|
2557
|
-
browserCompatible: true
|
|
2561
|
+
browserCompatible: true,
|
|
2558
2562
|
// Custom endpoints are assumed compatible
|
|
2563
|
+
servesGetTransactions: true
|
|
2564
|
+
// Custom endpoints are assumed fully capable
|
|
2559
2565
|
};
|
|
2560
2566
|
}
|
|
2561
2567
|
/**
|
|
@@ -2886,26 +2892,39 @@ var _ProviderManager = class _ProviderManager {
|
|
|
2886
2892
|
// ========================================================================
|
|
2887
2893
|
/**
|
|
2888
2894
|
* Report a successful request
|
|
2895
|
+
*
|
|
2896
|
+
* @param providerId - Optionally attribute the success to a SPECIFIC provider
|
|
2897
|
+
* (used by callers that drive their own candidate list, e.g.
|
|
2898
|
+
* NodeAdapter.getTransactions, where the provider used is not necessarily the
|
|
2899
|
+
* selector's current best). Defaults to the current best provider.
|
|
2889
2900
|
*/
|
|
2890
|
-
reportSuccess() {
|
|
2901
|
+
reportSuccess(providerId) {
|
|
2891
2902
|
if (!this.initialized || !this.network) return;
|
|
2892
|
-
const
|
|
2893
|
-
if (
|
|
2894
|
-
this.rateLimiter.reportSuccess(
|
|
2903
|
+
const id = providerId ?? this.selector.getBestProvider(this.network)?.id;
|
|
2904
|
+
if (id) {
|
|
2905
|
+
this.rateLimiter.reportSuccess(id);
|
|
2895
2906
|
}
|
|
2896
2907
|
}
|
|
2897
2908
|
/**
|
|
2898
2909
|
* Report an error (triggers provider switch if needed)
|
|
2910
|
+
*
|
|
2911
|
+
* @param providerId - Optionally attribute the error to a SPECIFIC provider
|
|
2912
|
+
* (used by callers that drive their own candidate list, e.g.
|
|
2913
|
+
* NodeAdapter.getTransactions). Defaults to the current active/best provider.
|
|
2899
2914
|
*/
|
|
2900
|
-
reportError(error) {
|
|
2915
|
+
reportError(error, providerId) {
|
|
2901
2916
|
if (!this.initialized || !this.network) return;
|
|
2902
|
-
const activeProviderId = this.selector.getActiveProviderId(this.network);
|
|
2903
2917
|
let provider = null;
|
|
2904
|
-
if (
|
|
2905
|
-
provider = this.registry.getProvider(
|
|
2906
|
-
}
|
|
2907
|
-
|
|
2908
|
-
|
|
2918
|
+
if (providerId) {
|
|
2919
|
+
provider = this.registry.getProvider(providerId) || null;
|
|
2920
|
+
} else {
|
|
2921
|
+
const activeProviderId = this.selector.getActiveProviderId(this.network);
|
|
2922
|
+
if (activeProviderId) {
|
|
2923
|
+
provider = this.registry.getProvider(activeProviderId) || null;
|
|
2924
|
+
}
|
|
2925
|
+
if (!provider) {
|
|
2926
|
+
provider = this.selector.getBestProvider(this.network);
|
|
2927
|
+
}
|
|
2909
2928
|
}
|
|
2910
2929
|
if (!provider) {
|
|
2911
2930
|
this.options.logger.warn(`Cannot report error: no provider available for ${this.network}`);
|
|
@@ -3035,6 +3054,21 @@ var _ProviderManager = class _ProviderManager {
|
|
|
3035
3054
|
}
|
|
3036
3055
|
return providers;
|
|
3037
3056
|
}
|
|
3057
|
+
/**
|
|
3058
|
+
* Get transaction-capable providers for the current network, in selector
|
|
3059
|
+
* score order (best first).
|
|
3060
|
+
*
|
|
3061
|
+
* Read-only: enumerates the score-ordered available providers and excludes any
|
|
3062
|
+
* flagged `servesGetTransactions: false` (Chainstack/Orbs testnet liteserver
|
|
3063
|
+
* proxies, which 403 on v2 getTransactions). Used by
|
|
3064
|
+
* NodeAdapter.getTransactions to build its candidate set WITHOUT poisoning the
|
|
3065
|
+
* incapable providers' global health — so the get-method path keeps using them.
|
|
3066
|
+
* Returns [] when no capable provider is currently selectable.
|
|
3067
|
+
*/
|
|
3068
|
+
getTransactionCapableProviders() {
|
|
3069
|
+
if (!this.initialized || !this.network) return [];
|
|
3070
|
+
return this.selector.getAvailableProviders(this.network).filter((p) => p.servesGetTransactions !== false);
|
|
3071
|
+
}
|
|
3038
3072
|
/**
|
|
3039
3073
|
* Get provider health results for current network
|
|
3040
3074
|
*/
|
|
@@ -3253,24 +3287,27 @@ var NodeAdapter = class {
|
|
|
3253
3287
|
// Failover-aware high-level reads
|
|
3254
3288
|
// ========================================================================
|
|
3255
3289
|
/**
|
|
3256
|
-
* Get account transactions with provider failover.
|
|
3290
|
+
* Get account transactions with capability-aware provider failover.
|
|
3257
3291
|
*
|
|
3258
|
-
* Unlike `getClient().getTransactions(...)`, this
|
|
3259
|
-
*
|
|
3260
|
-
*
|
|
3261
|
-
*
|
|
3292
|
+
* Unlike `getClient().getTransactions(...)`, this builds a candidate set of the
|
|
3293
|
+
* network's *transaction-capable* providers (score-ordered, best first) and
|
|
3294
|
+
* loops over THAT set. Providers known not to serve the v2 `getTransactions`
|
|
3295
|
+
* shape — flagged `servesGetTransactions: false` in config (Chainstack/Orbs
|
|
3296
|
+
* testnet, which pass the `getMasterchainInfo` health probe but 403 on
|
|
3297
|
+
* transaction reads) — are excluded UP FRONT. They are never called and never
|
|
3298
|
+
* `reportError`-ed here, so their global health stays intact and the fast
|
|
3299
|
+
* get-method path keeps using them (a wasted 403 would otherwise evict them).
|
|
3262
3300
|
*
|
|
3263
|
-
* Semantics:
|
|
3264
|
-
* 1.
|
|
3265
|
-
* 2. Acquire a rate-limit token for THAT provider, bind a short-lived
|
|
3301
|
+
* Semantics (per capable candidate, in score order):
|
|
3302
|
+
* 1. Acquire a rate-limit token for THAT provider, bind a short-lived
|
|
3266
3303
|
* `TonClient` to its endpoint, and call `getTransactions`.
|
|
3267
|
-
*
|
|
3268
|
-
*
|
|
3269
|
-
*
|
|
3270
|
-
*
|
|
3271
|
-
*
|
|
3272
|
-
* caller's retry/dead-letter logic still triggers
|
|
3273
|
-
*
|
|
3304
|
+
* 2. On success → `reportSuccess(provider.id)` and return.
|
|
3305
|
+
* 3. On a GENUINE error → `reportError(error, provider.id)` (marks THAT
|
|
3306
|
+
* provider success:false + clears the selection cache) and try the next
|
|
3307
|
+
* capable candidate.
|
|
3308
|
+
* 4. When every capable candidate has been tried, re-throw the last error so
|
|
3309
|
+
* the caller's retry/dead-letter logic still triggers.
|
|
3310
|
+
* 5. If there is NO capable provider at all, throw a clear error.
|
|
3274
3311
|
*
|
|
3275
3312
|
* Returns the same `Transaction[]` `TonClient.getTransactions` returns, so a
|
|
3276
3313
|
* consumer can swap `client.getTransactions(addr, opts)` for
|
|
@@ -3283,28 +3320,27 @@ var NodeAdapter = class {
|
|
|
3283
3320
|
}
|
|
3284
3321
|
const addr = typeof address === "string" ? core.Address.parse(address) : address;
|
|
3285
3322
|
const reqOpts = { limit: opts.limit ?? 20, ...opts };
|
|
3286
|
-
const
|
|
3323
|
+
const candidates = this.manager.getTransactionCapableProviders();
|
|
3324
|
+
if (candidates.length === 0) {
|
|
3325
|
+
throw new Error(
|
|
3326
|
+
`getTransactions: no transaction-capable provider for ${network}`
|
|
3327
|
+
);
|
|
3328
|
+
}
|
|
3287
3329
|
const rateLimiter = this.manager.getRateLimiter();
|
|
3288
|
-
const tried = /* @__PURE__ */ new Set();
|
|
3289
3330
|
let lastError;
|
|
3290
|
-
for (
|
|
3291
|
-
const provider = this.manager.getActiveProvider();
|
|
3292
|
-
if (!provider) break;
|
|
3293
|
-
if (tried.has(provider.id)) break;
|
|
3294
|
-
tried.add(provider.id);
|
|
3331
|
+
for (const provider of candidates) {
|
|
3295
3332
|
if (rateLimiter) {
|
|
3296
3333
|
await rateLimiter.acquire(provider.id, timeoutMs);
|
|
3297
3334
|
}
|
|
3298
|
-
const endpoint =
|
|
3299
|
-
const
|
|
3300
|
-
const client = new ton.TonClient({ endpoint, apiKey });
|
|
3335
|
+
const endpoint = normalizeV2Endpoint(provider.endpointV2, provider);
|
|
3336
|
+
const client = new ton.TonClient({ endpoint, apiKey: provider.apiKey });
|
|
3301
3337
|
try {
|
|
3302
3338
|
const result = await withTimeout(
|
|
3303
3339
|
client.getTransactions(addr, reqOpts),
|
|
3304
3340
|
timeoutMs,
|
|
3305
3341
|
`getTransactions(${provider.id})`
|
|
3306
3342
|
);
|
|
3307
|
-
this.manager.reportSuccess();
|
|
3343
|
+
this.manager.reportSuccess(provider.id);
|
|
3308
3344
|
return result;
|
|
3309
3345
|
} catch (error) {
|
|
3310
3346
|
lastError = error;
|
|
@@ -3312,10 +3348,10 @@ var NodeAdapter = class {
|
|
|
3312
3348
|
`getTransactions failed on ${provider.id}, failing over`,
|
|
3313
3349
|
{ error: error?.message || String(error) }
|
|
3314
3350
|
);
|
|
3315
|
-
this.manager.reportError(error);
|
|
3351
|
+
this.manager.reportError(error, provider.id);
|
|
3316
3352
|
}
|
|
3317
3353
|
}
|
|
3318
|
-
throw lastError || new Error(`getTransactions:
|
|
3354
|
+
throw lastError || new Error(`getTransactions: all transaction-capable providers failed for ${network}`);
|
|
3319
3355
|
}
|
|
3320
3356
|
// ========================================================================
|
|
3321
3357
|
// Direct REST API Methods
|