@human-protocol/sdk 5.0.0 → 5.1.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.
Files changed (52) hide show
  1. package/dist/base.d.ts +1 -10
  2. package/dist/base.d.ts.map +1 -1
  3. package/dist/base.js +0 -21
  4. package/dist/constants.d.ts +0 -1
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/constants.js +1 -16
  7. package/dist/enums.d.ts +0 -1
  8. package/dist/enums.d.ts.map +1 -1
  9. package/dist/enums.js +0 -1
  10. package/dist/error.d.ts +4 -0
  11. package/dist/error.d.ts.map +1 -1
  12. package/dist/error.js +5 -1
  13. package/dist/escrow.d.ts +14 -17
  14. package/dist/escrow.d.ts.map +1 -1
  15. package/dist/escrow.js +34 -33
  16. package/dist/interfaces.d.ts +9 -0
  17. package/dist/interfaces.d.ts.map +1 -1
  18. package/dist/kvstore.d.ts +9 -5
  19. package/dist/kvstore.d.ts.map +1 -1
  20. package/dist/kvstore.js +15 -15
  21. package/dist/operator.d.ts +9 -5
  22. package/dist/operator.d.ts.map +1 -1
  23. package/dist/operator.js +16 -16
  24. package/dist/staking.d.ts +6 -3
  25. package/dist/staking.d.ts.map +1 -1
  26. package/dist/staking.js +13 -14
  27. package/dist/statistics.d.ts +13 -7
  28. package/dist/statistics.d.ts.map +1 -1
  29. package/dist/statistics.js +24 -22
  30. package/dist/transaction.d.ts +5 -3
  31. package/dist/transaction.d.ts.map +1 -1
  32. package/dist/transaction.js +8 -10
  33. package/dist/utils.d.ts +7 -0
  34. package/dist/utils.d.ts.map +1 -1
  35. package/dist/utils.js +51 -1
  36. package/dist/worker.d.ts +5 -3
  37. package/dist/worker.d.ts.map +1 -1
  38. package/dist/worker.js +8 -10
  39. package/package.json +2 -1
  40. package/src/base.ts +1 -23
  41. package/src/constants.ts +0 -18
  42. package/src/enums.ts +0 -1
  43. package/src/error.ts +7 -0
  44. package/src/escrow.ts +69 -64
  45. package/src/interfaces.ts +10 -0
  46. package/src/kvstore.ts +26 -24
  47. package/src/operator.ts +54 -26
  48. package/src/staking.ts +27 -26
  49. package/src/statistics.ts +87 -47
  50. package/src/transaction.ts +39 -25
  51. package/src/utils.ts +64 -0
  52. package/src/worker.ts +32 -17
@@ -1,6 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { ethers } from 'ethers';
3
- import gqlFetch from 'graphql-request';
4
3
  import { NETWORKS } from './constants';
5
4
  import { ChainId, OrderDirection } from './enums';
