@fenelabs/fene-sdk 0.3.0 → 0.3.2

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/CHANGELOG.md CHANGED
@@ -5,6 +5,30 @@ All notable changes to the Resonance SDK will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.2.1] - 2025-12-10
9
+
10
+ ### Added
11
+
12
+ #### Analytics Helper Utilities
13
+ - **Error handling helpers**: `isValidatorNotFound()`, `isServiceUnavailable()`, `isTimeout()`
14
+ - **Data validation helpers**: `isStaleData()`, `isCachedData()`, `validatePagination()`
15
+ - **Sync monitoring helpers**: `isSyncHealthy()`, `isSyncDegraded()`, `getSyncLag()`
16
+ - **Data freshness**: `getDataFreshness()` - Calculate freshness score (0-100)
17
+ - **Number formatting**: `formatNumber()`, `weiToEther()` - Format large numbers
18
+ - **Batch optimization**: `getOptimalBatchSize()` - Calculate optimal pagination size
19
+
20
+ #### Retry Logic
21
+ - **`withRetry()`** - Execute functions with automatic retry on transient errors
22
+ - **`createRetryWrapper()`** - Create retry-wrapped versions of functions
23
+ - Configurable retry options: max retries, backoff, custom predicates
24
+ - Built-in retry for timeout and 503 errors
25
+ - Exponential backoff with max delay cap
26
+
27
+ ### Changed
28
+ - Enhanced README with utility function documentation
29
+ - Added `examples/analytics-advanced.ts` with advanced usage patterns
30
+ - Improved error handling examples
31
+
8
32
  ## [0.2.0] - 2025-12-10
9
33
 
10
34
  ### Added
package/README.md CHANGED
@@ -249,6 +249,62 @@ console.log('Total Stakes Fetched:', allRewards.stakes.length);
249
249
  - The rewards endpoint is heavy and **requires pagination** - never fetch without limit/offset
250
250
  - Use `getSyncStatus()` to verify data freshness before making critical decisions
251
251
 
252
+ ### Analytics Helper Utilities
253
+
254
+ The SDK provides utility functions for working with analytics data:
255
+
256
+ ```typescript
257
+ import {
258
+ isValidatorNotFound,
259
+ isStaleData,
260
+ isCachedData,
261
+ isSyncHealthy,
262
+ getSyncLag,
263
+ getDataFreshness,
264
+ formatNumber,
265
+ weiToEther,
266
+ withRetry,
267
+ } from '@avenbreaks/resonance-sdk';
268
+
269
+ // Error handling
270
+ try {
271
+ const validator = await sdk.analytics.getValidatorAnalytics(address);
272
+ } catch (error) {
273
+ if (isValidatorNotFound(error)) {
274
+ console.log('Validator does not exist');
275
+ }
276
+ }
277
+
278
+ // Data freshness validation
279
+ const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
280
+ if (isStaleData(rewards)) {
281
+ console.warn('Data may be outdated');
282
+ }
283
+
284
+ // Sync health monitoring
285
+ const syncStatus = await sdk.analytics.getSyncStatus();
286
+ if (isSyncHealthy(syncStatus, 'protocol_sync')) {
287
+ console.log('Sync is healthy');
288
+ }
289
+
290
+ // Retry logic for heavy queries
291
+ const rewardsWithRetry = await withRetry(
292
+ () => sdk.analytics.getValidatorRewards(address, { limit: 100 }),
293
+ {
294
+ maxRetries: 3,
295
+ initialDelay: 1000,
296
+ onRetry: (error, attempt, delay) => {
297
+ console.log(`Retry ${attempt} after ${delay}ms`);
298
+ }
299
+ }
300
+ );
301
+
302
+ // Number formatting
303
+ const stats = await sdk.analytics.getProtocolStats();
304
+ console.log(formatNumber(stats.TotalStaking)); // "26,883,345,073,055,930,973,683,712"
305
+ console.log(weiToEther(stats.TotalStaking)); // "26883345.0730"
306
+ ```
307
+
252
308
  ## Advanced Usage
253
309
 
254
310
  ### Custom Headers
package/dist/index.d.mts CHANGED
@@ -875,6 +875,316 @@ declare class AnalyticsAPI {
875
875
  }): Promise<ValidatorRewardsResponse>;
876
876
  }
877
877
 
