@human-protocol/sdk 2.1.3 → 3.0.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 (54) hide show
  1. package/dist/constants.d.ts +1 -0
  2. package/dist/constants.d.ts.map +1 -1
  3. package/dist/constants.js +56 -24
  4. package/dist/enums.d.ts +3 -2
  5. package/dist/enums.d.ts.map +1 -1
  6. package/dist/enums.js +2 -1
  7. package/dist/error.d.ts +9 -0
  8. package/dist/error.d.ts.map +1 -1
  9. package/dist/error.js +11 -2
  10. package/dist/escrow.d.ts +1 -2
  11. package/dist/escrow.d.ts.map +1 -1
  12. package/dist/escrow.js +3 -4
  13. package/dist/graphql/queries/kvstore.d.ts +2 -0
  14. package/dist/graphql/queries/kvstore.d.ts.map +1 -0
  15. package/dist/graphql/queries/kvstore.js +28 -0
  16. package/dist/graphql/queries/transaction.d.ts +4 -0
  17. package/dist/graphql/queries/transaction.d.ts.map +1 -0
  18. package/dist/graphql/queries/transaction.js +59 -0
  19. package/dist/graphql/types.d.ts +8 -0
  20. package/dist/graphql/types.d.ts.map +1 -1
  21. package/dist/interfaces.d.ts +23 -1
  22. package/dist/interfaces.d.ts.map +1 -1
  23. package/dist/kvstore.d.ts +84 -0
  24. package/dist/kvstore.d.ts.map +1 -1
  25. package/dist/kvstore.js +103 -1
  26. package/dist/operator.d.ts +5 -2
  27. package/dist/operator.d.ts.map +1 -1
  28. package/dist/operator.js +50 -22
  29. package/dist/statistics.d.ts +1 -0
  30. package/dist/statistics.d.ts.map +1 -1
  31. package/dist/statistics.js +8 -7
  32. package/dist/transaction.d.ts +69 -0
  33. package/dist/transaction.d.ts.map +1 -0
  34. package/dist/transaction.js +121 -0
  35. package/dist/types.d.ts +4 -0
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/utils.d.ts +9 -0
  38. package/dist/utils.d.ts.map +1 -1
  39. package/dist/utils.js +21 -1
  40. package/package.json +4 -4
  41. package/src/constants.ts +73 -23
  42. package/src/enums.ts +2 -1
  43. package/src/error.ts +15 -0
  44. package/src/escrow.ts +4 -5
  45. package/src/graphql/queries/kvstore.ts +23 -0
  46. package/src/graphql/queries/transaction.ts +59 -0
  47. package/src/graphql/types.ts +9 -0
  48. package/src/interfaces.ts +26 -1
  49. package/src/kvstore.ts +114 -1
  50. package/src/operator.ts +62 -29
  51. package/src/statistics.ts +10 -8
  52. package/src/transaction.ts +142 -0
  53. package/src/types.ts +4 -0
  54. package/src/utils.ts +25 -0
package/src/operator.ts CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  ErrorInvalidStakerAddressProvided,
22
22
  ErrorUnsupportedChainID,
23
23
  } from './error';
24
- import { throwError } from './utils';
24
+ import { getSubgraphUrl, throwError } from './utils';
25
25
  import { ChainId } from './enums';
26
26
  import { NETWORKS } from './constants';
27
27
 