6
5
  import {
@@ -17,8 +16,9 @@ import {
17
16
  InternalTransaction,
18
17
  ITransaction,
19
18
  ITransactionsFilter,
19
+ SubgraphOptions,
20
20
  } from './interfaces';
21
- import { getSubgraphUrl, getUnixTimestamp } from './utils';
21
+ import { getSubgraphUrl, getUnixTimestamp, customGqlFetch } from './utils';
22
22
 
23
23
  export class TransactionUtils {
24
24
  /**
@@ -54,6 +54,7 @@ export class TransactionUtils {
54
54
  *
55
55
  * @param {ChainId} chainId The chain ID.
56
56
  * @param {string} hash The transaction hash.
57
+ * @param {SubgraphOptions} options Optional configuration for subgraph requests.
57
58
  * @returns {Promise<ITransaction | null>} - Returns the transaction details or null if not found.
58
59
  *
59
60
  * **Code example**
@@ -66,7 +67,8 @@ export class TransactionUtils {
66
67
  */
67
68
  public static async getTransaction(
68
69
  chainId: ChainId,
69
- hash: string
70
+ hash: string,
71
+ options?: SubgraphOptions
70
72
  ): Promise<ITransaction | null> {
71
73
  if (!ethers.isHexString(hash)) {
72
74
  throw ErrorInvalidHashProvided;
@@ -77,11 +79,16 @@ export class TransactionUtils {
77
79
  throw ErrorUnsupportedChainID;
78
80
  }
79
81
 
80
- const { transaction } = await gqlFetch<{
82
+ const { transaction } = await customGqlFetch<{
81
83
  transaction: TransactionData | null;
82
- }>(getSubgraphUrl(networkData), GET_TRANSACTION_QUERY, {
83
- hash: hash.toLowerCase(),
84
- });
84
+ }>(
85
+ getSubgraphUrl(networkData),
86
+ GET_TRANSACTION_QUERY,
87
+ {
88
+ hash: hash.toLowerCase(),
89
+ },
90
+ options
91
+ );
85
92
  if (!transaction) return null;
86
93
 
87
94
  return mapTransaction(transaction);
@@ -141,6 +148,7 @@ export class TransactionUtils {
141
148
  * ```
142
149
  *
143
150
  * @param {ITransactionsFilter} filter Filter for the transactions.
151
+ * @param {SubgraphOptions} options Optional configuration for subgraph requests.
144
152
  * @returns {Promise<ITransaction[]>} Returns an array with all the transaction details.
145
153
  *
146
154
  * **Code example**
@@ -160,7 +168,8 @@ export class TransactionUtils {
160
168
  * ```
161
169
  */
162
170
  public static async getTransactions(
163
- filter: ITransactionsFilter
171
+ filter: ITransactionsFilter,
172
+ options?: SubgraphOptions
164
173
  ): Promise<ITransaction[]> {
165
174
  if (
166
175
  (!!filter.startDate || !!filter.endDate) &&
@@ -179,24 +188,29 @@ export class TransactionUtils {
179
188
  throw ErrorUnsupportedChainID;
180
189
  }
181
190
 
182
- const { transactions } = await gqlFetch<{
191
+ const { transactions } = await customGqlFetch<{
183
192
  transactions: TransactionData[];
184
- }>(getSubgraphUrl(networkData), GET_TRANSACTIONS_QUERY(filter), {
185
- fromAddress: filter?.fromAddress,
186
- toAddress: filter?.toAddress,
187
- startDate: filter?.startDate
188
- ? getUnixTimestamp(filter?.startDate)
189
- : undefined,
190
- endDate: filter.endDate ? getUnixTimestamp(filter.endDate) : undefined,
191
- startBlock: filter.startBlock ? filter.startBlock : undefined,
192
- endBlock: filter.endBlock ? filter.endBlock : undefined,
193
- method: filter.method ? filter.method : undefined,
194
- escrow: filter.escrow ? filter.escrow : undefined,
195
- token: filter.token ? filter.token : undefined,
196
- orderDirection: orderDirection,
197
- first: first,
198
- skip: skip,
199
- });
193
+ }>(
194
+ getSubgraphUrl(networkData),
195
+ GET_TRANSACTIONS_QUERY(filter),
196
+ {
197
+ fromAddress: filter?.fromAddress,
198
+ toAddress: filter?.toAddress,
199
+ startDate: filter?.startDate
200
+ ? getUnixTimestamp(filter?.startDate)
201
+ : undefined,
202
+ endDate: filter.endDate ? getUnixTimestamp(filter.endDate) : undefined,
203
+ startBlock: filter.startBlock ? filter.startBlock : undefined,
204
+ endBlock: filter.endBlock ? filter.endBlock : undefined,
205
+ method: filter.method ? filter.method : undefined,
206
+ escrow: filter.escrow ? filter.escrow : undefined,
207
+ token: filter.token ? filter.token : undefined,
208
+ orderDirection: orderDirection,
209
+ first: first,
210
+ skip: skip,
211
+ },
212
+ options
213
+ );
200
214
 
201
215
  if (!transactions) {
202
216
  return [];
package/src/utils.ts CHANGED
@@ -1,11 +1,13 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import { ethers } from 'ethers';
3
+ import gqlFetch from 'graphql-request';
3
4
 
4
5
  import { isURL } from 'validator';
5
6
  import { SUBGRAPH_API_KEY_PLACEHOLDER } from './constants';
6
7
  import { ChainId } from './enums';
7
8
  import {
8
9
  ContractExecutionError,
10
+ ErrorRetryParametersMissing,
9
11
  EthereumError,
10
12
  InvalidArgumentError,
11
13
  NonceExpired,
@@ -15,6 +17,7 @@ import {
15
17
  WarnSubgraphApiKeyNotProvided,
16
18
  } from './error';
17
19
  import { NetworkData } from './types';
20
+ import { SubgraphOptions } from './interfaces';
18
21
 
19
22
  /**
20
23
  * **Handle and throw the error.*
@@ -99,3 +102,64 @@ export const getSubgraphUrl = (networkData: NetworkData) => {
99
102
  export const getUnixTimestamp = (date: Date): number => {
100
103
  return Math.floor(date.getTime() / 1000);
101
104
  };
105
+
106
+ export const isIndexerError = (error: any): boolean => {
107
+ if (!error) return false;
108
+
109
+ const errorMessage =
110
+ error.response?.errors?.[0]?.message ||
111
+ error.message ||
112
+ error.toString() ||
113
+ '';
114
+ return errorMessage.toLowerCase().includes('bad indexers');
115
+ };
116
+
117
+ const sleep = (ms: number): Promise<void> => {
118
+ return new Promise((resolve) => setTimeout(resolve, ms));
119
+ };
120
+
121
+ /**
122
+ * Execute a GraphQL request with automatic retry logic for bad indexer errors.
123
+ * Only retries if options is provided.
124
+ */
125
+ export const customGqlFetch = async <T = any>(
126
+ url: string,
127
+ query: any,
128
+ variables?: any,
129
+ options?: SubgraphOptions
130
+ ): Promise<T> => {
131
+ if (!options) {
132
+ return await gqlFetch<T>(url, query, variables);
133
+ }
134
+
135
+ if (
136
+ (options.maxRetries && options.baseDelay === undefined) ||
137
+ (options.baseDelay && options.maxRetries === undefined)
138
+ ) {
139
+ throw ErrorRetryParametersMissing;
140
+ }
141
+
142
+ let lastError: any;
143
+
144
+ for (let attempt = 0; attempt <= (options.maxRetries as number); attempt++) {
145
+ try {
146
+ const result = await gqlFetch<T>(url, query, variables);
147
+ return result;
148
+ } catch (error) {
149
+ lastError = error;
150
+
151
+ if (attempt === options.maxRetries) {
152
+ throw error;
153
+ }
154
+
155
+ if (!isIndexerError(error)) {
156
+ throw error;
157
+ }
158
+
159
+ const delay = (options.baseDelay as number) * attempt;
160
+ await sleep(delay);
161
+ }
162
+ }
163
+
164
+ throw lastError;
165
+ };
package/src/worker.ts CHANGED
@@ -1,12 +1,11 @@
1
1
  import { ethers } from 'ethers';
2
- import gqlFetch from 'graphql-request';
3
2
  import { NETWORKS } from './constants';
4
3
  import { ChainId, OrderDirection } from './enums';
5
4
  import { ErrorInvalidAddress, ErrorUnsupportedChainID } from './error';
6
5
  import { WorkerData } from './graphql';
7
6
  import { GET_WORKER_QUERY, GET_WORKERS_QUERY } from './graphql/queries/worker';
8
- import { IWorker, IWorkersFilter } from './interfaces';
9
- import { getSubgraphUrl } from './utils';
7
+ import { IWorker, IWorkersFilter, SubgraphOptions } from './interfaces';
8
+ import { getSubgraphUrl, customGqlFetch } from './utils';
10
9
 
11
10
  export class WorkerUtils {
12
11
  /**
@@ -14,6 +13,7 @@ export class WorkerUtils {
14
13
  *
15
14
  * @param {ChainId} chainId The chain ID.
16
15
  * @param {string} address The worker address.
16
+ * @param {SubgraphOptions} options Optional configuration for subgraph requests.
17
17
  * @returns {Promise<IWorker | null>} - Returns the worker details or null if not found.
18
18
  *
19
19
  * **Code example**
@@ -26,7 +26,8 @@ export class WorkerUtils {
26
26
  */
27
27
  public static async getWorker(
28
28
  chainId: ChainId,
29
- address: string
29
+ address: string,
30
+ options?: SubgraphOptions
30
31
  ): Promise<IWorker | null> {
31
32
  const networkData = NETWORKS[chainId];
32
33
 
@@ -37,11 +38,16 @@ export class WorkerUtils {
37
38
  throw ErrorInvalidAddress;
38
39
  }
39
40
 
40
- const { worker } = await gqlFetch<{
41
+ const { worker } = await customGqlFetch<{
41
42
  worker: WorkerData | null;
42
- }>(getSubgraphUrl(networkData), GET_WORKER_QUERY, {
43
- address: address.toLowerCase(),
44
- });
43
+ }>(
44
+ getSubgraphUrl(networkData),
45
+ GET_WORKER_QUERY,
46
+ {
47
+ address: address.toLowerCase(),
48
+ },
49
+ options
50
+ );
45
51
 
46
52
  if (!worker) return null;
47
53
 
@@ -74,6 +80,7 @@ export class WorkerUtils {
74
80
  * ```
75
81
  *
76
82
  * @param {IWorkersFilter} filter Filter for the workers.
83
+ * @param {SubgraphOptions} options Optional configuration for subgraph requests.
77
84
  * @returns {Promise<IWorker[]>} Returns an array with all the worker details.
78
85
  *
79
86
  * **Code example**
@@ -89,7 +96,10 @@ export class WorkerUtils {
89
96
  * const workers = await WorkerUtils.getWorkers(filter);
90
97
  * ```
91
98
  */
92
- public static async getWorkers(filter: IWorkersFilter): Promise<IWorker[]> {
99
+ public static async getWorkers(
100
+ filter: IWorkersFilter,
101
+ options?: SubgraphOptions
102
+ ): Promise<IWorker[]> {
93
103
  const first =
94
104
  filter.first !== undefined ? Math.min(filter.first, 1000) : 10;
95
105
  const skip = filter.skip || 0;
@@ -104,15 +114,20 @@ export class WorkerUtils {
104
114
  throw ErrorInvalidAddress;
105
115
  }
106
116
 
107
- const { workers } = await gqlFetch<{
117
+ const { workers } = await customGqlFetch<{
108
118
  workers: WorkerData[];
109
- }>(getSubgraphUrl(networkData), GET_WORKERS_QUERY(filter), {
110
- address: filter?.address?.toLowerCase(),
111
- first: first,
112
- skip: skip,
113
- orderBy: orderBy,
114
- orderDirection: orderDirection,
115
- });
119
+ }>(
120
+ getSubgraphUrl(networkData),
121
+ GET_WORKERS_QUERY(filter),
122
+ {
123
+ address: filter?.address?.toLowerCase(),
124
+ first: first,
125
+ skip: skip,
126
+ orderBy: orderBy,
127
+ orderDirection: orderDirection,
128
+ },
129
+ options
130
+ );
116
131
 
117
132
  if (!workers) {
118
133
  return [];