@orbinum/sdk 0.7.7 → 0.7.9

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.mts CHANGED
@@ -653,6 +653,7 @@ interface IndexerStats {
653
653
  };
654
654
  extrinsics: {
655
655
  total: number;
656
+ signed: number;
656
657
  };
657
658
  evm: {
658
659
  transactions: number;
@@ -671,6 +672,19 @@ interface IndexerStats {
671
672
  successful: number;
672
673
  };
673
674
  }
675
+ /** One hour-bucket of transaction activity from `/stats/activity`. */
676
+ interface ActivityBucket {
677
+ hourStartMs: number;
678
+ transactions: number;
679
+ signedExtrinsics: number;
680
+ evmTransactions: number;
681
+ }
682
+ /** Transaction activity bucketed per hour over the last N hours of chain time. */
683
+ interface IndexerActivity {
684
+ hours: number;
685
+ anchorMs: number | null;
686
+ buckets: ActivityBucket[];
687
+ }
674
688
  /** A registered relayer stored by the indexer. */
675
689
  interface Relayer {
676
690
  evmAddress: string;
@@ -928,6 +942,11 @@ declare class IndexerClient {
928
942
  }): Promise<PaginatedResult<IndexedSession>>;
929
943
  /** Returns aggregated indexer statistics. */
930
944
  getStats(): Promise<IndexerStats>;
945
+ /**
946
+ * Returns transaction activity bucketed per hour over the last `hours` hours
947
+ * of chain time (default 24, max 168). For sparklines / activity charts.
948
+ */
949
+ getActivity(hours?: number): Promise<IndexerActivity>;
931
950
  /** Returns true if the indexer health endpoint responds OK. */
932
951
  isHealthy(): Promise<boolean>;
933
952
  }
@@ -2054,6 +2073,13 @@ interface ClientProviderConfig {
2054
2073
  reconnectBaseMs?: number;
2055
2074
  /** Maximum reconnect delay cap in milliseconds. Default: `30_000`. */
2056
2075
  reconnectMaxMs?: number;
2076
+ /**
2077
+ * How long a connection must stay live before the reconnect backoff is reset
2078
+ * to base, in milliseconds. Prevents a flapping node (connect → drop →
2079
+ * connect) from resetting the backoff on every brief connect and hammering
2080
+ * the node every `reconnectBaseMs`. Default: `10_000`.
2081
+ */
2082
+ stableAfterMs?: number;
2057
2083
  }
2058
2084
  /**
2059
2085
  * Manages the lifecycle of an `OrbinumClient` with heartbeat monitoring,
@@ -2081,11 +2107,13 @@ declare class OrbinumClientProvider {
2081
2107
  private readonly heartbeatTimeoutMs;
2082
2108
  private readonly reconnectBaseMs;
2083
2109
  private readonly reconnectMaxMs;
2110
+ private readonly stableAfterMs;
2084
2111
  private _status;
2085
2112
  private _orbinumClient;
2086
2113
  private _connectingPromise;
2087
2114
  private _heartbeatTimer;
2088
2115
  private _reconnectTimer;
2116
+ private _stableTimer;
2089
2117
  private _reconnectAttempt;
2090
2118
  private _listeners;
2091
2119
  /** Creates a new provider with the given configuration. Does not connect automatically — call `connect()` to initiate. */