@@ -57,13 +57,21 @@ export class OperatorUtils {
57
57
  try {
58
58
  const { leader } = await gqlFetch<{
59
59
  leader: ILeaderSubgraph;
60
- }>(networkData.subgraphUrl, GET_LEADER_QUERY, {
60
+ }>(getSubgraphUrl(networkData), GET_LEADER_QUERY, {
61
61
  address: address.toLowerCase(),
62
62
  });
63
63
 
64
+ let jobTypes: string[] = [];
65
+
66
+ if (typeof leader.jobTypes === 'string') {
67
+ jobTypes = leader.jobTypes.split(',');
68
+ } else if (Array.isArray(leader.jobTypes)) {
69
+ jobTypes = leader.jobTypes;
70
+ }
71
+
64
72
  return {
65
73
  ...leader,
66
- jobTypes: leader.jobTypes?.split(','),
74
+ jobTypes,
67
75
  };
68
76
  } catch (e) {
69
77
  return throwError(e);
@@ -82,33 +90,48 @@ export class OperatorUtils {
82
90
  * ```ts
83
91
  * import { OperatorUtils } from '@human-protocol/sdk';
84
92
  *
85
- * const leaders = await OperatorUtils.getLeaders();
93
+ * const filter: ILeadersFilter = {
94
+ * chainId: ChainId.POLYGON
95
+ * };
96
+ * const leaders = await OperatorUtils.getLeaders(filter);
86
97
  * ```
87
98
  */
88
- public static async getLeaders(
89
- filter: ILeadersFilter = { networks: [ChainId.POLYGON_AMOY] }
90
- ): Promise<ILeader[]> {
99
+ public static async getLeaders(filter: ILeadersFilter): Promise<ILeader[]> {
91
100
  try {
92
101
  let leaders_data: ILeader[] = [];
93
- for (const chainId of filter.networks) {
94
- const networkData = NETWORKS[chainId];
95
102
 
96
- if (!networkData) {
97
- throw ErrorUnsupportedChainID;
98
- }
99
- const { leaders } = await gqlFetch<{
100
- leaders: ILeaderSubgraph[];
101
- }>(networkData.subgraphUrl, GET_LEADERS_QUERY(filter), {
102
- role: filter.role,
103
- });
104
- leaders_data = leaders_data.concat(
105
- leaders.map((leader) => ({
106
- ...leader,
107
- jobTypes: leader.jobTypes?.split(','),
108
- }))
109
- );
103
+ const networkData = NETWORKS[filter.chainId];
104
+
105
+ if (!networkData) {
106
+ throw ErrorUnsupportedChainID;
107
+ }
108
+
109
+ const { leaders } = await gqlFetch<{
110
+ leaders: ILeaderSubgraph[];
111
+ }>(getSubgraphUrl(networkData), GET_LEADERS_QUERY(filter), {
112
+ role: filter?.role,
113
+ });
114
+
115
+ if (!leaders) {
116
+ return [];
110
117
  }
111
118
 
119
+ leaders_data = leaders_data.concat(
120
+ leaders.map((leader) => {
121
+ let jobTypes: string[] = [];
122
+
123
+ if (typeof leader.jobTypes === 'string') {
124
+ jobTypes = leader.jobTypes.split(',');
125
+ } else if (Array.isArray(leader.jobTypes)) {
126
+ jobTypes = leader.jobTypes;
127
+ }
128
+
129
+ return {
130
+ ...leader,
131
+ jobTypes,
132
+ };
133
+ })
134
+ );
112
135
  return leaders_data;
113
136
  } catch (e) {
114
137
  return throwError(e);
@@ -142,15 +165,25 @@ export class OperatorUtils {
142
165
  try {
143
166
  const { reputationNetwork } = await gqlFetch<{
144
167
  reputationNetwork: IReputationNetworkSubgraph;
145
- }>(networkData.subgraphUrl, GET_REPUTATION_NETWORK_QUERY(role), {
168
+ }>(getSubgraphUrl(networkData), GET_REPUTATION_NETWORK_QUERY(role), {
146
169
  address: address.toLowerCase(),
147
170
  role: role,
148
171
  });
149
172
 
150
- return reputationNetwork.operators.map((operator) => ({
151
- ...operator,
152
- jobTypes: operator.jobTypes?.split(','),
153
- }));
173
+ return reputationNetwork.operators.map((operator) => {
174
+ let jobTypes: string[] = [];
175
+
176
+ if (typeof operator.jobTypes === 'string') {
177
+ jobTypes = operator.jobTypes.split(',');
178
+ } else if (Array.isArray(operator.jobTypes)) {
179
+ jobTypes = operator.jobTypes;
180
+ }
181
+
182
+ return {
183
+ ...operator,
184
+ jobTypes,
185
+ };
186
+ });
154
187
  } catch (e) {
155
188
  return throwError(e);
156
189
  }
@@ -187,7 +220,7 @@ export class OperatorUtils {
187
220
  try {
188
221
  const { rewardAddedEvents } = await gqlFetch<{
189
222
  rewardAddedEvents: RewardAddedEventData[];
190
- }>(networkData.subgraphUrl, GET_REWARD_ADDED_EVENTS_QUERY, {
223
+ }>(getSubgraphUrl(networkData), GET_REWARD_ADDED_EVENTS_QUERY, {
191
224
  slasherAddress: slasherAddress.toLowerCase(),
192
225
  });
193
226
 
package/src/statistics.ts CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  } from './graphql';
19
19
  import { IStatisticsParams } from './interfaces';
20
20
  import { NetworkData } from './types';
21
- import { throwError } from './utils';
21
+ import { getSubgraphUrl, throwError } from './utils';
22
22
 
23
23
  /**
24
24
  * ## Introduction
@@ -59,6 +59,7 @@ import { throwError } from './utils';
59
59
  */
60
60
  export class StatisticsClient {
61
61
  public networkData: NetworkData;
62
+ public subgraphUrl: string;
62
63
 
63
64
  /**
64
65
  * **StatisticsClient constructor**
@@ -67,6 +68,7 @@ export class StatisticsClient {
67
68
  */
68
69
  constructor(networkData: NetworkData) {
69
70
  this.networkData = networkData;
71
+ this.subgraphUrl = getSubgraphUrl(networkData);
70
72
  }
71
73
 
72
74
  /**
@@ -124,11 +126,11 @@ export class StatisticsClient {
124
126
  try {
125
127
  const { escrowStatistics } = await gqlFetch<{
126
128
  escrowStatistics: EscrowStatisticsData;
127
- }>(this.networkData.subgraphUrl, GET_ESCROW_STATISTICS_QUERY);
129
+ }>(this.subgraphUrl, GET_ESCROW_STATISTICS_QUERY);
128
130
 
129
131
  const { eventDayDatas } = await gqlFetch<{
130
132
  eventDayDatas: EventDayData[];
131
- }>(this.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
133
+ }>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
132
134
  from: params.from ? params.from.getTime() / 1000 : undefined,
133
135
  to: params.to ? params.to.getTime() / 1000 : undefined,
134
136
  });
@@ -199,7 +201,7 @@ export class StatisticsClient {
199
201
  try {
200
202
  const { eventDayDatas } = await gqlFetch<{
201
203
  eventDayDatas: EventDayData[];
202
- }>(this.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
204
+ }>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
203
205
  from: params.from ? params.from.getTime() / 1000 : undefined,
204
206
  to: params.to ? params.to.getTime() / 1000 : undefined,
205
207
  });
@@ -288,7 +290,7 @@ export class StatisticsClient {
288
290
  try {
289
291
  const { eventDayDatas } = await gqlFetch<{
290
292
  eventDayDatas: EventDayData[];
291
- }>(this.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
293
+ }>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
292
294
  from: params.from ? params.from.getTime() / 1000 : undefined,
293
295
  to: params.to ? params.to.getTime() / 1000 : undefined,
294
296
  });
@@ -397,15 +399,15 @@ export class StatisticsClient {
397
399
  try {
398
400
  const { hmtokenStatistics } = await gqlFetch<{
399
401
  hmtokenStatistics: HMTStatisticsData;
400
- }>(this.networkData.subgraphUrl, GET_HMTOKEN_STATISTICS_QUERY);
402
+ }>(this.subgraphUrl, GET_HMTOKEN_STATISTICS_QUERY);
401
403
 
402
404
  const { holders } = await gqlFetch<{
403
405
  holders: HMTHolderData[];
404
- }>(this.networkData.subgraphUrl, GET_HOLDERS_QUERY);
406
+ }>(this.subgraphUrl, GET_HOLDERS_QUERY);
405
407
 
406
408
  const { eventDayDatas } = await gqlFetch<{
407
409
  eventDayDatas: EventDayData[];
408
- }>(this.networkData.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
410
+ }>(this.subgraphUrl, GET_EVENT_DAY_DATA_QUERY(params), {
409
411
  from: params.from ? params.from.getTime() / 1000 : undefined,
410
412
  to: params.to ? params.to.getTime() / 1000 : undefined,
411
413
  });
@@ -0,0 +1,142 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { ethers } from 'ethers';
3
+ import gqlFetch from 'graphql-request';
4
+ import { NETWORKS } from './constants';
5
+ import { ChainId } from './enums';
6
+ import {
7
+ ErrorCannotUseDateAndBlockSimultaneously,
8
+ ErrorInvalidHahsProvided,
9
+ ErrorUnsupportedChainID,
10
+ } from './error';
11
+ import {
12
+ GET_TRANSACTIONS_QUERY,
13
+ GET_TRANSACTION_QUERY,
14
+ } from './graphql/queries/transaction';
15
+ import { ITransaction, ITransactionsFilter } from './interfaces';
16
+ import { getSubgraphUrl } from './utils';
17
+
18
+ export class TransactionUtils {
19
+ /**
20
+ * This function returns the transaction data for the given hash.
21
+ *
22
+ * @param {ChainId} chainId The chain ID.
23
+ * @param {string} hash The transaction hash.
24
+ * @returns {Promise<ITransaction>} Returns the transaction details.
25
+ *
26
+ * **Code example**
27
+ *
28
+ * ```ts
29
+ * import { TransactionUtils, ChainId } from '@human-protocol/sdk';
30
+ *
31
+ * const transaction = await TransactionUtils.getTransaction(ChainId.POLYGON, '0x62dD51230A30401C455c8398d06F85e4EaB6309f');
32
+ * ```
33
+ */
34
+ public static async getTransaction(
35
+ chainId: ChainId,
36
+ hash: string
37
+ ): Promise<ITransaction> {
38
+ if (!ethers.isHexString(hash)) {
39
+ throw ErrorInvalidHahsProvided;
40
+ }
41
+ const networkData = NETWORKS[chainId];
42
+
43
+ if (!networkData) {
44
+ throw ErrorUnsupportedChainID;
45
+ }
46
+
47
+ const { transaction } = await gqlFetch<{
48
+ transaction: ITransaction;
49
+ }>(getSubgraphUrl(networkData), GET_TRANSACTION_QUERY, {
50
+ hash: hash.toLowerCase(),
51
+ });
52
+
53
+ return transaction;
54
+ }
55
+
56
+ /**
57
+ * This function returns all transaction details based on the provided filter.
58
+ *
59
+ * > This uses Subgraph
60
+ *
61
+ * **Input parameters**
62
+ *
63
+ * ```ts
64
+ * interface ITransactionsFilter {
65
+ * networks: ChainId[]; // List of chain IDs to query.
66
+ * fromAddress?: string; // (Optional) The address from which transactions are sent.
67
+ * toAddress?: string; // (Optional) The address to which transactions are sent.
68
+ * startDate?: Date; // (Optional) The start date to filter transactions (inclusive).
69
+ * endDate?: Date; // (Optional) The end date to filter transactions (inclusive).
70
+ * startBlock?: number; // (Optional) The start block number to filter transactions (inclusive).
71
+ * endBlock?: number; // (Optional) The end block number to filter transactions (inclusive).
72
+ * }
73
+ * ```
74
+ *
75
+ * ```ts
76
+ * type ITransaction = {
77
+ * block: number;
78
+ * txHash: string;
79
+ * from: string;
80
+ * to: string;
81
+ * timestamp: number;
82
+ * value: string;
83
+ * method: string;
84
+ * };
85
+ * ```
86
+ *
87
+ * @param {ITransactionsFilter} filter Filter for the transactions.
88
+ * @returns {Promise<ITransaction[]>} Returns an array with all the transaction details.
89
+ *
90
+ * **Code example**
91
+ *
92
+ * ```ts
93
+ * import { TransactionUtils, ChainId } from '@human-protocol/sdk';
94
+ *
95
+ * const filter: ITransactionsFilter = {
96
+ * networks: [ChainId.POLYGON],
97
+ * startDate: new Date('2022-01-01'),
98
+ * endDate: new Date('2022-12-31')
99
+ * };
100
+ * const transactions = await TransactionUtils.getTransactions(filter);
101
+ * ```
102
+ */
103
+ public static async getTransactions(
104
+ filter: ITransactionsFilter
105
+ ): Promise<ITransaction[]> {
106
+ if (
107
+ (!!filter.startDate || !!filter.endDate) &&
108
+ (!!filter.startBlock || !!filter.endBlock)
109
+ ) {
110
+ throw ErrorCannotUseDateAndBlockSimultaneously;
111
+ }
112
+
113
+ const transactions_data: ITransaction[] = [];
114
+ for (const chainId of filter.networks) {
115
+ const networkData = NETWORKS[chainId];
116
+ if (!networkData) {
117
+ throw ErrorUnsupportedChainID;
118
+ }
119
+ const { transactions } = await gqlFetch<{
120
+ transactions: ITransaction[];
121
+ }>(getSubgraphUrl(networkData), GET_TRANSACTIONS_QUERY(filter), {
122
+ fromAddress: filter?.fromAddress,
123
+ toAddress: filter?.toAddress,
124
+ startDate: filter?.startDate
125
+ ? Math.floor(filter?.startDate.getTime() / 1000)
126
+ : undefined,
127
+ endDate: filter.endDate
128
+ ? Math.floor(filter.endDate.getTime() / 1000)
129
+ : undefined,
130
+ startBlock: filter.startBlock ? filter.startBlock : undefined,
131
+ endBlock: filter.endBlock ? filter.endBlock : undefined,
132
+ });
133
+
134
+ if (!transactions) {
135
+ continue;
136
+ }
137
+
138
+ transactions_data.push(...transactions);
139
+ }
140
+ return transactions_data;
141
+ }
142
+ }
package/src/types.ts CHANGED
@@ -127,6 +127,10 @@ export type NetworkData = {
127
127
  * Subgraph URL
128
128
  */
129
129
  subgraphUrl: string;
130
+ /**
131
+ * Subgraph URL
132
+ */
133
+ subgraphUrlApiKey: string;
130
134
  /**
131
135
  * Old subgraph URL
132
136
  */
package/src/utils.ts CHANGED
@@ -9,7 +9,10 @@ import {
9
9
  NumericFault,
10
10
  ReplacementUnderpriced,
11
11
  TransactionReplaced,
12
+ WarnSubgraphApiKeyNotProvided,
12
13
  } from './error';
14
+ import { NetworkData } from './types';
15
+ import { SUBGRAPH_API_KEY_PLACEHOLDER } from './constants';
13
16
 
14
17
  /**
15
18
  * **Handle and throw the error.*
@@ -49,3 +52,25 @@ export const isValidUrl = (url: string) => {
49
52
  return false;
50
53
  }
51
54
  };
55
+
56
+ /**
57
+ * **Get the subgraph URL.*
58
+ *
59
+ * @param {NetworkData} networkData
60
+ * @param {string} apiKey
61
+ * @returns
62
+ */
63
+ export const getSubgraphUrl = (networkData: NetworkData) => {
64
+ let subgraphUrl = networkData.subgraphUrl;
65
+ if (process.env.SUBGRAPH_API_KEY) {
66
+ subgraphUrl = networkData.subgraphUrlApiKey.replace(
67
+ SUBGRAPH_API_KEY_PLACEHOLDER,
68
+ process.env.SUBGRAPH_API_KEY
69
+ );
70
+ } else {
71
+ // eslint-disable-next-line no-console
72
+ console.warn(WarnSubgraphApiKeyNotProvided);
73
+ }
74
+
75
+ return subgraphUrl;
76
+ };