878
+ /**
879
+ * Analytics Helper Utilities
880
+ *
881
+ * Provides utility functions for working with analytics data,
882
+ * including error checking, data validation, and freshness checks.
883
+ */
884
+ /**
885
+ * Check if error is a validator not found error
886
+ *
887
+ * @param error - Error object to check
888
+ * @returns True if validator was not found
889
+ *
890
+ * @example
891
+ * ```typescript
892
+ * try {
893
+ * const validator = await sdk.analytics.getValidatorAnalytics(address);
894
+ * } catch (error) {
895
+ * if (isValidatorNotFound(error)) {
896
+ * console.log('Validator does not exist');
897
+ * }
898
+ * }
899
+ * ```
900
+ */
901
+ declare function isValidatorNotFound(error: any): boolean;
902
+ /**
903
+ * Check if error is a service unavailable error (sync in progress)
904
+ *
905
+ * @param error - Error object to check
906
+ * @returns True if service is temporarily unavailable
907
+ *
908
+ * @example
909
+ * ```typescript
910
+ * try {
911
+ * const stats = await sdk.analytics.getProtocolStats();
912
+ * } catch (error) {
913
+ * if (isServiceUnavailable(error)) {
914
+ * console.log('Analytics service is syncing, try again later');
915
+ * }
916
+ * }
917
+ * ```
918
+ */
919
+ declare function isServiceUnavailable(error: any): boolean;
920
+ /**
921
+ * Check if error is a timeout error
922
+ *
923
+ * @param error - Error object to check
924
+ * @returns True if request timed out
925
+ *
926
+ * @example
927
+ * ```typescript
928
+ * try {
929
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 1000 });
930
+ * } catch (error) {
931
+ * if (isTimeout(error)) {
932
+ * console.log('Request timed out, try with smaller limit');
933
+ * }
934
+ * }
935
+ * ```
936
+ */
937
+ declare function isTimeout(error: any): boolean;
938
+ /**
939
+ * Check if analytics data is stale
940
+ *
941
+ * @param response - Response with metadata
942
+ * @returns True if data is marked as stale
943
+ *
944
+ * @example
945
+ * ```typescript
946
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
947
+ * if (isStaleData(rewards)) {
948
+ * console.warn('Data may be outdated');
949
+ * }
950
+ * ```
951
+ */
952
+ declare function isStaleData(response: ValidatorRewardsResponse): boolean;
953
+ /**
954
+ * Check if analytics data is from cache
955
+ *
956
+ * @param response - Response with metadata
957
+ * @returns True if data was served from cache
958
+ *
959
+ * @example
960
+ * ```typescript
961
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
962
+ * if (isCachedData(rewards)) {
963
+ * console.log('Serving from cache');
964
+ * }
965
+ * ```
966
+ */
967
+ declare function isCachedData(response: ValidatorRewardsResponse): boolean;
968
+ /**
969
+ * Check if sync worker is healthy
970
+ *
971
+ * @param syncStatus - Sync status response
972
+ * @param workerName - Worker name to check ('protocol_sync' or 'validator_sync')
973
+ * @returns True if worker is in success state
974
+ *
975
+ * @example
976
+ * ```typescript
977
+ * const status = await sdk.analytics.getSyncStatus();
978
+ * if (isSyncHealthy(status, 'protocol_sync')) {
979
+ * console.log('Protocol sync is healthy');
980
+ * }
981
+ * ```
982
+ */
983
+ declare function isSyncHealthy(syncStatus: SyncStatusResponse, workerName?: 'protocol_sync' | 'validator_sync'): boolean;
984
+ /**
985
+ * Check if sync worker is degraded
986
+ *
987
+ * @param syncStatus - Sync status response
988
+ * @param workerName - Worker name to check
989
+ * @returns True if worker is in degraded state
990
+ *
991
+ * @example
992
+ * ```typescript
993
+ * const status = await sdk.analytics.getSyncStatus();
994
+ * if (isSyncDegraded(status, 'protocol_sync')) {
995
+ * console.warn('Protocol sync is degraded, some data may be incomplete');
996
+ * }
997
+ * ```
998
+ */
999
+ declare function isSyncDegraded(syncStatus: SyncStatusResponse, workerName?: 'protocol_sync' | 'validator_sync'): boolean;
1000
+ /**
1001
+ * Get sync lag in blocks
1002
+ *
1003
+ * @param syncStatus - Sync status response
1004
+ * @param currentBlock - Current blockchain block number
1005
+ * @param workerName - Worker name to check
1006
+ * @returns Number of blocks behind, or null if unknown
1007
+ *
1008
+ * @example
1009
+ * ```typescript
1010
+ * const status = await sdk.analytics.getSyncStatus();
1011
+ * const currentBlock = await provider.getBlockNumber();
1012
+ * const lag = getSyncLag(status, currentBlock);
1013
+ * if (lag && lag > 100) {
1014
+ * console.warn(`Analytics is ${lag} blocks behind`);
1015
+ * }
1016
+ * ```
1017
+ */
1018
+ declare function getSyncLag(syncStatus: SyncStatusResponse, currentBlock: number, workerName?: 'protocol_sync' | 'validator_sync'): number | null;
1019
+ /**
1020
+ * Calculate data freshness score (0-100)
1021
+ *
1022
+ * @param response - Response with metadata
1023
+ * @param currentBlock - Current blockchain block number
1024
+ * @returns Freshness score (100 = perfectly fresh, 0 = very stale)
1025
+ *
1026
+ * @remarks
1027
+ * Score calculation:
1028
+ * - 100: Data is from current block
1029
+ * - 90-99: Data is 1-10 blocks behind
1030
+ * - 50-89: Data is 11-100 blocks behind
1031
+ * - 0-49: Data is >100 blocks behind
1032
+ *
1033
+ * @example
1034
+ * ```typescript
1035
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
1036
+ * const currentBlock = await provider.getBlockNumber();
1037
+ * const freshness = getDataFreshness(rewards, currentBlock);
1038
+ *
1039
+ * if (freshness < 50) {
1040
+ * console.warn('Data is very stale');
1041
+ * } else if (freshness < 90) {
1042
+ * console.log('Data is slightly behind');
1043
+ * } else {
1044
+ * console.log('Data is fresh');
1045
+ * }
1046
+ * ```
1047
+ */
1048
+ declare function getDataFreshness(response: ValidatorRewardsResponse, currentBlock: number): number;
1049
+ /**
1050
+ * Validate pagination options
1051
+ *
1052
+ * @param limit - Limit value
1053
+ * @param offset - Offset value
1054
+ * @throws Error if pagination options are invalid
1055
+ *
1056
+ * @example
1057
+ * ```typescript
1058
+ * try {
1059
+ * validatePagination(50, 0);
1060
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50, offset: 0 });
1061
+ * } catch (error) {
1062
+ * console.error('Invalid pagination:', error.message);
1063
+ * }
1064
+ * ```
1065
+ */
1066
+ declare function validatePagination(limit?: number, offset?: number): void;
1067
+ /**
1068
+ * Calculate optimal batch size for pagination
1069
+ *
1070
+ * @param totalItems - Total number of items to fetch
1071
+ * @param maxBatchSize - Maximum batch size (default: 100)
1072
+ * @returns Optimal batch size
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * const totalStakers = 250;
1077
+ * const batchSize = getOptimalBatchSize(totalStakers);
1078
+ * // Returns 50 (250 / 5 batches)
1079
+ * ```
1080
+ */
1081
+ declare function getOptimalBatchSize(totalItems: number, maxBatchSize?: number): number;
1082
+ /**
1083
+ * Format large numbers with commas
1084
+ *
1085
+ * @param value - Number or string to format
1086
+ * @returns Formatted string with commas
1087
+ *
1088
+ * @example
1089
+ * ```typescript
1090
+ * const staking = stats.TotalStaking;
1091
+ * console.log(formatNumber(staking)); // "26,883,345,073,055,930,973,683,712"
1092
+ * ```
1093
+ */
1094
+ declare function formatNumber(value: string | number): string;
1095
+ /**
1096
+ * Convert Wei to Ether string
1097
+ *
1098
+ * @param wei - Wei amount as string
1099
+ * @param decimals - Number of decimal places (default: 4)
1100
+ * @returns Ether amount as string
1101
+ *
1102
+ * @example
1103
+ * ```typescript
1104
+ * const stake = "4000000000000000000000000";
1105
+ * console.log(weiToEther(stake)); // "4000000.0000"
1106
+ * ```
1107
+ */
1108
+ declare function weiToEther(wei: string, decimals?: number): string;
1109
+
1110
+ /**
1111
+ * Retry Utilities
1112
+ *
1113
+ * Provides retry logic with exponential backoff for handling
1114
+ * transient errors and timeouts.
1115
+ */
1116
+ interface RetryOptions {
1117
+ /**
1118
+ * Maximum number of retry attempts
1119
+ * @default 3
1120
+ */
1121
+ maxRetries?: number;
1122
+ /**
1123
+ * Initial delay in milliseconds before first retry
1124
+ * @default 1000
1125
+ */
1126
+ initialDelay?: number;
1127
+ /**
1128
+ * Maximum delay in milliseconds between retries
1129
+ * @default 10000
1130
+ */
1131
+ maxDelay?: number;
1132
+ /**
1133
+ * Backoff multiplier for exponential backoff
1134
+ * @default 2
1135
+ */
1136
+ backoffMultiplier?: number;
1137
+ /**
1138
+ * Function to determine if error should be retried
1139
+ * @default Retries on timeout and 503 errors
1140
+ */
1141
+ shouldRetry?: (error: any, attempt: number) => boolean;
1142
+ /**
1143
+ * Callback called before each retry
1144
+ */
1145
+ onRetry?: (error: any, attempt: number, delay: number) => void;
1146
+ }
1147
+ /**
1148
+ * Execute a function with retry logic
1149
+ *
1150
+ * @param fn - Async function to execute
1151
+ * @param options - Retry options
1152
+ * @returns Promise resolving to function result
1153
+ *
1154
+ * @example
1155
+ * ```typescript
1156
+ * const result = await withRetry(
1157
+ * () => sdk.analytics.getValidatorRewards(address, { limit: 100 }),
1158
+ * {
1159
+ * maxRetries: 3,
1160
+ * initialDelay: 1000,
1161
+ * onRetry: (error, attempt, delay) => {
1162
+ * console.log(`Retry attempt ${attempt} after ${delay}ms`);
1163
+ * }
1164
+ * }
1165
+ * );
1166
+ * ```
1167
+ */
1168
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
1169
+ /**
1170
+ * Create a retry wrapper for a function
1171
+ *
1172
+ * @param fn - Function to wrap
1173
+ * @param options - Retry options
1174
+ * @returns Wrapped function with retry logic
1175
+ *
1176
+ * @example
1177
+ * ```typescript
1178
+ * const getRewardsWithRetry = createRetryWrapper(
1179
+ * (address: string, opts: any) => sdk.analytics.getValidatorRewards(address, opts),
1180
+ * { maxRetries: 3 }
1181
+ * );
1182
+ *
1183
+ * const rewards = await getRewardsWithRetry(address, { limit: 50 });
1184
+ * ```
1185
+ */
1186
+ declare function createRetryWrapper<T extends (...args: any[]) => Promise<any>>(fn: T, options?: RetryOptions): T;
1187
+
878
1188
  /**
879
1189
  * Resonance Network SDK
880
1190
  *
@@ -934,4 +1244,4 @@ declare class ResonanceSDK {
934
1244
  logout(): void;
935
1245
  }
936
1246
 
937
- export { type APIError, type APIResponse, type ActiveValidator, AnalyticsAPI, type AuthResponse, AuthService, type DelegatorDetailResponse, type DelegatorListResponse, type DelegatorReward, type DelegatorRewardsResponse, type DelegatorStakeInfo, type DelegatorStakesResponse, type DelegatorUnbondingResponse, type DelegatorValidatorStake, type DelegatorValidatorsResponse, type DelegatorWithdrawal, type DelegatorWithdrawalsResponse, DelegatorsAPI, type EpochDistribution, type EpochReward, type EpochStakes, type EpochUnclaimed, GlobalAPI, type GlobalNetworkResponse, HTTPClient, type JWTClaims, type LeaderboardDelegatorResponse, type LeaderboardValidatorResponse, type NetworkAPRBreakdownResponse, type NetworkAPRResponse, type PaginationOptions, type ProtocolStats, type QueryParams, type ReferralApplyRequest, type ReferralCreateRequest, type ReferralDelegatorResponse, type ReferralValidateRequest, type ReferralValidateResponse, type ReferralValidatorResponse, ReferralsAPI, ResonanceSDK, type ResponseMetadata, type RewardDTO, type RewardSummary, type SDKConfig, SlashingAPI, type SlashingEventResponse, type StakeDTO, type SyncJobStatus, type SyncStatusResponse, type TopDelegatorRank, type UnbondingInfo, type UnclaimedDelegator, type ValidatorAPRResponse, type ValidatorAnalytics, type ValidatorAnalyticsListResponse, type ValidatorDelegatorsResponse, type ValidatorDetailResponse, type ValidatorEpochResponse, type ValidatorHistoryItem, type ValidatorHistoryResponse, type ValidatorListOptions, type ValidatorListResponse, type ValidatorMetricsResponse, type ValidatorRewardsResponse, type ValidatorStakeBreakdownResponse, type ValidatorWithdrawal, type ValidatorWithdrawalsResponse, ValidatorsAPI, ResonanceSDK as default };
1247
+ export { type APIError, type APIResponse, type ActiveValidator, AnalyticsAPI, type AuthResponse, AuthService, type DelegatorDetailResponse, type DelegatorListResponse, type DelegatorReward, type DelegatorRewardsResponse, type DelegatorStakeInfo, type DelegatorStakesResponse, type DelegatorUnbondingResponse, type DelegatorValidatorStake, type DelegatorValidatorsResponse, type DelegatorWithdrawal, type DelegatorWithdrawalsResponse, DelegatorsAPI, type EpochDistribution, type EpochReward, type EpochStakes, type EpochUnclaimed, GlobalAPI, type GlobalNetworkResponse, HTTPClient, type JWTClaims, type LeaderboardDelegatorResponse, type LeaderboardValidatorResponse, type NetworkAPRBreakdownResponse, type NetworkAPRResponse, type PaginationOptions, type ProtocolStats, type QueryParams, type ReferralApplyRequest, type ReferralCreateRequest, type ReferralDelegatorResponse, type ReferralValidateRequest, type ReferralValidateResponse, type ReferralValidatorResponse, ReferralsAPI, ResonanceSDK, type ResponseMetadata, type RetryOptions, type RewardDTO, type RewardSummary, type SDKConfig, SlashingAPI, type SlashingEventResponse, type StakeDTO, type SyncJobStatus, type SyncStatusResponse, type TopDelegatorRank, type UnbondingInfo, type UnclaimedDelegator, type ValidatorAPRResponse, type ValidatorAnalytics, type ValidatorAnalyticsListResponse, type ValidatorDelegatorsResponse, type ValidatorDetailResponse, type ValidatorEpochResponse, type ValidatorHistoryItem, type ValidatorHistoryResponse, type ValidatorListOptions, type ValidatorListResponse, type ValidatorMetricsResponse, type ValidatorRewardsResponse, type ValidatorStakeBreakdownResponse, type ValidatorWithdrawal, type ValidatorWithdrawalsResponse, ValidatorsAPI, createRetryWrapper, ResonanceSDK as default, formatNumber, getDataFreshness, getOptimalBatchSize, getSyncLag, isCachedData, isServiceUnavailable, isStaleData, isSyncDegraded, isSyncHealthy, isTimeout, isValidatorNotFound, validatePagination, weiToEther, withRetry };
package/dist/index.d.ts CHANGED
@@ -875,6 +875,316 @@ declare class AnalyticsAPI {
875
875
  }): Promise<ValidatorRewardsResponse>;
876
876
  }
877
877
 
878
+ /**
879
+ * Analytics Helper Utilities
880
+ *
881
+ * Provides utility functions for working with analytics data,
882
+ * including error checking, data validation, and freshness checks.
883
+ */
884
+ /**
885
+ * Check if error is a validator not found error
886
+ *
887
+ * @param error - Error object to check
888
+ * @returns True if validator was not found
889
+ *
890
+ * @example
891
+ * ```typescript
892
+ * try {
893
+ * const validator = await sdk.analytics.getValidatorAnalytics(address);
894
+ * } catch (error) {
895
+ * if (isValidatorNotFound(error)) {
896
+ * console.log('Validator does not exist');
897
+ * }
898
+ * }
899
+ * ```
900
+ */
901
+ declare function isValidatorNotFound(error: any): boolean;
902
+ /**
903
+ * Check if error is a service unavailable error (sync in progress)
904
+ *
905
+ * @param error - Error object to check
906
+ * @returns True if service is temporarily unavailable
907
+ *
908
+ * @example
909
+ * ```typescript
910
+ * try {
911
+ * const stats = await sdk.analytics.getProtocolStats();
912
+ * } catch (error) {
913
+ * if (isServiceUnavailable(error)) {
914
+ * console.log('Analytics service is syncing, try again later');
915
+ * }
916
+ * }
917
+ * ```
918
+ */
919
+ declare function isServiceUnavailable(error: any): boolean;
920
+ /**
921
+ * Check if error is a timeout error
922
+ *
923
+ * @param error - Error object to check
924
+ * @returns True if request timed out
925
+ *
926
+ * @example
927
+ * ```typescript
928
+ * try {
929
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 1000 });
930
+ * } catch (error) {
931
+ * if (isTimeout(error)) {
932
+ * console.log('Request timed out, try with smaller limit');
933
+ * }
934
+ * }
935
+ * ```
936
+ */
937
+ declare function isTimeout(error: any): boolean;
938
+ /**
939
+ * Check if analytics data is stale
940
+ *
941
+ * @param response - Response with metadata
942
+ * @returns True if data is marked as stale
943
+ *
944
+ * @example
945
+ * ```typescript
946
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
947
+ * if (isStaleData(rewards)) {
948
+ * console.warn('Data may be outdated');
949
+ * }
950
+ * ```
951
+ */
952
+ declare function isStaleData(response: ValidatorRewardsResponse): boolean;
953
+ /**
954
+ * Check if analytics data is from cache
955
+ *
956
+ * @param response - Response with metadata
957
+ * @returns True if data was served from cache
958
+ *
959
+ * @example
960
+ * ```typescript
961
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
962
+ * if (isCachedData(rewards)) {
963
+ * console.log('Serving from cache');
964
+ * }
965
+ * ```
966
+ */
967
+ declare function isCachedData(response: ValidatorRewardsResponse): boolean;
968
+ /**
969
+ * Check if sync worker is healthy
970
+ *
971
+ * @param syncStatus - Sync status response
972
+ * @param workerName - Worker name to check ('protocol_sync' or 'validator_sync')
973
+ * @returns True if worker is in success state
974
+ *
975
+ * @example
976
+ * ```typescript
977
+ * const status = await sdk.analytics.getSyncStatus();
978
+ * if (isSyncHealthy(status, 'protocol_sync')) {
979
+ * console.log('Protocol sync is healthy');
980
+ * }
981
+ * ```
982
+ */
983
+ declare function isSyncHealthy(syncStatus: SyncStatusResponse, workerName?: 'protocol_sync' | 'validator_sync'): boolean;
984
+ /**
985
+ * Check if sync worker is degraded
986
+ *
987
+ * @param syncStatus - Sync status response
988
+ * @param workerName - Worker name to check
989
+ * @returns True if worker is in degraded state
990
+ *
991
+ * @example
992
+ * ```typescript
993
+ * const status = await sdk.analytics.getSyncStatus();
994
+ * if (isSyncDegraded(status, 'protocol_sync')) {
995
+ * console.warn('Protocol sync is degraded, some data may be incomplete');
996
+ * }
997
+ * ```
998
+ */
999
+ declare function isSyncDegraded(syncStatus: SyncStatusResponse, workerName?: 'protocol_sync' | 'validator_sync'): boolean;
1000
+ /**
1001
+ * Get sync lag in blocks
1002
+ *
1003
+ * @param syncStatus - Sync status response
1004
+ * @param currentBlock - Current blockchain block number
1005
+ * @param workerName - Worker name to check
1006
+ * @returns Number of blocks behind, or null if unknown
1007
+ *
1008
+ * @example
1009
+ * ```typescript
1010
+ * const status = await sdk.analytics.getSyncStatus();
1011
+ * const currentBlock = await provider.getBlockNumber();
1012
+ * const lag = getSyncLag(status, currentBlock);
1013
+ * if (lag && lag > 100) {
1014
+ * console.warn(`Analytics is ${lag} blocks behind`);
1015
+ * }
1016
+ * ```
1017
+ */
1018
+ declare function getSyncLag(syncStatus: SyncStatusResponse, currentBlock: number, workerName?: 'protocol_sync' | 'validator_sync'): number | null;
1019
+ /**
1020
+ * Calculate data freshness score (0-100)
1021
+ *
1022
+ * @param response - Response with metadata
1023
+ * @param currentBlock - Current blockchain block number
1024
+ * @returns Freshness score (100 = perfectly fresh, 0 = very stale)
1025
+ *
1026
+ * @remarks
1027
+ * Score calculation:
1028
+ * - 100: Data is from current block
1029
+ * - 90-99: Data is 1-10 blocks behind
1030
+ * - 50-89: Data is 11-100 blocks behind
1031
+ * - 0-49: Data is >100 blocks behind
1032
+ *
1033
+ * @example
1034
+ * ```typescript
1035
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50 });
1036
+ * const currentBlock = await provider.getBlockNumber();
1037
+ * const freshness = getDataFreshness(rewards, currentBlock);
1038
+ *
1039
+ * if (freshness < 50) {
1040
+ * console.warn('Data is very stale');
1041
+ * } else if (freshness < 90) {
1042
+ * console.log('Data is slightly behind');
1043
+ * } else {
1044
+ * console.log('Data is fresh');
1045
+ * }
1046
+ * ```
1047
+ */
1048
+ declare function getDataFreshness(response: ValidatorRewardsResponse, currentBlock: number): number;
1049
+ /**
1050
+ * Validate pagination options
1051
+ *
1052
+ * @param limit - Limit value
1053
+ * @param offset - Offset value
1054
+ * @throws Error if pagination options are invalid
1055
+ *
1056
+ * @example
1057
+ * ```typescript
1058
+ * try {
1059
+ * validatePagination(50, 0);
1060
+ * const rewards = await sdk.analytics.getValidatorRewards(address, { limit: 50, offset: 0 });
1061
+ * } catch (error) {
1062
+ * console.error('Invalid pagination:', error.message);
1063
+ * }
1064
+ * ```
1065
+ */
1066
+ declare function validatePagination(limit?: number, offset?: number): void;
1067
+ /**
1068
+ * Calculate optimal batch size for pagination
1069
+ *
1070
+ * @param totalItems - Total number of items to fetch
1071
+ * @param maxBatchSize - Maximum batch size (default: 100)
1072
+ * @returns Optimal batch size
1073
+ *
1074
+ * @example
1075
+ * ```typescript
1076
+ * const totalStakers = 250;
1077
+ * const batchSize = getOptimalBatchSize(totalStakers);
1078
+ * // Returns 50 (250 / 5 batches)
1079
+ * ```
1080
+ */
1081
+ declare function getOptimalBatchSize(totalItems: number, maxBatchSize?: number): number;
1082
+ /**
1083
+ * Format large numbers with commas
1084
+ *
1085
+ * @param value - Number or string to format
1086
+ * @returns Formatted string with commas
1087
+ *
1088
+ * @example
1089
+ * ```typescript
1090
+ * const staking = stats.TotalStaking;
1091
+ * console.log(formatNumber(staking)); // "26,883,345,073,055,930,973,683,712"
1092
+ * ```
1093
+ */
1094
+ declare function formatNumber(value: string | number): string;
1095
+ /**
1096
+ * Convert Wei to Ether string
1097
+ *
1098
+ * @param wei - Wei amount as string
1099
+ * @param decimals - Number of decimal places (default: 4)
1100
+ * @returns Ether amount as string
1101
+ *
1102
+ * @example
1103
+ * ```typescript
1104
+ * const stake = "4000000000000000000000000";
1105
+ * console.log(weiToEther(stake)); // "4000000.0000"
1106
+ * ```
1107
+ */
1108
+ declare function weiToEther(wei: string, decimals?: number): string;
1109
+
1110
+ /**
1111
+ * Retry Utilities
1112
+ *
1113
+ * Provides retry logic with exponential backoff for handling
1114
+ * transient errors and timeouts.
1115
+ */
1116
+ interface RetryOptions {
1117
+ /**
1118
+ * Maximum number of retry attempts
1119
+ * @default 3
1120
+ */
1121
+ maxRetries?: number;
1122
+ /**
1123
+ * Initial delay in milliseconds before first retry
1124
+ * @default 1000
1125
+ */
1126
+ initialDelay?: number;
1127
+ /**
1128
+ * Maximum delay in milliseconds between retries
1129
+ * @default 10000
1130
+ */
1131
+ maxDelay?: number;
1132
+ /**
1133
+ * Backoff multiplier for exponential backoff
1134
+ * @default 2
1135
+ */
1136
+ backoffMultiplier?: number;
1137
+ /**
1138
+ * Function to determine if error should be retried
1139
+ * @default Retries on timeout and 503 errors
1140
+ */
1141
+ shouldRetry?: (error: any, attempt: number) => boolean;
1142
+ /**
1143
+ * Callback called before each retry
1144
+ */
1145
+ onRetry?: (error: any, attempt: number, delay: number) => void;
1146
+ }
1147
+ /**
1148
+ * Execute a function with retry logic
1149
+ *
1150
+ * @param fn - Async function to execute
1151
+ * @param options - Retry options
1152
+ * @returns Promise resolving to function result
1153
+ *
1154
+ * @example
1155
+ * ```typescript
1156
+ * const result = await withRetry(
1157
+ * () => sdk.analytics.getValidatorRewards(address, { limit: 100 }),
1158
+ * {
1159
+ * maxRetries: 3,
1160
+ * initialDelay: 1000,
1161
+ * onRetry: (error, attempt, delay) => {
1162
+ * console.log(`Retry attempt ${attempt} after ${delay}ms`);
1163
+ * }
1164
+ * }
1165
+ * );
1166
+ * ```
1167
+ */
1168
+ declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
1169
+ /**
1170
+ * Create a retry wrapper for a function
1171
+ *
1172
+ * @param fn - Function to wrap
1173
+ * @param options - Retry options
1174
+ * @returns Wrapped function with retry logic
1175
+ *
1176
+ * @example
1177
+ * ```typescript
1178
+ * const getRewardsWithRetry = createRetryWrapper(
1179
+ * (address: string, opts: any) => sdk.analytics.getValidatorRewards(address, opts),
1180
+ * { maxRetries: 3 }
1181
+ * );
1182
+ *
1183
+ * const rewards = await getRewardsWithRetry(address, { limit: 50 });
1184
+ * ```
1185
+ */
1186
+ declare function createRetryWrapper<T extends (...args: any[]) => Promise<any>>(fn: T, options?: RetryOptions): T;
1187
+
878
1188
  /**
879
1189
  * Resonance Network SDK
880
1190
  *
@@ -934,4 +1244,4 @@ declare class ResonanceSDK {
934
1244
  logout(): void;
935
1245
  }
936
1246
 
937
- export { type APIError, type APIResponse, type ActiveValidator, AnalyticsAPI, type AuthResponse, AuthService, type DelegatorDetailResponse, type DelegatorListResponse, type DelegatorReward, type DelegatorRewardsResponse, type DelegatorStakeInfo, type DelegatorStakesResponse, type DelegatorUnbondingResponse, type DelegatorValidatorStake, type DelegatorValidatorsResponse, type DelegatorWithdrawal, type DelegatorWithdrawalsResponse, DelegatorsAPI, type EpochDistribution, type EpochReward, type EpochStakes, type EpochUnclaimed, GlobalAPI, type GlobalNetworkResponse, HTTPClient, type JWTClaims, type LeaderboardDelegatorResponse, type LeaderboardValidatorResponse, type NetworkAPRBreakdownResponse, type NetworkAPRResponse, type PaginationOptions, type ProtocolStats, type QueryParams, type ReferralApplyRequest, type ReferralCreateRequest, type ReferralDelegatorResponse, type ReferralValidateRequest, type ReferralValidateResponse, type ReferralValidatorResponse, ReferralsAPI, ResonanceSDK, type ResponseMetadata, type RewardDTO, type RewardSummary, type SDKConfig, SlashingAPI, type SlashingEventResponse, type StakeDTO, type SyncJobStatus, type SyncStatusResponse, type TopDelegatorRank, type UnbondingInfo, type UnclaimedDelegator, type ValidatorAPRResponse, type ValidatorAnalytics, type ValidatorAnalyticsListResponse, type ValidatorDelegatorsResponse, type ValidatorDetailResponse, type ValidatorEpochResponse, type ValidatorHistoryItem, type ValidatorHistoryResponse, type ValidatorListOptions, type ValidatorListResponse, type ValidatorMetricsResponse, type ValidatorRewardsResponse, type ValidatorStakeBreakdownResponse, type ValidatorWithdrawal, type ValidatorWithdrawalsResponse, ValidatorsAPI, ResonanceSDK as default };
1247
+ export { type APIError, type APIResponse, type ActiveValidator, AnalyticsAPI, type AuthResponse, AuthService, type DelegatorDetailResponse, type DelegatorListResponse, type DelegatorReward, type DelegatorRewardsResponse, type DelegatorStakeInfo, type DelegatorStakesResponse, type DelegatorUnbondingResponse, type DelegatorValidatorStake, type DelegatorValidatorsResponse, type DelegatorWithdrawal, type DelegatorWithdrawalsResponse, DelegatorsAPI, type EpochDistribution, type EpochReward, type EpochStakes, type EpochUnclaimed, GlobalAPI, type GlobalNetworkResponse, HTTPClient, type JWTClaims, type LeaderboardDelegatorResponse, type LeaderboardValidatorResponse, type NetworkAPRBreakdownResponse, type NetworkAPRResponse, type PaginationOptions, type ProtocolStats, type QueryParams, type ReferralApplyRequest, type ReferralCreateRequest, type ReferralDelegatorResponse, type ReferralValidateRequest, type ReferralValidateResponse, type ReferralValidatorResponse, ReferralsAPI, ResonanceSDK, type ResponseMetadata, type RetryOptions, type RewardDTO, type RewardSummary, type SDKConfig, SlashingAPI, type SlashingEventResponse, type StakeDTO, type SyncJobStatus, type SyncStatusResponse, type TopDelegatorRank, type UnbondingInfo, type UnclaimedDelegator, type ValidatorAPRResponse, type ValidatorAnalytics, type ValidatorAnalyticsListResponse, type ValidatorDelegatorsResponse, type ValidatorDetailResponse, type ValidatorEpochResponse, type ValidatorHistoryItem, type ValidatorHistoryResponse, type ValidatorListOptions, type ValidatorListResponse, type ValidatorMetricsResponse, type ValidatorRewardsResponse, type ValidatorStakeBreakdownResponse, type ValidatorWithdrawal, type ValidatorWithdrawalsResponse, ValidatorsAPI, createRetryWrapper, ResonanceSDK as default, formatNumber, getDataFreshness, getOptimalBatchSize, getSyncLag, isCachedData, isServiceUnavailable, isStaleData, isSyncDegraded, isSyncHealthy, isTimeout, isValidatorNotFound, validatePagination, weiToEther, withRetry };
package/dist/index.js CHANGED
@@ -29,7 +29,22 @@ __export(index_exports, {
29
29
  ResonanceSDK: () => ResonanceSDK,
30
30
  SlashingAPI: () => SlashingAPI,
31
31
  ValidatorsAPI: () => ValidatorsAPI,
32
- default: () => index_default
32
+ createRetryWrapper: () => createRetryWrapper,
33
+ default: () => index_default,
34
+ formatNumber: () => formatNumber,
35
+ getDataFreshness: () => getDataFreshness,
36
+ getOptimalBatchSize: () => getOptimalBatchSize,
37
+ getSyncLag: () => getSyncLag,
38
+ isCachedData: () => isCachedData,
39
+ isServiceUnavailable: () => isServiceUnavailable,
40
+ isStaleData: () => isStaleData,
41
+ isSyncDegraded: () => isSyncDegraded,
42
+ isSyncHealthy: () => isSyncHealthy,
43
+ isTimeout: () => isTimeout,
44
+ isValidatorNotFound: () => isValidatorNotFound,
45
+ validatePagination: () => validatePagination,
46
+ weiToEther: () => weiToEther,
47
+ withRetry: () => withRetry
33
48
  });
34
49
  module.exports = __toCommonJS(index_exports);
35
50
 
@@ -927,6 +942,120 @@ var AnalyticsAPI = class {
927
942
  }
928
943
  };
929
944
 
945
+ // src/utils/analytics-helpers.ts
946
+ function isValidatorNotFound(error) {
947
+ return error instanceof ResonanceAPIError && error.statusCode === 404;
948
+ }
949
+ function isServiceUnavailable(error) {
950
+ return error instanceof ResonanceAPIError && error.statusCode === 503;
951
+ }
952
+ function isTimeout(error) {
953
+ return error instanceof Error && error.message.includes("timeout");
954
+ }
955
+ function isStaleData(response) {
956
+ return response.metadata?.stale === true;
957
+ }
958
+ function isCachedData(response) {
959
+ return response.metadata?.cached === true;
960
+ }
961
+ function isSyncHealthy(syncStatus, workerName = "protocol_sync") {
962
+ const worker = syncStatus[workerName];
963
+ return worker?.status === "success";
964
+ }
965
+ function isSyncDegraded(syncStatus, workerName = "protocol_sync") {
966
+ const worker = syncStatus[workerName];
967
+ return worker?.status === "degraded";
968
+ }
969
+ function getSyncLag(syncStatus, currentBlock, workerName = "protocol_sync") {
970
+ const worker = syncStatus[workerName];
971
+ if (!worker?.last_block) return null;
972
+ return currentBlock - worker.last_block;
973
+ }
974
+ function getDataFreshness(response, currentBlock) {
975
+ const subgraphBlock = response.metadata?.subgraph_block;
976
+ if (!subgraphBlock) return 0;
977
+ const blocksBehind = currentBlock - subgraphBlock;
978
+ if (blocksBehind <= 0) return 100;
979
+ if (blocksBehind <= 10) return 100 - blocksBehind;
980
+ if (blocksBehind <= 100) return 90 - Math.floor((blocksBehind - 10) * 0.44);
981
+ return Math.max(0, 50 - Math.floor((blocksBehind - 100) * 0.5));
982
+ }
983
+ function validatePagination(limit, offset) {
984
+ if (limit !== void 0 && (limit <= 0 || limit > 1e3)) {
985
+ throw new Error("Limit must be between 1 and 1000");
986
+ }
987
+ if (offset !== void 0 && offset < 0) {
988
+ throw new Error("Offset must be non-negative");
989
+ }
990
+ }
991
+ function getOptimalBatchSize(totalItems, maxBatchSize = 100) {
992
+ if (totalItems <= maxBatchSize) return totalItems;
993
+ const targetBatches = 7;
994
+ const calculatedSize = Math.ceil(totalItems / targetBatches);
995
+ return Math.min(calculatedSize, maxBatchSize);
996
+ }
997
+ function formatNumber(value) {
998
+ const num = typeof value === "string" ? value : value.toString();
999
+ return num.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1000
+ }
1001
+ function weiToEther(wei, decimals = 4) {
1002
+ const weiNum = BigInt(wei);
1003
+ const etherNum = Number(weiNum) / 1e18;
1004
+ return etherNum.toFixed(decimals);
1005
+ }
1006
+
1007
+ // src/utils/retry.ts
1008
+ function defaultShouldRetry(error, attempt) {
1009
+ if (attempt >= 3) return false;
1010
+ if (error instanceof Error && error.message.includes("timeout")) {
1011
+ return true;
1012
+ }
1013
+ if (error.statusCode === 503) {
1014
+ return true;
1015
+ }
1016
+ if (error instanceof Error && error.message.includes("fetch failed")) {
1017
+ return true;
1018
+ }
1019
+ return false;
1020
+ }
1021
+ async function withRetry(fn, options = {}) {
1022
+ const {
1023
+ maxRetries = 3,
1024
+ initialDelay = 1e3,
1025
+ maxDelay = 1e4,
1026
+ backoffMultiplier = 2,
1027
+ shouldRetry = defaultShouldRetry,
1028
+ onRetry
1029
+ } = options;
1030
+ let lastError;
1031
+ let delay = initialDelay;
1032
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
1033
+ try {
1034
+ return await fn();
1035
+ } catch (error) {
1036
+ lastError = error;
1037
+ if (attempt < maxRetries && shouldRetry(error, attempt)) {
1038
+ if (onRetry) {
1039
+ onRetry(error, attempt + 1, delay);
1040
+ }
1041
+ await sleep(delay);
1042
+ delay = Math.min(delay * backoffMultiplier, maxDelay);
1043
+ } else {
1044
+ throw error;
1045
+ }
1046
+ }
1047
+ }
1048
+ throw lastError;
1049
+ }
1050
+ function sleep(ms) {
1051
+ return new Promise((resolve) => setTimeout(resolve, ms));
1052
+ }
1053
+ function createRetryWrapper(fn, options = {}) {
1054
+ return ((...args) => {
1055
+ return withRetry(() => fn(...args), options);
1056
+ });
1057
+ }
1058
+
930
1059
  // src/index.ts
931
1060
  var ResonanceSDK = class {
932
1061
  constructor(config) {
@@ -985,5 +1114,20 @@ var index_default = ResonanceSDK;
985
1114
  ReferralsAPI,
986
1115
  ResonanceSDK,
987
1116
  SlashingAPI,
988
- ValidatorsAPI
1117
+ ValidatorsAPI,
1118
+ createRetryWrapper,
1119
+ formatNumber,
1120
+ getDataFreshness,
1121
+ getOptimalBatchSize,
1122
+ getSyncLag,
1123
+ isCachedData,
1124
+ isServiceUnavailable,
1125
+ isStaleData,
1126
+ isSyncDegraded,
1127
+ isSyncHealthy,
1128
+ isTimeout,
1129
+ isValidatorNotFound,
1130
+ validatePagination,
1131
+ weiToEther,
1132
+ withRetry
989
1133
  });
package/dist/index.mjs CHANGED
@@ -892,6 +892,120 @@ var AnalyticsAPI = class {
892
892
  }
893
893
  };
894
894
 
895
+ // src/utils/analytics-helpers.ts
896
+ function isValidatorNotFound(error) {
897
+ return error instanceof ResonanceAPIError && error.statusCode === 404;
898
+ }
899
+ function isServiceUnavailable(error) {
900
+ return error instanceof ResonanceAPIError && error.statusCode === 503;
901
+ }
902
+ function isTimeout(error) {
903
+ return error instanceof Error && error.message.includes("timeout");
904
+ }
905
+ function isStaleData(response) {
906
+ return response.metadata?.stale === true;
907
+ }
908
+ function isCachedData(response) {
909
+ return response.metadata?.cached === true;
910
+ }
911
+ function isSyncHealthy(syncStatus, workerName = "protocol_sync") {
912
+ const worker = syncStatus[workerName];
913
+ return worker?.status === "success";
914
+ }
915
+ function isSyncDegraded(syncStatus, workerName = "protocol_sync") {
916
+ const worker = syncStatus[workerName];
917
+ return worker?.status === "degraded";
918
+ }
919
+ function getSyncLag(syncStatus, currentBlock, workerName = "protocol_sync") {
920
+ const worker = syncStatus[workerName];
921
+ if (!worker?.last_block) return null;
922
+ return currentBlock - worker.last_block;
923
+ }
924
+ function getDataFreshness(response, currentBlock) {
925
+ const subgraphBlock = response.metadata?.subgraph_block;
926
+ if (!subgraphBlock) return 0;
927
+ const blocksBehind = currentBlock - subgraphBlock;
928
+ if (blocksBehind <= 0) return 100;
929
+ if (blocksBehind <= 10) return 100 - blocksBehind;
930
+ if (blocksBehind <= 100) return 90 - Math.floor((blocksBehind - 10) * 0.44);
931
+ return Math.max(0, 50 - Math.floor((blocksBehind - 100) * 0.5));
932
+ }
933
+ function validatePagination(limit, offset) {
934
+ if (limit !== void 0 && (limit <= 0 || limit > 1e3)) {
935
+ throw new Error("Limit must be between 1 and 1000");
936
+ }
937
+ if (offset !== void 0 && offset < 0) {
938
+ throw new Error("Offset must be non-negative");
939
+ }
940
+ }
941
+ function getOptimalBatchSize(totalItems, maxBatchSize = 100) {
942
+ if (totalItems <= maxBatchSize) return totalItems;
943
+ const targetBatches = 7;
944
+ const calculatedSize = Math.ceil(totalItems / targetBatches);
945
+ return Math.min(calculatedSize, maxBatchSize);
946
+ }
947
+ function formatNumber(value) {
948
+ const num = typeof value === "string" ? value : value.toString();
949
+ return num.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
950
+ }
951
+ function weiToEther(wei, decimals = 4) {
952
+ const weiNum = BigInt(wei);
953
+ const etherNum = Number(weiNum) / 1e18;
954
+ return etherNum.toFixed(decimals);
955
+ }
956
+
957
+ // src/utils/retry.ts
958
+ function defaultShouldRetry(error, attempt) {
959
+ if (attempt >= 3) return false;
960
+ if (error instanceof Error && error.message.includes("timeout")) {
961
+ return true;
962
+ }
963
+ if (error.statusCode === 503) {
964
+ return true;
965
+ }
966
+ if (error instanceof Error && error.message.includes("fetch failed")) {
967
+ return true;
968
+ }
969
+ return false;
970
+ }
971
+ async function withRetry(fn, options = {}) {
972
+ const {
973
+ maxRetries = 3,
974
+ initialDelay = 1e3,
975
+ maxDelay = 1e4,
976
+ backoffMultiplier = 2,
977
+ shouldRetry = defaultShouldRetry,
978
+ onRetry
979
+ } = options;
980
+ let lastError;
981
+ let delay = initialDelay;
982
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
983
+ try {
984
+ return await fn();
985
+ } catch (error) {
986
+ lastError = error;
987
+ if (attempt < maxRetries && shouldRetry(error, attempt)) {
988
+ if (onRetry) {
989
+ onRetry(error, attempt + 1, delay);
990
+ }
991
+ await sleep(delay);
992
+ delay = Math.min(delay * backoffMultiplier, maxDelay);
993
+ } else {
994
+ throw error;
995
+ }
996
+ }
997
+ }
998
+ throw lastError;
999
+ }
1000
+ function sleep(ms) {
1001
+ return new Promise((resolve) => setTimeout(resolve, ms));
1002
+ }
1003
+ function createRetryWrapper(fn, options = {}) {
1004
+ return ((...args) => {
1005
+ return withRetry(() => fn(...args), options);
1006
+ });
1007
+ }
1008
+
895
1009
  // src/index.ts
896
1010
  var ResonanceSDK = class {
897
1011
  constructor(config) {
@@ -950,5 +1064,20 @@ export {
950
1064
  ResonanceSDK,
951
1065
  SlashingAPI,
952
1066
  ValidatorsAPI,
953
- index_default as default
1067
+ createRetryWrapper,
1068
+ index_default as default,
1069
+ formatNumber,
1070
+ getDataFreshness,
1071
+ getOptimalBatchSize,
1072
+ getSyncLag,
1073
+ isCachedData,
1074
+ isServiceUnavailable,
1075
+ isStaleData,
1076
+ isSyncDegraded,
1077
+ isSyncHealthy,
1078
+ isTimeout,
1079
+ isValidatorNotFound,
1080
+ validatePagination,
1081
+ weiToEther,
1082
+ withRetry
954
1083
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fenelabs/fene-sdk",
3
- "version": "0.3.0",
4
- "description": "Resonance Network SDK for TypeScript/JavaScript - Official SDK for interacting with Resonance FPoS blockchain",
3
+ "version": "0.3.2",
4
+ "description": "Fene Network SDK for interacting with Resonance FPoS blockchain",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
@@ -44,18 +44,21 @@
44
44
  "web3",
45
45
  "validator",
46
46
  "delegator",
47
+ "dpos",
48
+ "organization",
49
+ "politics",
47
50
  "typescript"
48
51
  ],
49
52
  "author": "avenbreaks",
50
53
  "license": "MIT",
51
54
  "repository": {
52
55
  "type": "git",
53
- "url": "https://github.com/avenbreaks/resonance-sdk.git"
56
+ "url": "https://github.com/fenelabs/fene-sdk"
54
57
  },
55
58
  "bugs": {
56
- "url": "https://github.com/avenbreaks/resonance-sdk/issues"
59
+ "url": "https://github.com/fenelabs/fene-sdk/issues"
57
60
  },
58
- "homepage": "https://github.com/avenbreaks/resonance-sdk#readme",
61
+ "homepage": "https://github.com/fenelabs/fene-sdk#readme",
59
62
  "publishConfig": {
60
63
  "access": "public"
61
64
  },