@@ -2126,9 +2154,20 @@ declare class OrbinumClientProvider {
2126
2154
  * Returns `true` if the node responds in time, `false` otherwise.
2127
2155
  */
2128
2156
  private probe;
2157
+ /**
2158
+ * After a successful connect, wait `stableAfterMs` before resetting the
2159
+ * backoff. If the connection survives that long it's considered stable and
2160
+ * the next drop starts from base delay again; if it drops sooner the backoff
2161
+ * keeps growing, so a flapping node backs off instead of hammering.
2162
+ */
2163
+ private startStableTimer;
2164
+ /** Clears the stability timer if active (on disconnect/teardown/reset). */
2165
+ private stopStableTimer;
2129
2166
  /**
2130
2167
  * Schedules the next connection attempt using exponential backoff
2131
- * (capped at `reconnectMaxMs`), then transitions to `'reconnecting'`.
2168
+ * (capped at `reconnectMaxMs`) with full jitter, then transitions to
2169
+ * `'reconnecting'`. Jitter (a random fraction of the delay) spreads out
2170
+ * reconnects so many clients don't retry in lockstep after a shared outage.
2132
2171
  */
2133
2172
  private scheduleReconnect;
2134
2173
  /** Clears any pending reconnect timer without triggering a new attempt. */
@@ -4428,4 +4467,4 @@ interface ExtrinsicFailedData {
4428
4467
  dispatch_info: DispatchInfo;
4429
4468
  }
4430
4469
 
4431
- export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, type IndexedBlock, type IndexedEvmTx, type IndexedExtrinsic, type IndexedSession, type IndexedValidator, IndexerClient, type IndexerClientConfig, type IndexerStats, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, type MerkleRoot, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifierStatusResult, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, type PaginatedResult, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type PrivateTransferTimestamp, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RegisteredAsset, type RelayFeeEvent, type RelayFeeSummaryEntry, type Relayer, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, type ScanCommitment, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedAddressEvent, type ShieldedCommitment, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type SpentNullifier, type StatusChangeEvent, type StatusListener, type StealthScanHint, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TxResult, type UnsafeTxOptions, type Unshield, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, buildDummyTransferInput, bytesToBigintLE, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessage, deriveStealthOwnerPk, deriveStealthSk, deriveVaultKey, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, randomBlinding, recoverOwnerPkPoint, selectNotes, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
4470
+ export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type ActivityBucket, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, type IndexedBlock, type IndexedEvmTx, type IndexedExtrinsic, type IndexedSession, type IndexedValidator, type IndexerActivity, IndexerClient, type IndexerClientConfig, type IndexerStats, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, type MerkleRoot, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifierStatusResult, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, type PaginatedResult, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type PrivateTransferTimestamp, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RegisteredAsset, type RelayFeeEvent, type RelayFeeSummaryEntry, type Relayer, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, type ScanCommitment, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedAddressEvent, type ShieldedCommitment, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type SpentNullifier, type StatusChangeEvent, type StatusListener, type StealthScanHint, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TxResult, type UnsafeTxOptions, type Unshield, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, buildDummyTransferInput, bytesToBigintLE, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessage, deriveStealthOwnerPk, deriveStealthSk, deriveVaultKey, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, randomBlinding, recoverOwnerPkPoint, selectNotes, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
package/dist/index.d.ts CHANGED
@@ -653,6 +653,7 @@ interface IndexerStats {
653
653
  };
654
654
  extrinsics: {
655
655
  total: number;
656
+ signed: number;
656
657
  };
657
658
  evm: {
658
659
  transactions: number;
@@ -671,6 +672,19 @@ interface IndexerStats {
671
672
  successful: number;
672
673
  };
673
674
  }
675
+ /** One hour-bucket of transaction activity from `/stats/activity`. */
676
+ interface ActivityBucket {
677
+ hourStartMs: number;
678
+ transactions: number;
679
+ signedExtrinsics: number;
680
+ evmTransactions: number;
681
+ }
682
+ /** Transaction activity bucketed per hour over the last N hours of chain time. */
683
+ interface IndexerActivity {
684
+ hours: number;
685
+ anchorMs: number | null;
686
+ buckets: ActivityBucket[];
687
+ }
674
688
  /** A registered relayer stored by the indexer. */
675
689
  interface Relayer {
676
690
  evmAddress: string;
@@ -928,6 +942,11 @@ declare class IndexerClient {
928
942
  }): Promise<PaginatedResult<IndexedSession>>;
929
943
  /** Returns aggregated indexer statistics. */
930
944
  getStats(): Promise<IndexerStats>;
945
+ /**
946
+ * Returns transaction activity bucketed per hour over the last `hours` hours
947
+ * of chain time (default 24, max 168). For sparklines / activity charts.
948
+ */
949
+ getActivity(hours?: number): Promise<IndexerActivity>;
931
950
  /** Returns true if the indexer health endpoint responds OK. */
932
951
  isHealthy(): Promise<boolean>;
933
952
  }
