@sip-protocol/sdk 0.7.3 → 0.8.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/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +47556 -19603
- package/dist/browser.mjs +628 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
- package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48396 -19623
- package/dist/index.mjs +537 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +44 -11
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +252 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +47 -6
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +186 -33
- package/src/chains/solana/providers/index.ts +31 -0
- package/src/chains/solana/providers/interface.ts +61 -18
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +338 -67
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +83 -66
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +57 -6
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +23 -0
- package/src/compliance/range-sas.ts +398 -33
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +686 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +254 -4
- package/src/privacy-backends/interface.ts +649 -6
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash.ts +13 -17
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +414 -2
- package/src/privacy-backends/router.ts +283 -3
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +3 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +110 -29
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-2XIVXWHA.mjs +0 -1930
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-7RFRWDCW.mjs +0 -1504
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-F6F73W35.mjs +0 -16166
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-OFDBEIEK.mjs +0 -16166
- package/dist/chunk-SF7YSLF5.mjs +0 -1515
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/chunk-WWUSGOXE.mjs +0 -17129
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-B71aXVzk.d.ts +0 -13264
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-pOIIuwfV.d.mts +0 -13264
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-4O4K45VU.mjs +0 -46
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-NDABAZ6P.mjs +0 -56
- package/dist/solana-Q4NAVBTS.mjs +0 -46
- package/dist/solana-ZYO63LY5.mjs +0 -46
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Privacy Backend Registry
|
|
3
3
|
*
|
|
4
4
|
* Manages registration and discovery of privacy backends.
|
|
5
|
+
* Optionally integrates with BackendHealthTracker for circuit breaker support.
|
|
5
6
|
*
|
|
6
7
|
* @example
|
|
7
8
|
* ```typescript
|
|
@@ -16,6 +17,10 @@
|
|
|
16
17
|
* const byName = registry.get('sip-native')
|
|
17
18
|
* const forChain = registry.getByChain('solana')
|
|
18
19
|
* const forType = registry.getByType('transaction')
|
|
20
|
+
*
|
|
21
|
+
* // Health-aware operations (when health tracker is attached)
|
|
22
|
+
* const healthy = registry.getHealthy()
|
|
23
|
+
* const health = registry.getHealthState('sip-native')
|
|
19
24
|
* ```
|
|
20
25
|
*/
|
|
21
26
|
|
|
@@ -27,21 +32,118 @@ import type {
|
|
|
27
32
|
RegisteredBackend,
|
|
28
33
|
TransferParams,
|
|
29
34
|
AvailabilityResult,
|
|
35
|
+
BackendHealthState,
|
|
36
|
+
BackendMetrics,
|
|
37
|
+
CircuitBreakerConfig,
|
|
30
38
|
} from './interface'
|
|
39
|
+
import { warnIfDeprecatedVersion } from './interface'
|
|
40
|
+
import { BackendHealthTracker } from './health'
|
|
41
|
+
import { RateLimiter, type RateLimiterConfig, type RateLimitStats, type AcquireOptions } from './rate-limiter'
|
|
31
42
|
|
|
32
43
|
/**
|
|
33
44
|
* Default priority for registered backends
|
|
34
45
|
*/
|
|
35
46
|
const DEFAULT_PRIORITY = 50
|
|
36
47
|
|
|
48
|
+
/**
|
|
49
|
+
* Registry configuration options
|
|
50
|
+
*/
|
|
51
|
+
export interface PrivacyBackendRegistryConfig {
|
|
52
|
+
/**
|
|
53
|
+
* Enable health tracking with circuit breaker
|
|
54
|
+
* @default true
|
|
55
|
+
*/
|
|
56
|
+
enableHealthTracking?: boolean
|
|
57
|
+
/**
|
|
58
|
+
* Circuit breaker configuration (when health tracking is enabled)
|
|
59
|
+
*/
|
|
60
|
+
circuitBreakerConfig?: Partial<CircuitBreakerConfig>
|
|
61
|
+
/**
|
|
62
|
+
* Enable rate limiting for backends
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
enableRateLimiting?: boolean
|
|
66
|
+
/**
|
|
67
|
+
* Rate limiter configuration (when rate limiting is enabled)
|
|
68
|
+
*/
|
|
69
|
+
rateLimiterConfig?: RateLimiterConfig
|
|
70
|
+
}
|
|
71
|
+
|
|
37
72
|
/**
|
|
38
73
|
* Registry for managing privacy backends
|
|
39
74
|
*
|
|
40
75
|
* Provides a centralized way to register, discover, and manage
|
|
41
|
-
* different privacy backend implementations.
|
|
76
|
+
* different privacy backend implementations. Optionally integrates
|
|
77
|
+
* with BackendHealthTracker for circuit breaker support.
|
|
42
78
|
*/
|
|
43
79
|
export class PrivacyBackendRegistry {
|
|
44
80
|
private backends: Map<string, RegisteredBackend> = new Map()
|
|
81
|
+
private healthTracker: BackendHealthTracker | null = null
|
|
82
|
+
private rateLimiter: RateLimiter | null = null
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Create a new registry
|
|
86
|
+
*
|
|
87
|
+
* @param config - Registry configuration
|
|
88
|
+
*/
|
|
89
|
+
constructor(config: PrivacyBackendRegistryConfig = {}) {
|
|
90
|
+
const {
|
|
91
|
+
enableHealthTracking = true,
|
|
92
|
+
circuitBreakerConfig,
|
|
93
|
+
enableRateLimiting = false,
|
|
94
|
+
rateLimiterConfig,
|
|
95
|
+
} = config
|
|
96
|
+
|
|
97
|
+
if (enableHealthTracking) {
|
|
98
|
+
this.healthTracker = new BackendHealthTracker(circuitBreakerConfig)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (enableRateLimiting) {
|
|
102
|
+
this.rateLimiter = new RateLimiter(rateLimiterConfig)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get the health tracker instance
|
|
108
|
+
*
|
|
109
|
+
* @returns Health tracker or null if not enabled
|
|
110
|
+
*/
|
|
111
|
+
getHealthTracker(): BackendHealthTracker | null {
|
|
112
|
+
return this.healthTracker
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Attach an external health tracker
|
|
117
|
+
*
|
|
118
|
+
* Useful for sharing a health tracker between multiple registries
|
|
119
|
+
* or for testing.
|
|
120
|
+
*
|
|
121
|
+
* @param tracker - Health tracker to attach
|
|
122
|
+
*/
|
|
123
|
+
setHealthTracker(tracker: BackendHealthTracker | null): void {
|
|
124
|
+
this.healthTracker = tracker
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Get the rate limiter instance
|
|
129
|
+
*
|
|
130
|
+
* @returns Rate limiter or null if not enabled
|
|
131
|
+
*/
|
|
132
|
+
getRateLimiter(): RateLimiter | null {
|
|
133
|
+
return this.rateLimiter
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Attach an external rate limiter
|
|
138
|
+
*
|
|
139
|
+
* Useful for sharing a rate limiter between multiple registries
|
|
140
|
+
* or for testing.
|
|
141
|
+
*
|
|
142
|
+
* @param limiter - Rate limiter to attach
|
|
143
|
+
*/
|
|
144
|
+
setRateLimiter(limiter: RateLimiter | null): void {
|
|
145
|
+
this.rateLimiter = limiter
|
|
146
|
+
}
|
|
45
147
|
|
|
46
148
|
/**
|
|
47
149
|
* Register a privacy backend
|
|
@@ -69,12 +171,20 @@ export class PrivacyBackendRegistry {
|
|
|
69
171
|
)
|
|
70
172
|
}
|
|
71
173
|
|
|
174
|
+
// Warn about deprecated interface versions
|
|
175
|
+
warnIfDeprecatedVersion(backend)
|
|
176
|
+
|
|
72
177
|
this.backends.set(backend.name, {
|
|
73
178
|
backend,
|
|
74
179
|
priority,
|
|
75
180
|
enabled,
|
|
76
181
|
registeredAt: Date.now(),
|
|
77
182
|
})
|
|
183
|
+
|
|
184
|
+
// Register with health tracker if enabled
|
|
185
|
+
if (this.healthTracker) {
|
|
186
|
+
this.healthTracker.register(backend.name)
|
|
187
|
+
}
|
|
78
188
|
}
|
|
79
189
|
|
|
80
190
|
/**
|
|
@@ -84,7 +194,11 @@ export class PrivacyBackendRegistry {
|
|
|
84
194
|
* @returns true if backend was removed, false if not found
|
|
85
195
|
*/
|
|
86
196
|
unregister(name: string): boolean {
|
|
87
|
-
|
|
197
|
+
const removed = this.backends.delete(name)
|
|
198
|
+
if (removed && this.healthTracker) {
|
|
199
|
+
this.healthTracker.unregister(name)
|
|
200
|
+
}
|
|
201
|
+
return removed
|
|
88
202
|
}
|
|
89
203
|
|
|
90
204
|
/**
|
|
@@ -251,6 +365,9 @@ export class PrivacyBackendRegistry {
|
|
|
251
365
|
*/
|
|
252
366
|
clear(): void {
|
|
253
367
|
this.backends.clear()
|
|
368
|
+
if (this.healthTracker) {
|
|
369
|
+
this.healthTracker.clear()
|
|
370
|
+
}
|
|
254
371
|
}
|
|
255
372
|
|
|
256
373
|
/**
|
|
@@ -267,6 +384,301 @@ export class PrivacyBackendRegistry {
|
|
|
267
384
|
}
|
|
268
385
|
return Array.from(this.backends.keys())
|
|
269
386
|
}
|
|
387
|
+
|
|
388
|
+
// ─── Health-Aware Methods ───────────────────────────────────────────────────
|
|
389
|
+
|
|
390
|
+
/**
|
|
391
|
+
* Get all healthy backends (circuit not open)
|
|
392
|
+
*
|
|
393
|
+
* Filters out backends where the circuit breaker is open.
|
|
394
|
+
* Falls back to getAll() if health tracking is disabled.
|
|
395
|
+
*
|
|
396
|
+
* @returns Array of healthy backends
|
|
397
|
+
*/
|
|
398
|
+
getHealthy(): PrivacyBackend[] {
|
|
399
|
+
const all = this.getAll()
|
|
400
|
+
if (!this.healthTracker) {
|
|
401
|
+
return all
|
|
402
|
+
}
|
|
403
|
+
return all.filter(backend => this.healthTracker!.isHealthy(backend.name))
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Get healthy backends supporting a specific chain
|
|
408
|
+
*
|
|
409
|
+
* @param chain - Chain type to filter by
|
|
410
|
+
* @returns Array of healthy backends supporting the chain
|
|
411
|
+
*/
|
|
412
|
+
getHealthyByChain(chain: ChainType): PrivacyBackend[] {
|
|
413
|
+
return this.getHealthy().filter(backend => backend.chains.includes(chain))
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Get health state for a backend
|
|
418
|
+
*
|
|
419
|
+
* @param name - Backend name
|
|
420
|
+
* @returns Health state or undefined if not tracked
|
|
421
|
+
*/
|
|
422
|
+
getHealthState(name: string): BackendHealthState | undefined {
|
|
423
|
+
return this.healthTracker?.getHealth(name)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Get metrics for a backend
|
|
428
|
+
*
|
|
429
|
+
* @param name - Backend name
|
|
430
|
+
* @returns Metrics or undefined if not tracked
|
|
431
|
+
*/
|
|
432
|
+
getMetrics(name: string): BackendMetrics | undefined {
|
|
433
|
+
return this.healthTracker?.getMetrics(name)
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Get summary of all backend health
|
|
438
|
+
*
|
|
439
|
+
* @returns Object with backend names as keys and health info as values
|
|
440
|
+
*/
|
|
441
|
+
getHealthSummary(): Record<string, {
|
|
442
|
+
healthy: boolean
|
|
443
|
+
state: string
|
|
444
|
+
failures: number
|
|
445
|
+
lastError?: string
|
|
446
|
+
}> {
|
|
447
|
+
if (!this.healthTracker) {
|
|
448
|
+
// Return all backends as healthy when tracking is disabled
|
|
449
|
+
const summary: Record<string, {
|
|
450
|
+
healthy: boolean
|
|
451
|
+
state: string
|
|
452
|
+
failures: number
|
|
453
|
+
}> = {}
|
|
454
|
+
for (const name of this.getNames()) {
|
|
455
|
+
summary[name] = { healthy: true, state: 'closed', failures: 0 }
|
|
456
|
+
}
|
|
457
|
+
return summary
|
|
458
|
+
}
|
|
459
|
+
return this.healthTracker.getHealthSummary()
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Check if a backend is healthy
|
|
464
|
+
*
|
|
465
|
+
* @param name - Backend name
|
|
466
|
+
* @returns true if healthy or health tracking is disabled
|
|
467
|
+
*/
|
|
468
|
+
isHealthy(name: string): boolean {
|
|
469
|
+
if (!this.healthTracker) {
|
|
470
|
+
return true
|
|
471
|
+
}
|
|
472
|
+
return this.healthTracker.isHealthy(name)
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Manually open circuit for a backend
|
|
477
|
+
*
|
|
478
|
+
* Useful for maintenance or known issues.
|
|
479
|
+
*
|
|
480
|
+
* @param name - Backend name
|
|
481
|
+
* @returns true if circuit was opened, false if not found or tracking disabled
|
|
482
|
+
*/
|
|
483
|
+
openCircuit(name: string): boolean {
|
|
484
|
+
if (!this.healthTracker || !this.backends.has(name)) {
|
|
485
|
+
return false
|
|
486
|
+
}
|
|
487
|
+
this.healthTracker.forceOpen(name)
|
|
488
|
+
return true
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Manually close circuit for a backend
|
|
493
|
+
*
|
|
494
|
+
* Use with caution - may route requests to failing backend.
|
|
495
|
+
*
|
|
496
|
+
* @param name - Backend name
|
|
497
|
+
* @returns true if circuit was closed, false if not found or tracking disabled
|
|
498
|
+
*/
|
|
499
|
+
closeCircuit(name: string): boolean {
|
|
500
|
+
if (!this.healthTracker || !this.backends.has(name)) {
|
|
501
|
+
return false
|
|
502
|
+
}
|
|
503
|
+
this.healthTracker.forceClose(name)
|
|
504
|
+
return true
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* Reset health state for a backend
|
|
509
|
+
*
|
|
510
|
+
* Clears failure count and closes circuit.
|
|
511
|
+
*
|
|
512
|
+
* @param name - Backend name
|
|
513
|
+
* @returns true if reset, false if not found or tracking disabled
|
|
514
|
+
*/
|
|
515
|
+
resetHealth(name: string): boolean {
|
|
516
|
+
if (!this.healthTracker || !this.backends.has(name)) {
|
|
517
|
+
return false
|
|
518
|
+
}
|
|
519
|
+
this.healthTracker.reset(name)
|
|
520
|
+
return true
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
/**
|
|
524
|
+
* Record a successful execution for a backend
|
|
525
|
+
*
|
|
526
|
+
* @param name - Backend name
|
|
527
|
+
* @param latencyMs - Request latency in milliseconds
|
|
528
|
+
*/
|
|
529
|
+
recordSuccess(name: string, latencyMs: number): void {
|
|
530
|
+
if (this.healthTracker) {
|
|
531
|
+
this.healthTracker.recordSuccess(name, latencyMs)
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
/**
|
|
536
|
+
* Record a failed execution for a backend
|
|
537
|
+
*
|
|
538
|
+
* @param name - Backend name
|
|
539
|
+
* @param reason - Failure reason
|
|
540
|
+
*/
|
|
541
|
+
recordFailure(name: string, reason: string): void {
|
|
542
|
+
if (this.healthTracker) {
|
|
543
|
+
this.healthTracker.recordFailure(name, reason)
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// ─── Rate Limiting Methods ─────────────────────────────────────────────────
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
* Try to acquire rate limit tokens for a backend (non-blocking)
|
|
551
|
+
*
|
|
552
|
+
* @param name - Backend name
|
|
553
|
+
* @param tokens - Number of tokens to acquire (default: 1)
|
|
554
|
+
* @returns true if tokens were acquired, false if rate limited or limiter disabled
|
|
555
|
+
*/
|
|
556
|
+
tryAcquire(name: string, tokens: number = 1): boolean {
|
|
557
|
+
if (!this.rateLimiter) {
|
|
558
|
+
return true // No rate limiting enabled
|
|
559
|
+
}
|
|
560
|
+
return this.rateLimiter.tryAcquire(name, tokens)
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Acquire rate limit tokens for a backend (async with queueing)
|
|
565
|
+
*
|
|
566
|
+
* @param name - Backend name
|
|
567
|
+
* @param options - Acquire options (tokens, timeout)
|
|
568
|
+
* @returns Promise resolving when tokens are acquired
|
|
569
|
+
* @throws RateLimitExceededError, QueueFullError, or AcquireTimeoutError
|
|
570
|
+
*/
|
|
571
|
+
async acquire(name: string, options?: AcquireOptions): Promise<void> {
|
|
572
|
+
if (!this.rateLimiter) {
|
|
573
|
+
return // No rate limiting enabled
|
|
574
|
+
}
|
|
575
|
+
await this.rateLimiter.acquire(name, options)
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/**
|
|
579
|
+
* Check if tokens can be acquired without consuming them
|
|
580
|
+
*
|
|
581
|
+
* @param name - Backend name
|
|
582
|
+
* @param tokens - Number of tokens to check (default: 1)
|
|
583
|
+
* @returns true if tokens are available
|
|
584
|
+
*/
|
|
585
|
+
canAcquire(name: string, tokens: number = 1): boolean {
|
|
586
|
+
if (!this.rateLimiter) {
|
|
587
|
+
return true // No rate limiting enabled
|
|
588
|
+
}
|
|
589
|
+
return this.rateLimiter.canAcquire(name, tokens)
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Get rate limit statistics for a backend
|
|
594
|
+
*
|
|
595
|
+
* @param name - Backend name
|
|
596
|
+
* @returns Rate limit stats or undefined if limiter disabled
|
|
597
|
+
*/
|
|
598
|
+
getRateLimitStats(name: string): RateLimitStats | undefined {
|
|
599
|
+
return this.rateLimiter?.getStats(name)
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Check if a backend is rate limited (no tokens available)
|
|
604
|
+
*
|
|
605
|
+
* @param name - Backend name
|
|
606
|
+
* @returns true if rate limited, false if available or limiter disabled
|
|
607
|
+
*/
|
|
608
|
+
isRateLimited(name: string): boolean {
|
|
609
|
+
if (!this.rateLimiter) {
|
|
610
|
+
return false
|
|
611
|
+
}
|
|
612
|
+
return !this.rateLimiter.canAcquire(name)
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Get all backends that are NOT rate limited
|
|
617
|
+
*
|
|
618
|
+
* @returns Array of backends with available rate limit tokens
|
|
619
|
+
*/
|
|
620
|
+
getAvailable(): PrivacyBackend[] {
|
|
621
|
+
const all = this.getAll()
|
|
622
|
+
if (!this.rateLimiter) {
|
|
623
|
+
return all
|
|
624
|
+
}
|
|
625
|
+
return all.filter(backend => this.rateLimiter!.canAcquire(backend.name))
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
/**
|
|
629
|
+
* Get available backends for a specific chain
|
|
630
|
+
*
|
|
631
|
+
* Filters by both chain support and rate limit availability.
|
|
632
|
+
*
|
|
633
|
+
* @param chain - Chain type to filter by
|
|
634
|
+
* @returns Array of available backends supporting the chain
|
|
635
|
+
*/
|
|
636
|
+
getAvailableByChain(chain: ChainType): PrivacyBackend[] {
|
|
637
|
+
return this.getAvailable().filter(backend => backend.chains.includes(chain))
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Get backends that are both healthy AND not rate limited
|
|
642
|
+
*
|
|
643
|
+
* @returns Array of backends ready for use
|
|
644
|
+
*/
|
|
645
|
+
getReady(): PrivacyBackend[] {
|
|
646
|
+
const healthy = this.getHealthy()
|
|
647
|
+
if (!this.rateLimiter) {
|
|
648
|
+
return healthy
|
|
649
|
+
}
|
|
650
|
+
return healthy.filter(backend => this.rateLimiter!.canAcquire(backend.name))
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Get ready backends for a specific chain
|
|
655
|
+
*
|
|
656
|
+
* @param chain - Chain type to filter by
|
|
657
|
+
* @returns Array of ready backends supporting the chain
|
|
658
|
+
*/
|
|
659
|
+
getReadyByChain(chain: ChainType): PrivacyBackend[] {
|
|
660
|
+
return this.getReady().filter(backend => backend.chains.includes(chain))
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Reset rate limit state for a backend
|
|
665
|
+
*
|
|
666
|
+
* Refills bucket to max tokens and clears stats.
|
|
667
|
+
*
|
|
668
|
+
* @param name - Backend name
|
|
669
|
+
*/
|
|
670
|
+
resetRateLimit(name: string): void {
|
|
671
|
+
this.rateLimiter?.reset(name)
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
/**
|
|
675
|
+
* Dispose rate limiter resources
|
|
676
|
+
*
|
|
677
|
+
* Call when shutting down to clean up queue processing intervals.
|
|
678
|
+
*/
|
|
679
|
+
disposeRateLimiter(): void {
|
|
680
|
+
this.rateLimiter?.dispose()
|
|
681
|
+
}
|
|
270
682
|
}
|
|
271
683
|
|
|
272
684
|
/**
|