@@ -2054,6 +2073,13 @@ interface ClientProviderConfig {
2054
2073
  reconnectBaseMs?: number;
2055
2074
  /** Maximum reconnect delay cap in milliseconds. Default: `30_000`. */
2056
2075
  reconnectMaxMs?: number;
2076
+ /**
2077
+ * How long a connection must stay live before the reconnect backoff is reset
2078
+ * to base, in milliseconds. Prevents a flapping node (connect → drop →
2079
+ * connect) from resetting the backoff on every brief connect and hammering
2080
+ * the node every `reconnectBaseMs`. Default: `10_000`.
2081
+ */
2082
+ stableAfterMs?: number;
2057
2083
  }
2058
2084
  /**
2059
2085
  * Manages the lifecycle of an `OrbinumClient` with heartbeat monitoring,
@@ -2081,11 +2107,13 @@ declare class OrbinumClientProvider {
2081
2107
  private readonly heartbeatTimeoutMs;
2082
2108
  private readonly reconnectBaseMs;
2083
2109
  private readonly reconnectMaxMs;
2110
+ private readonly stableAfterMs;
2084
2111
  private _status;
2085
2112
  private _orbinumClient;
2086
2113
  private _connectingPromise;
2087
2114
  private _heartbeatTimer;
2088
2115
  private _reconnectTimer;
2116
+ private _stableTimer;
2089
2117
  private _reconnectAttempt;
2090
2118
  private _listeners;
2091
2119
  /** Creates a new provider with the given configuration. Does not connect automatically — call `connect()` to initiate. */
@@ -2126,9 +2154,20 @@ declare class OrbinumClientProvider {
2126
2154
  * Returns `true` if the node responds in time, `false` otherwise.
2127
2155
  */
2128
2156
  private probe;
2157
+ /**
2158
+ * After a successful connect, wait `stableAfterMs` before resetting the
2159
+ * backoff. If the connection survives that long it's considered stable and
2160
+ * the next drop starts from base delay again; if it drops sooner the backoff
2161
+ * keeps growing, so a flapping node backs off instead of hammering.
2162
+ */
2163
+ private startStableTimer;
2164
+ /** Clears the stability timer if active (on disconnect/teardown/reset). */
2165
+ private stopStableTimer;
2129
2166
  /**
2130
2167
  * Schedules the next connection attempt using exponential backoff
2131
- * (capped at `reconnectMaxMs`), then transitions to `'reconnecting'`.
2168
+ * (capped at `reconnectMaxMs`) with full jitter, then transitions to
2169
+ * `'reconnecting'`. Jitter (a random fraction of the delay) spreads out
2170
+ * reconnects so many clients don't retry in lockstep after a shared outage.
2132
2171
  */
2133
2172
  private scheduleReconnect;
2134
2173
  /** Clears any pending reconnect timer without triggering a new attempt. */
@@ -4428,4 +4467,4 @@ interface ExtrinsicFailedData {
4428
4467
  dispatch_info: DispatchInfo;
4429
4468
  }
4430
4469
 
4431
- export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, type IndexedBlock, type IndexedEvmTx, type IndexedExtrinsic, type IndexedSession, type IndexedValidator, IndexerClient, type IndexerClientConfig, type IndexerStats, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, type MerkleRoot, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifierStatusResult, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, type PaginatedResult, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type PrivateTransferTimestamp, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RegisteredAsset, type RelayFeeEvent, type RelayFeeSummaryEntry, type Relayer, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, type ScanCommitment, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedAddressEvent, type ShieldedCommitment, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type SpentNullifier, type StatusChangeEvent, type StatusListener, type StealthScanHint, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TxResult, type UnsafeTxOptions, type Unshield, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, buildDummyTransferInput, bytesToBigintLE, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessage, deriveStealthOwnerPk, deriveStealthSk, deriveVaultKey, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, randomBlinding, recoverOwnerPkPoint, selectNotes, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
4470
+ export { type AccountListing, type AccountMappedData, type AccountMappedEvent, type AccountMappingCall, type AccountMappingEvent, AccountMappingModule, AccountMappingPrecompile, type AccountMetadata, type AccountUnmappedEvent, type ActiveVersionSetEvent, type ActivityBucket, type AddChainLinkArgs, type AddChainLinkParams, type AddSupportedChainArgs, type AliasFullIdentity, type AliasInfo, type AliasListedForSaleEvent, type AliasOnSaleData, type AliasRegisteredData, type AliasRegisteredEvent, type AliasReleasedEvent, type AliasSaleCancelledEvent, type AliasSoldData, type AliasSoldEvent, type AliasTransferredData, type AliasTransferredEvent, type AssetRegisteredEvent, type AssetUnverifiedEvent, type AssetVerifiedEvent, BABYJUB_SUBORDER, BN254_R, type BatchRegisterVerificationKeysArgs, type BatchVerificationKeysRegisteredEvent, type BlockInfo, type BuyAliasArgs, type Bytes32, type ChainInfo, type ChainLink, type ChainLinkAddedEvent, type ChainLinkRemovedEvent, CircuitId, CircuitId as CircuitIdType, type ClaimShieldedFeesParams, type ClientProviderConfig, type CommitmentsInsertedEvent, type CommitmentsInsertedEventData, type ConnectionStatus, CryptoPrecompiles, type DecodedAddChainLinkArgs, type DecodedBatchArgs, type DecodedDispatchAsPrivateLinkArgs, type DecodedEthereumTransactArgs, type DecodedEvmCallArgs, type DecodedPrecompile, type DecodedPrivateTransferArgs, type DecodedPutAliasForSaleArgs, type DecodedRegisterAliasArgs, type DecodedRemarkArgs, type DecodedRevealPrivateLinkArgs, type DecodedSetAccountMetadataArgs, type DecodedShieldArgs, type DecodedShieldBatchArgs, type DecodedShieldBatchOperation, type DecodedSudoArgs, type DecodedTransferAllArgs, type DecodedTransferArgs, type DecodedTransferKeepAliveArgs, type DecodedUnshieldArgs, type DecryptedMemo, type DispatchAsLinkedAccountArgs, type DispatchAsLinkedParams, type DispatchAsPrivateLinkArgs, type DispatchError, type DispatchInfo, type DynamicBuilder, ENCRYPTED_MEMO_SIZE, EncryptedMemo, type EncryptedNoteRecord, type EndowedEventData, type EthereumExecutedData, type EventData, type EventPhase, type EventRecord, type EvmAddressInfo, type EvmBlock, EvmClient, type EvmExecutedData, type EvmExitReason, EvmExplorer, type EvmLog, type EvmSigner, type EvmTransaction, type EvmTxRequest, type EvmTxSummary, type ExtrinsicDecoder, type ExtrinsicFailedData, type ExtrinsicSuccessData, type FeeClaimProofInputs, type FormatOptions, type IndexedBlock, type IndexedEvmTx, type IndexedExtrinsic, type IndexedSession, type IndexedValidator, type IndexerActivity, IndexerClient, type IndexerClientConfig, type IndexerStats, KNOWN_PRECOMPILES, type KnownPrecompileInfo, type ListingInfo, type MerkleRoot, type MerkleRootUpdatedData, type MerkleRootUpdatedEvent, type MerkleTreeInfo, type MetadataUpdatedEvent, NoteBuilder, type NoteDisclosure, type NoteInput, type NoteStatusUpdate, type NullifierStatusResult, type NullifiersSpentEvent, type NullifiersSpentEventData, OrbinumClient, type OrbinumClientConfig, OrbinumClientProvider, PRECOMPILE_ADDR, type PaginatedResult, PrivacyKeyManager, type PrivacyMerkleProof, PrivacyModule, type PrivateChainLinkAddedEvent, type PrivateChainLinkRemovedEvent, type PrivateChainLinkRevealedEvent, type PrivateLink, type PrivateLinkDispatchExecutedEvent, type PrivateTransferArgs, type PrivateTransferInput, type PrivateTransferOutput, type PrivateTransferParams, type PrivateTransferProofInputs, type PrivateTransferTimestamp, type ProofVerificationFailedEvent, type ProofVerifiedEvent, type ProxyCallExecutedEvent, type PutAliasOnSaleArgs, type PutOnSaleParams, type RawBlock, type RawBlockHeader, type RawTransferInput, type RawTransferOutput, type RegisterAliasArgs, type RegisterAssetArgs, type RegisterPrivateLinkArgs, type RegisterVerificationKeyArgs, type RegisteredAsset, type RelayFeeEvent, type RelayFeeSummaryEntry, type Relayer, type RelayerInfo, RelayerStatusModule, type RemoveChainLinkArgs, type RemovePrivateLinkArgs, type RemoveSupportedChainArgs, type RemoveVerificationKeyArgs, type ReservedEventData, type ResolvedAlias, type RevealPrivateLinkArgs, type RpcV2MerkleProof, type RpcV2NullifierStatus, type RpcV2PoolAssetBalance, type RpcV2PoolStats, SLIP0044_NAMESPACE, type ScanCommitment, type SetAccountMetadataArgs, type SetActiveVersionArgs, type SetMetadataParams, type ShieldArgs, type ShieldBatchArgs, type ShieldBatchItem, type ShieldBatchParams, type ShieldOperation, type ShieldParams, type ShieldedAddressEvent, type ShieldedCommitment, type ShieldedEvent, type ShieldedEventData, type ShieldedPoolCall, type ShieldedPoolEvent, ShieldedPoolModule, ShieldedPoolPrecompile, SignatureScheme, type SpentNullifier, type StatusChangeEvent, type StatusListener, type StealthScanHint, SubstrateClient, type SupportedChain, type SupportedChainAddedEvent, type SupportedChainRemovedEvent, type SystemHealth, type TokenInfo, type TokenTransfer, type TransferAliasArgs, type TransferEventData, type TransferInputNote, type TransferOutputNote, type TxResult, type UnsafeTxOptions, type Unshield, type UnshieldArgs, type UnshieldParams, type UnshieldProofInputs, type UnshieldedEvent, type UnshieldedEventData, type UnverifyAssetArgs, VaultLockedError, type VerificationKeyRegisteredEvent, type VerificationKeyRemovedEvent, type VerifyAssetArgs, type VerifyProofArgs, type VkEntry, type ZkNote, type ZkVerifierCall, type ZkVerifierCircuitVersionInfo, type ZkVerifierEvent, type ZkVerifierHistoricalVersion, ZkVerifierModule, type ZkVerifierVersionStats, type ZkVerifierVkHash, accountIdHexToSs58, addressToAccountIdHex, applyNoteStatus, bigintTo32Be, bigintTo32Le, bigintTo32LeArr, buildDummyTransferInput, bytesToBigintLE, computeNullifier, computePathIndices, createNoteDisclosureKey, decodeNoteDisclosureKey, decodePrecompileCalldata, decryptJson, decryptNoteRecord, deriveMasterKeyBytes, deriveOwnerPk, deriveSpendingKeyFromSignature, deriveSpendingKeyMessage, deriveStealthOwnerPk, deriveStealthSk, deriveVaultKey, deriveViewingPublicKey, deriveViewingSecretKey, encryptJson, encryptNote, ensureHexPrefix, evmAddressToAccountId, evmToImplicitSubstrate, evmToMappedAccountHex, evmToSubstrate, formatBalance, formatORB, fromBase64, fromHex, generateFeeClaimProof, generateTransferProof, generateUnshieldProof, getPrecompileLabel, hexToBigint, hexToNumber, implicitSubstrateToEvm, isEvmAddress, isImplicitEvmAccount, isSs58, isSubstrateAddress, isUnifiedAddress, leHexToBigint, mapExtrinsicArgs, mapZkEventData, normalizeEvmAddress, randomBlinding, recoverOwnerPkPoint, selectNotes, shortHash, substrateSs58ToAccountIdHex, substrateToEvm, toBase64, toHex, toTxResult, truncateMiddle, tryDecryptNote, tryDecryptNoteVerbose, vaultReplacer, vaultReviver };
package/dist/index.js CHANGED
@@ -1423,6 +1423,13 @@ var IndexerClient = class {
1423
1423
  async getStats() {
1424
1424
  return this.get("/stats");
1425
1425
  }
1426
+ /**
1427
+ * Returns transaction activity bucketed per hour over the last `hours` hours
1428
+ * of chain time (default 24, max 168). For sparklines / activity charts.
1429
+ */
1430
+ async getActivity(hours = 24) {
1431
+ return this.get(`/stats/activity?hours=${hours}`);
1432
+ }
1426
1433
  /** Returns true if the indexer health endpoint responds OK. */
1427
1434
  async isHealthy() {
1428
1435
  try {
@@ -3519,6 +3526,7 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
3519
3526
  var DEFAULT_HEARTBEAT_TIMEOUT_MS = 4e3;
3520
3527
  var DEFAULT_RECONNECT_BASE_MS = 3e3;
3521
3528
  var DEFAULT_RECONNECT_MAX_MS = 3e4;
3529
+ var DEFAULT_STABLE_AFTER_MS = 1e4;
3522
3530
  var OrbinumClientProvider = class {
3523
3531
  config;
3524
3532
  connectTimeoutMs;
@@ -3526,6 +3534,7 @@ var OrbinumClientProvider = class {
3526
3534
  heartbeatTimeoutMs;
3527
3535
  reconnectBaseMs;
3528
3536
  reconnectMaxMs;
3537
+ stableAfterMs;
3529
3538
  // ─── State ──────────────────────────────────────────────────────────────
3530
3539
  _status = "idle";
3531
3540
  _orbinumClient = null;
@@ -3533,6 +3542,7 @@ var OrbinumClientProvider = class {
3533
3542
  // ─── Timers ─────────────────────────────────────────────────────────────
3534
3543
  _heartbeatTimer = null;
3535
3544
  _reconnectTimer = null;
3545
+ _stableTimer = null;
3536
3546
  _reconnectAttempt = 0;
3537
3547
  // ─── Events ─────────────────────────────────────────────────────────────
3538
3548
  _listeners = /* @__PURE__ */ new Set();
@@ -3544,6 +3554,7 @@ var OrbinumClientProvider = class {
3544
3554
  this.heartbeatTimeoutMs = config.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;
3545
3555
  this.reconnectBaseMs = config.reconnectBaseMs ?? DEFAULT_RECONNECT_BASE_MS;
3546
3556
  this.reconnectMaxMs = config.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;
3557
+ this.stableAfterMs = config.stableAfterMs ?? DEFAULT_STABLE_AFTER_MS;
3547
3558
  }
3548
3559
  // ─── Status ─────────────────────────────────────────────────────────────
3549
3560
  /** Current connection status. Reflects the last state set by the provider internals. */
@@ -3630,9 +3641,9 @@ var OrbinumClientProvider = class {
3630
3641
  orphanClient = null;
3631
3642
  this._orbinumClient = client;
3632
3643
  this._connectingPromise = null;
3633
- this._reconnectAttempt = 0;
3634
3644
  this.setStatus("connected");
3635
3645
  this.startHeartbeat();
3646
+ this.startStableTimer();
3636
3647
  return client;
3637
3648
  } catch (err) {
3638
3649
  clearTimeout(timeoutId);
@@ -3689,17 +3700,41 @@ var OrbinumClientProvider = class {
3689
3700
  return false;
3690
3701
  }
3691
3702
  }
3703
+ // ─── Connection stability ───────────────────────────────────────────────
3704
+ /**
3705
+ * After a successful connect, wait `stableAfterMs` before resetting the
3706
+ * backoff. If the connection survives that long it's considered stable and
3707
+ * the next drop starts from base delay again; if it drops sooner the backoff
3708
+ * keeps growing, so a flapping node backs off instead of hammering.
3709
+ */
3710
+ startStableTimer() {
3711
+ this.stopStableTimer();
3712
+ this._stableTimer = setTimeout(() => {
3713
+ this._stableTimer = null;
3714
+ if (this._status === "connected") this._reconnectAttempt = 0;
3715
+ }, this.stableAfterMs);
3716
+ }
3717
+ /** Clears the stability timer if active (on disconnect/teardown/reset). */
3718
+ stopStableTimer() {
3719
+ if (this._stableTimer) {
3720
+ clearTimeout(this._stableTimer);
3721
+ this._stableTimer = null;
3722
+ }
3723
+ }
3692
3724
  // ─── Reconnection ───────────────────────────────────────────────────────
3693
3725
  /**
3694
3726
  * Schedules the next connection attempt using exponential backoff
3695
- * (capped at `reconnectMaxMs`), then transitions to `'reconnecting'`.
3727
+ * (capped at `reconnectMaxMs`) with full jitter, then transitions to
3728
+ * `'reconnecting'`. Jitter (a random fraction of the delay) spreads out
3729
+ * reconnects so many clients don't retry in lockstep after a shared outage.
3696
3730
  */
3697
3731
  scheduleReconnect() {
3698
3732
  if (this._reconnectTimer) clearTimeout(this._reconnectTimer);
3699
- const delay = Math.min(
3733
+ const capped = Math.min(
3700
3734
  this.reconnectBaseMs * 2 ** this._reconnectAttempt,
3701
3735
  this.reconnectMaxMs
3702
3736
  );
3737
+ const delay = capped / 2 + Math.random() * (capped / 2);
3703
3738
  this._reconnectAttempt++;
3704
3739
  this.setStatus("reconnecting");
3705
3740
  this._reconnectTimer = setTimeout(() => {
@@ -3718,6 +3753,7 @@ var OrbinumClientProvider = class {
3718
3753
  /** Stops the heartbeat, destroys the active client, and clears all in-progress promises. */
3719
3754
  teardownClient() {
3720
3755
  this.stopHeartbeat();
3756
+ this.stopStableTimer();
3721
3757
  try {
3722
3758
  this._orbinumClient?.destroy();
3723
3759
  } catch {
package/dist/index.mjs CHANGED
@@ -1296,6 +1296,13 @@ var IndexerClient = class {
1296
1296
  async getStats() {
1297
1297
  return this.get("/stats");
1298
1298
  }
1299
+ /**
1300
+ * Returns transaction activity bucketed per hour over the last `hours` hours
1301
+ * of chain time (default 24, max 168). For sparklines / activity charts.
1302
+ */
1303
+ async getActivity(hours = 24) {
1304
+ return this.get(`/stats/activity?hours=${hours}`);
1305
+ }
1299
1306
  /** Returns true if the indexer health endpoint responds OK. */
1300
1307
  async isHealthy() {
1301
1308
  try {
@@ -3392,6 +3399,7 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
3392
3399
  var DEFAULT_HEARTBEAT_TIMEOUT_MS = 4e3;
3393
3400
  var DEFAULT_RECONNECT_BASE_MS = 3e3;
3394
3401
  var DEFAULT_RECONNECT_MAX_MS = 3e4;
3402
+ var DEFAULT_STABLE_AFTER_MS = 1e4;
3395
3403
  var OrbinumClientProvider = class {
3396
3404
  config;
3397
3405
  connectTimeoutMs;
@@ -3399,6 +3407,7 @@ var OrbinumClientProvider = class {
3399
3407
  heartbeatTimeoutMs;
3400
3408
  reconnectBaseMs;
3401
3409
  reconnectMaxMs;
3410
+ stableAfterMs;
3402
3411
  // ─── State ──────────────────────────────────────────────────────────────
3403
3412
  _status = "idle";
3404
3413
  _orbinumClient = null;
@@ -3406,6 +3415,7 @@ var OrbinumClientProvider = class {
3406
3415
  // ─── Timers ─────────────────────────────────────────────────────────────
3407
3416
  _heartbeatTimer = null;
3408
3417
  _reconnectTimer = null;
3418
+ _stableTimer = null;
3409
3419
  _reconnectAttempt = 0;
3410
3420
  // ─── Events ─────────────────────────────────────────────────────────────
3411
3421
  _listeners = /* @__PURE__ */ new Set();
@@ -3417,6 +3427,7 @@ var OrbinumClientProvider = class {
3417
3427
  this.heartbeatTimeoutMs = config.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS;
3418
3428
  this.reconnectBaseMs = config.reconnectBaseMs ?? DEFAULT_RECONNECT_BASE_MS;
3419
3429
  this.reconnectMaxMs = config.reconnectMaxMs ?? DEFAULT_RECONNECT_MAX_MS;
3430
+ this.stableAfterMs = config.stableAfterMs ?? DEFAULT_STABLE_AFTER_MS;
3420
3431
  }
3421
3432
  // ─── Status ─────────────────────────────────────────────────────────────
3422
3433
  /** Current connection status. Reflects the last state set by the provider internals. */
@@ -3503,9 +3514,9 @@ var OrbinumClientProvider = class {
3503
3514
  orphanClient = null;
3504
3515
  this._orbinumClient = client;
3505
3516
  this._connectingPromise = null;
3506
- this._reconnectAttempt = 0;
3507
3517
  this.setStatus("connected");
3508
3518
  this.startHeartbeat();
3519
+ this.startStableTimer();
3509
3520
  return client;
3510
3521
  } catch (err) {
3511
3522
  clearTimeout(timeoutId);
@@ -3562,17 +3573,41 @@ var OrbinumClientProvider = class {
3562
3573
  return false;
3563
3574
  }
3564
3575
  }
3576
+ // ─── Connection stability ───────────────────────────────────────────────
3577
+ /**
3578
+ * After a successful connect, wait `stableAfterMs` before resetting the
3579
+ * backoff. If the connection survives that long it's considered stable and
3580
+ * the next drop starts from base delay again; if it drops sooner the backoff
3581
+ * keeps growing, so a flapping node backs off instead of hammering.
3582
+ */
3583
+ startStableTimer() {
3584
+ this.stopStableTimer();
3585
+ this._stableTimer = setTimeout(() => {
3586
+ this._stableTimer = null;
3587
+ if (this._status === "connected") this._reconnectAttempt = 0;
3588
+ }, this.stableAfterMs);
3589
+ }
3590
+ /** Clears the stability timer if active (on disconnect/teardown/reset). */
3591
+ stopStableTimer() {
3592
+ if (this._stableTimer) {
3593
+ clearTimeout(this._stableTimer);
3594
+ this._stableTimer = null;
3595
+ }
3596
+ }
3565
3597
  // ─── Reconnection ───────────────────────────────────────────────────────
3566
3598
  /**
3567
3599
  * Schedules the next connection attempt using exponential backoff
3568
- * (capped at `reconnectMaxMs`), then transitions to `'reconnecting'`.
3600
+ * (capped at `reconnectMaxMs`) with full jitter, then transitions to
3601
+ * `'reconnecting'`. Jitter (a random fraction of the delay) spreads out
3602
+ * reconnects so many clients don't retry in lockstep after a shared outage.
3569
3603
  */
3570
3604
  scheduleReconnect() {
3571
3605
  if (this._reconnectTimer) clearTimeout(this._reconnectTimer);
3572
- const delay = Math.min(
3606
+ const capped = Math.min(
3573
3607
  this.reconnectBaseMs * 2 ** this._reconnectAttempt,
3574
3608
  this.reconnectMaxMs
3575
3609
  );
3610
+ const delay = capped / 2 + Math.random() * (capped / 2);
3576
3611
  this._reconnectAttempt++;
3577
3612
  this.setStatus("reconnecting");
3578
3613
  this._reconnectTimer = setTimeout(() => {
@@ -3591,6 +3626,7 @@ var OrbinumClientProvider = class {
3591
3626
  /** Stops the heartbeat, destroys the active client, and clears all in-progress promises. */
3592
3627
  teardownClient() {
3593
3628
  this.stopHeartbeat();
3629
+ this.stopStableTimer();
3594
3630
  try {
3595
3631
  this._orbinumClient?.destroy();
3596
3632
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orbinum/sdk",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "Official TypeScript SDK for Orbinum.",
5
5
  "author": "Orbinum",
6
6
  "license": "MIT",